550 lines
21 KiB
PHP
Executable File
550 lines
21 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* 数据清理处理
|
|
* autoReset; // 清空修复异常数据
|
|
* resetSourceEmpty // source中表清理; sourceHash为空或所属关系错误的条目删除;
|
|
* resetShareTo // share_to中存在share中不存在的数据清理
|
|
* resetShare // share中存在,source已不存在的内容清理
|
|
* resetSourceFile // source中的文件fileID,file中不存在清理;
|
|
* resetFileSource // file中存在,source中不存在的进行清理
|
|
* resetSourceHistory // 文件历史版本,fileID不存在的内容清理;
|
|
* resetFileLink // 重置fileID的linkCount引用计数(source,sourceHistory);
|
|
* clearSameFile // 清理重复的文件记录
|
|
|
|
* sql清理操作日志:
|
|
* delete from `system_log` where createTime < UNIX_TIMESTAMP('2023-03-01 00:00:00')
|
|
*/
|
|
class adminRepair extends Controller {
|
|
function __construct() {
|
|
parent::__construct();
|
|
$this->resetPathKey = '';
|
|
$this->pageCount = 20000;// 分页查询限制; 默认5000, 20000;
|
|
}
|
|
|
|
/**
|
|
* 清空修复异常数据(php终止,断电,宕机等引起数据库表错误的进行处理;)
|
|
* 6个小时执行一次;
|
|
*
|
|
* 手动执行:
|
|
* /?admin/repair/autoReset&done=1/2,done=1为清理数据;done=2为实际删除不存在的文件记录
|
|
*/
|
|
public function autoReset(){
|
|
$done = isset($this->in['done']) ? intval($this->in['done']) : 0;
|
|
if ($done == 2) { // 计划任务执行
|
|
$msg = $this->resetPathSource();
|
|
echoLog('异常数据清理,'.$msg.'可在后台任务管理进行中止.');
|
|
} else {
|
|
$cacheKey = 'autoReset';
|
|
$lastTime = Cache::get($cacheKey);
|
|
$lastTime = false;//debug ;
|
|
if($lastTime && time() - intval($lastTime) < 3600*6 ){
|
|
echo '最后一次执行未超过6小时!';return;
|
|
}
|
|
Cache::set($cacheKey,time());
|
|
echoLog('异常数据清理,可在后台任务管理进行中止.');
|
|
}
|
|
// echoLog('请求参数done=1时,不直接删除已缺失的物理文件,可查看“物理文件不存在的数据记录”,确认需要删除后,再执行done=2进行删除');
|
|
echoLog('=====================================================');
|
|
if ($done == 2) {return $this->clearErrorFile();}
|
|
// http_close();
|
|
|
|
$this->resetSourceEmpty(); // source中表清理; sourceHash为空或所属关系错误的条目删除;
|
|
$this->resetShareTo(); // share_to中存在share中不存在的数据清理
|
|
$this->resetShare(); // share中存在,source已不存在的内容清理
|
|
$this->resetSourceFile(); // source中的文件fileID,file中不存在清理;
|
|
$this->resetFileSource(); // file中存在,source中不存在的进行清理
|
|
$this->resetSourceHistory(); // 文件历史版本,fileID不存在的内容清理;
|
|
$this->resetFileLink(); // 重置fileID的linkCount引用计数(source,sourceHistory);
|
|
$this->clearSameFile(); // 清理重复的文件记录
|
|
write_log('异常数据清理完成!','sourceRepair');
|
|
echoLog('=====================================================');
|
|
echoLog('异常数据清理完成!');
|
|
}
|
|
|
|
public function clearEmptyFile(){
|
|
Model('File')->clearEmpty(0);
|
|
pr('ok');
|
|
}
|
|
|
|
// 处理指定目录数据
|
|
private function resetPathSource(){
|
|
if (!isset($this->in['path'])) return '';
|
|
$path = $this->in['path'];
|
|
$parse = KodIO::parse($path);
|
|
$info = IO::infoSimple($path);
|
|
$id = $parse['id'];
|
|
if (!$id || !$info || $info['isFolder'] != 1) {
|
|
echoLog('指定目录参数错误: path='.$path);exit;
|
|
}
|
|
// 获取指定目录下子文件
|
|
$pathLevel = $info['parentLevel'].$id.',';
|
|
$where = array(
|
|
'isFolder' => 0,
|
|
'parentLevel' => array('like', $pathLevel.'%')
|
|
);
|
|
$result = Model("Source")->where($where)->select();
|
|
if (!$result) {
|
|
echoLog('指定目录下没有待处理数据: path='.$path);exit;
|
|
}
|
|
$this->resetPathKey = 'repair.reset.path.'.$id;
|
|
Cache::remove($this->resetPathKey);
|
|
|
|
$source = $file = array();
|
|
foreach ($result as $item) {
|
|
$source[] = $item['sourceID'];
|
|
$file[] = $item['fileID'];
|
|
}
|
|
$cache = array(
|
|
'source'=> array_filter(array_unique($source)),
|
|
'file' => array_filter(array_unique($file)),
|
|
);
|
|
Cache::set($this->resetPathKey, $cache);
|
|
return '执行目录: '.$path.',';
|
|
}
|
|
private function pathWhere($model, $file=false, $shareTo=false) {
|
|
if (!$this->resetPathKey) return;
|
|
$cache = Cache::get($this->resetPathKey);
|
|
if (!$cache) {
|
|
echoLog('缓存数据异常,请尝试重新执行!');exit;
|
|
}
|
|
$key = $file ? 'file' : 'source';
|
|
$ids = $cache[$key];
|
|
$where = array($key.'ID'=>array('in', $ids));
|
|
if ($shareTo) {
|
|
$list = Model('Share')->where($where)->select();
|
|
if (!$list) {
|
|
$where = array('shareID'=>0);
|
|
} else {
|
|
$ids = array_to_keyvalue($list, '', 'shareID');
|
|
$ids = array_filter(array_unique($ids));
|
|
$where = array('shareID'=>array('in',$ids));
|
|
}
|
|
}
|
|
$model->where($where);
|
|
}
|
|
|
|
/**
|
|
* 清除已不存在的物理文件记录
|
|
* 需先执行autoReset方法,并查看sourceRepair日志【resetFileLink--已不存在的物理文件】,确认是否需要清除
|
|
* @return void
|
|
*/
|
|
public function clearErrorFile(){
|
|
$cache = Cache::get('clear_file_'.date('Ymd'));
|
|
if (!$cache || !is_array($cache)) {
|
|
echoLog('没有缺失的物理文件记录!');
|
|
echoLog('注意:此记录从缓存中获取,缓存数据在执行done=1时产生,因此请务必先执行done=1.');
|
|
exit;
|
|
}
|
|
echoLog('clearErrorFile,物理文件不存在的数据处理;');
|
|
$model = Model('File');
|
|
$modelSource = Model("Source");$modelHistory = Model("SourceHistory");
|
|
$result = array('file' => 0, 'source' => 0);
|
|
foreach ($cache as $item) {
|
|
$rest = $this->delFileNone($model, $modelSource, $modelHistory, $item);
|
|
$result['file'] += $rest['file'];
|
|
$result['source'] += $rest['source'];
|
|
echoLog('file:'.$result['file'].';source:'.$result['source'],true);
|
|
}
|
|
Cache::remove('clear_file_'.date('Ymd'));
|
|
echoLog('clearErrorFile,finished:清除已不存在的物理文件记录共'.$result['file'].'条,涉及source记录'.$result['source'].'条!');
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* source表中异常数据处理:
|
|
* 1. parentID为0, 但 parentLevel不为0情况处理;
|
|
* 2. parentID 不存在处理;
|
|
* 3. sourchHash 为空的数据;
|
|
*/
|
|
public function resetSourceEmpty(){
|
|
$taskID ='resetSourceEmpty';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model = Model("Source");
|
|
$this->pathWhere($model);
|
|
$list = $model->selectPage($pageNum,$page);
|
|
|
|
$task = TaskLog::newTask($taskID,'source表异常数据处理',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
$parentSource = $removeSource = $removeFiles = array();
|
|
foreach ($list['list'] as $item) {
|
|
$levelEnd = ','.$item['parentID'].',';
|
|
$levelEndNow = substr($item['parentLevel'],- strlen($levelEnd));
|
|
if( $item['sourceHash'] == '' || $levelEndNow != $levelEnd ){
|
|
$changeNum++;write_log(array($taskID,$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个不存在';
|
|
$parentSource[] = $item['parentID'];
|
|
$removeSource[] = $item['sourceID'];
|
|
$removeFiles[] = $item['fileID'];
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$model->removeRelevance($removeSource,$removeFiles); // 优化性能;
|
|
$this->folderSizeReset($parentSource);
|
|
$this->pathWhere($model);$page++;
|
|
$list = $model->selectPage($pageNum,$page);
|
|
}
|
|
$task->end();
|
|
}
|
|
|
|
// source对应fileID 不存在处理;
|
|
public function resetSourceFile(){
|
|
$taskID ='resetSourceFile';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model = Model("Source");$modelFile = Model("File");
|
|
$this->pathWhere($model);
|
|
$list = $model->selectPage($pageNum,$page);
|
|
|
|
$task = TaskLog::newTask($taskID,'source表空数据处理',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
$parentSource = $removeSource = $removeFiles = array();
|
|
foreach ($list['list'] as $item) {
|
|
if($item['isFolder'] == '0' && !$modelFile->find($item['fileID'])){
|
|
$changeNum++;write_log(array($taskID,$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个不存在';
|
|
$parentSource[] = $item['parentID'];
|
|
$removeSource[] = $item['sourceID'];
|
|
$removeFiles[] = $item['fileID'];
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$model->removeRelevance($removeSource,$removeFiles); // 优化性能;
|
|
$this->folderSizeReset($parentSource);
|
|
$this->pathWhere($model);$page++;
|
|
$list = $model->selectPage($pageNum,$page);
|
|
}
|
|
$task->end();
|
|
}
|
|
|
|
// 重置文件夹大小
|
|
private function folderSizeReset($parentSource){
|
|
$model = Model("Source");
|
|
$parentSource = array_filter(array_unique($parentSource));
|
|
foreach ($parentSource as $sourceID) {
|
|
$model->folderSizeReset($sourceID);
|
|
}
|
|
}
|
|
|
|
public function resetFileHash(){
|
|
$taskID ='resetFileHash';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model = Model('File');
|
|
$this->pathWhere($model, true);
|
|
$list = $model->selectPage($pageNum,$page);
|
|
|
|
$task = TaskLog::newTask($taskID,'更新文件hash',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
foreach ($list['list'] as $item) {
|
|
if(!$item['hashSimple'] || !$item['hashMd5']){
|
|
$data = array('hashSimple'=>IO::hashSimple($item['path']) );
|
|
if(!$item['hashMd5']){$data['hashMd5'] = IO::hashMd5($item['path']);}
|
|
|
|
$changeNum++;write_log(array($taskID,$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个修改';
|
|
$model->where(array('fileID'=>$item['fileID']))->save($data);
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$this->pathWhere($model, true);$page++;
|
|
$list = $model->selectPage($pageNum,$page);
|
|
}
|
|
$task->end();
|
|
}
|
|
|
|
// 重置分享,内部协作分享数据;(删除文件夹,删除对应分享,及内部协作分享)
|
|
public function resetShareTo(){
|
|
$taskID ='resetShareTo';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model = Model('share_to');$modelShare = Model("share");
|
|
$this->pathWhere($model, false, true);
|
|
$list = $model->selectPage($pageNum,$page);
|
|
|
|
$task = TaskLog::newTask($taskID,'重置内部协作数据',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
foreach ($list['list'] as $item) {
|
|
$where = array("shareID"=>$item['shareID']);
|
|
if(!$modelShare->where($where)->find()){
|
|
$changeNum++;write_log(array($taskID,$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个不存在';
|
|
$model->where($where)->delete();
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$this->pathWhere($model, false, true);$page++;
|
|
$list = $model->selectPage($pageNum,$page);
|
|
}
|
|
$task->end();
|
|
}
|
|
|
|
// 重置分享,内部协作分享数据;(删除文件夹,删除对应分享,及内部协作分享)
|
|
public function resetShare(){
|
|
$taskID ='resetShare';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model = Model('share');$modelSource = Model("Source");
|
|
$this->pathWhere($model);
|
|
$list = $model->selectPage($pageNum,$page);
|
|
|
|
$task = TaskLog::newTask($taskID,'重置分享数据',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
foreach ($list['list'] as $item) {
|
|
$where = array("sourceID"=>$item['sourceID']);
|
|
if($item['sourceID'] != '0' && !$modelSource->where($where)->find()){
|
|
$changeNum++;write_log(array($taskID,$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个不存在';
|
|
|
|
$where = array('shareID'=>$item['shareID']);
|
|
$model->where($where)->delete();
|
|
Model('share_to')->where($where)->delete();
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$this->pathWhere($model);$page++;
|
|
$list = $model->selectPage($pageNum,$page);
|
|
}
|
|
$task->end();
|
|
}
|
|
|
|
// file表中存在, source表中不存在的进行清除;历史记录表等;
|
|
public function resetFileSource(){
|
|
$taskID ='resetFileSource';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model = Model("File");$modelSource = Model("Source");
|
|
$modelHistory = Model('SourceHistory');;
|
|
$this->pathWhere($model, true);
|
|
$list = $model->selectPage($pageNum,$page);
|
|
$stores = Model('Storage')->listData();
|
|
$stores = array_to_keyvalue($stores, '', 'id'); // 有效存储列表
|
|
|
|
$task = TaskLog::newTask($taskID,'Source记录异常处理',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
foreach ($list['list'] as $item) {
|
|
$where = array("fileID"=>$item['fileID']);
|
|
$findSource = $modelSource->where($where)->find();
|
|
$findHistory = $modelHistory->where($where)->find();
|
|
if(!$findSource && !$findHistory){
|
|
$changeNum++;write_log(array($taskID,$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个不存在';
|
|
// if (in_array($item['ioType'], $stores)) {IO::remove($item['path']);}
|
|
$model->where($where)->delete();
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$this->pathWhere($model, true);$page++;
|
|
$list = $model->selectPage($pageNum,$page);
|
|
}
|
|
$task->end();
|
|
}
|
|
|
|
// File表中,io不存在的文件进行处理;(被手动删除的)
|
|
public function resetFileLink(){
|
|
$taskID ='resetFileLink';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model = Model('File');
|
|
$this->pathWhere($model, true);
|
|
$list = $model->selectPage($pageNum,$page);
|
|
$stores = Model('Storage')->listData();
|
|
$stores = array_to_keyvalue($stores, '', 'id'); // 有效存储列表
|
|
|
|
$cache = array();$rest = array('file' => 0, 'source' => 0);
|
|
$task = TaskLog::newTask($taskID,'重置清理File表引用',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
foreach ($list['list'] as $item) {
|
|
$ioNone = in_array($item['ioType'], $stores);
|
|
if($ioNone && IO::exist($item['path']) ){
|
|
$model->resetFile($item);
|
|
}else{
|
|
$changeNum++;write_log(array($taskID.'--已不存在的物理文件',$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个不存在'.';'.$item['path'];
|
|
$cache[] = array(
|
|
'fileID' => $item['fileID'],
|
|
'linkCount' => $item['linkCount'],
|
|
);
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$this->pathWhere($model, true);$page++;
|
|
$list = $model->selectPage($pageNum,$page);
|
|
}
|
|
$task->end();
|
|
if($cache) Cache::set('clear_file_'.date('Ymd'), $cache);
|
|
return $rest;
|
|
}
|
|
// 删除不存在的物理文件
|
|
private function delFileNone($model, $modelSource, $modelHistory, $item){
|
|
$where = array("fileID"=>$item['fileID']);
|
|
$list = $modelSource->where($where)->select();
|
|
$cnt1 = $modelSource->where($where)->delete();
|
|
$modelHistory->where($where)->delete();
|
|
|
|
$model->metaSet($item['fileID'],null,null);
|
|
$cnt2 = $model->where(array('fileID'=>$item['fileID']))->delete();
|
|
|
|
// 重置父目录大小
|
|
$list = array_to_keyvalue($list, '', 'parentID');
|
|
$this->folderSizeReset($list);
|
|
return array('source' => intval($cnt1),'file'=> intval($cnt2));
|
|
}
|
|
|
|
public function resetSourceHistory(){
|
|
$taskID ='resetSourceHistory';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model = Model('SourceHistory');$modelSource = Model("Source");
|
|
$modelFile = Model("File");
|
|
$this->pathWhere($model);
|
|
$list = $model->selectPage($pageNum,$page);
|
|
|
|
$task = TaskLog::newTask($taskID,'历史版本异常数据处理',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
foreach ($list['list'] as $item) {
|
|
$where = array("sourceID"=>$item['sourceID']);
|
|
if( !$modelSource->where($where)->find() ){
|
|
$changeNum++;write_log(array($taskID,$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个不存在';
|
|
$model->where($where)->delete();
|
|
}
|
|
if( !$modelFile->where(array('fileID'=>$item['fileID']))->find()){
|
|
$changeNum++;write_log(array($taskID.',fileError!',$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个不存在';
|
|
$model->where(array('fileID'=>$item['fileID']))->delete();
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$this->pathWhere($model);$page++;
|
|
$list = $model->selectPage($pageNum,$page);
|
|
}
|
|
$task->end();
|
|
}
|
|
|
|
// 文件列表自然排序,文件名处理; 升级向下兼容数据处理;
|
|
public function sourceNameInit(){
|
|
// Model("SystemOption")->set('sourceNameSortFlag','');
|
|
if(Model("SystemOption")->get('sourceNameSortFlag')) return;
|
|
$this->sourceNameSort();
|
|
}
|
|
public function sourceNameSort(){
|
|
$taskID ='sourceNameSort';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
Model("SystemOption")->set('sourceNameSortFlag','1');
|
|
$model = Model('Source');$modelMeta = Model("io_source_meta");
|
|
$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$model->selectPageReset();
|
|
$list = $model->field('sourceID,name')->selectPage($pageNum,$page);
|
|
|
|
$task = TaskLog::newTask($taskID,'更新Source排序名',$list['pageInfo']['totalNum']);
|
|
while($list && $page <= $list['pageInfo']['pageTotal']){
|
|
$metaAdd = array();
|
|
foreach ($list['list'] as $item){
|
|
if(!$item['name']) continue;
|
|
$metaAdd[] = array(
|
|
'sourceID' => $item['sourceID'],
|
|
'key' => 'nameSort',
|
|
'value' => KodSort::makeStr($item['name']),
|
|
);
|
|
$task->update(1);
|
|
if(count($metaAdd) >= 1000){
|
|
$modelMeta->addAll($metaAdd,array(),true);$metaAdd = array();
|
|
}
|
|
}
|
|
if(count($metaAdd) > 0){
|
|
$modelMeta->addAll($metaAdd,array(),true);$metaAdd = array();
|
|
}
|
|
$page++;
|
|
$list = $model->field('sourceID,name')->selectPage($pageNum,$page);
|
|
}
|
|
Model("SystemOption")->set('sourceNameSortFlag','2');
|
|
$model->selectPageRestore();
|
|
$task->end();
|
|
}
|
|
|
|
/**
|
|
* 根据sourceID彻底删除文件,sourceID可传多个,如sourceID=1,2,3
|
|
* @return void
|
|
*/
|
|
public function clearSource(){
|
|
echoLog('根据sourceID彻底删除关联文件!参数sourceID=1,2,3');
|
|
$ids = $this->in['sourceID'];
|
|
if (!$ids) {
|
|
echoLog('无效的参数:sourceID!');exit;
|
|
}
|
|
// 1.根据sourceID查fileID
|
|
$ids = array_filter(explode(',',$ids));
|
|
$where = array(
|
|
'isFolder' => 0,
|
|
'sourceID' => array('in', $ids)
|
|
);
|
|
$list = Model('Source')->where($where)->field('sourceID,fileID')->select();
|
|
if (empty($list)) {
|
|
echoLog('找不到对应的source记录,请检查sourceID是否正确.');
|
|
exit;
|
|
}
|
|
|
|
echoLog('删除开始:');
|
|
$ids = array_to_keyvalue($list, '', 'sourceID');
|
|
$file = array_to_keyvalue($list, '', 'fileID');
|
|
$file = array_filter($file);
|
|
$fCnt = count($file);
|
|
// 2.根据fileID查所有sourceID
|
|
if (!empty($file)) {
|
|
$where = array('fileID'=>array('in', $file));
|
|
$list = Model('Source')->where($where)->field('sourceID')->select();
|
|
$ids = array_to_keyvalue($list, '', 'sourceID');
|
|
}
|
|
$ids = array_filter($ids);
|
|
$sCnt = count($ids);
|
|
// 3.根据sourceID删除文件
|
|
foreach ($ids as $i => $id) {
|
|
$path = KodIO::make($id);
|
|
IO::remove($path, false);
|
|
echoLog('source记录:'.($i+1), true);
|
|
}
|
|
// 4.删除可能还存在的file记录——实际物理文件删除与否不影响
|
|
if (!empty($file)) {
|
|
$where = array('fileID'=>array('in', $file));
|
|
Model('File')->where($where)->delete();
|
|
}
|
|
echoLog("删除完成!共删除source记录{$sCnt}条;file记录{$fCnt}条.");
|
|
}
|
|
|
|
public function resetSize(){
|
|
$id = $this->in['sourceID'];
|
|
if(!$id) return;
|
|
model('Source')->folderSizeResetChildren($id);
|
|
echoLog("更新完成!");
|
|
}
|
|
|
|
// 重复文件清理; 根据hashMd5处理;
|
|
public function clearSameFile(){
|
|
$taskID ='clearSameFile';$pageNum = $this->pageCount;$page = 1;$changeNum = 0;
|
|
$list = Model()->query('select hashMd5,count(1) from io_file group by hashMd5 having count(hashMd5)>1;');
|
|
$list = is_array($list) ? $list : array();
|
|
$modelFile = Model("File");
|
|
|
|
$task = TaskLog::newTask($taskID,'重复文件清理',count($list));
|
|
foreach ($list as $item) {
|
|
if(!$item['hashMd5'] || $item['hashMd5'] == '0') continue;
|
|
$where = array("hashMd5"=>$item['hashMd5']);
|
|
|
|
$files = $modelFile->field('fileID,path,linkCount')->where($where)->order('fileID asc')->select();
|
|
$files = is_array($files) ? $files : array();
|
|
$fileRemove = array();$linkCount = 0;
|
|
foreach ($files as $i=>$file){
|
|
if($i == 0) continue;
|
|
$linkCount += intval($file['linkCount']);
|
|
$fileRemove[] = $file['fileID'];
|
|
if($file['path'] && $file['path'] != $files[0]['path']){
|
|
IO::remove($file['path']);
|
|
}
|
|
}
|
|
if($fileRemove){
|
|
$fileID = $files[0]['fileID'];
|
|
$linkCount += intval($files[0]['linkCount']);
|
|
$fileWhere = array('fileID'=>array('in',$fileRemove));
|
|
$save = array('fileID'=>$fileID);
|
|
Model("Source")->where($fileWhere)->save($save);
|
|
Model("SourceHistory")->where($fileWhere)->save($save);
|
|
Model("share_report")->where($fileWhere)->save($save);
|
|
|
|
Model("io_file_meta")->where($fileWhere)->delete();
|
|
Model("io_file_contents")->where($fileWhere)->delete();
|
|
Model("io_file_meta")->where($fileWhere)->delete();
|
|
$modelFile->where($fileWhere)->delete();
|
|
$modelFile->where(array('fileID'=>$fileID))->save(array('linkCount'=>$linkCount));
|
|
|
|
$changeNum++;write_log(array($taskID,$item),'sourceRepair');
|
|
$task->task['desc'] = $task->task['currentTitle'] = $changeNum.'个修改';
|
|
}
|
|
$task->update(1);
|
|
}
|
|
$task->end();
|
|
}
|
|
} |