mirror of
https://github.com/kuaifan/dootask.git
synced 2026-01-19 14:18:10 +00:00
perf: 文件上传支持覆盖上传
This commit is contained in:
parent
d553f77533
commit
16359a968d
@ -699,6 +699,9 @@ class FileController extends AbstractController
|
|||||||
* @apiName content__upload
|
* @apiName content__upload
|
||||||
*
|
*
|
||||||
* @apiParam {Number} [pid] 父级ID
|
* @apiParam {Number} [pid] 父级ID
|
||||||
|
* @apiParam {Number} [cover] 覆盖已存在的文件
|
||||||
|
* - 0:不覆盖,保留两者(默认)
|
||||||
|
* - 1:覆盖
|
||||||
* @apiParam {String} [files] 文件名
|
* @apiParam {String} [files] 文件名
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
@ -709,8 +712,9 @@ class FileController extends AbstractController
|
|||||||
{
|
{
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
$pid = intval(Request::input('pid'));
|
$pid = intval(Request::input('pid'));
|
||||||
|
$overwrite = intval(Request::input('cover'));
|
||||||
$webkitRelativePath = Request::input('webkitRelativePath');
|
$webkitRelativePath = Request::input('webkitRelativePath');
|
||||||
$data = (new File)->contentUpload($user, $pid, $webkitRelativePath);
|
$data = (new File)->contentUpload($user, $pid, $webkitRelativePath, $overwrite);
|
||||||
return Base::retSuccess($data['data']['name'] . ' 上传成功', $data['addItem']);
|
return Base::retSuccess($data['data']['name'] . ' 上传成功', $data['addItem']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -190,9 +190,10 @@ class File extends AbstractModel
|
|||||||
* @param user $user
|
* @param user $user
|
||||||
* @param int $pid
|
* @param int $pid
|
||||||
* @param string $webkitRelativePath
|
* @param string $webkitRelativePath
|
||||||
|
* @param bool $overwrite
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function contentUpload($user, int $pid, $webkitRelativePath)
|
public function contentUpload($user, int $pid, $webkitRelativePath, $overwrite = false)
|
||||||
{
|
{
|
||||||
$userid = $user->userid;
|
$userid = $user->userid;
|
||||||
if ($pid > 0) {
|
if ($pid > 0) {
|
||||||
@ -283,17 +284,25 @@ class File extends AbstractModel
|
|||||||
if ($data['ext'] == 'markdown') {
|
if ($data['ext'] == 'markdown') {
|
||||||
$data['ext'] = 'md';
|
$data['ext'] = 'md';
|
||||||
}
|
}
|
||||||
$file = File::createInstance([
|
$file = null;
|
||||||
|
$params = [
|
||||||
'pid' => $pid,
|
'pid' => $pid,
|
||||||
'name' => Base::rightDelete($data['name'], '.' . $data['ext']),
|
'name' => Base::rightDelete($data['name'], '.' . $data['ext']),
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'ext' => $data['ext'],
|
'ext' => $data['ext'],
|
||||||
'userid' => $userid,
|
'userid' => $userid,
|
||||||
'created_id' => $user->userid,
|
'created_id' => $user->userid,
|
||||||
]);
|
];
|
||||||
$file->handleDuplicateName();
|
if ($overwrite) {
|
||||||
|
$file = self::wherePid($params['pid'])->whereExt($params['ext'])->whereName($params['name'])->first();
|
||||||
|
}
|
||||||
|
if (!$file) {
|
||||||
|
$overwrite = false;
|
||||||
|
$file = File::createInstance($params);
|
||||||
|
$file->handleDuplicateName();
|
||||||
|
}
|
||||||
// 开始创建
|
// 开始创建
|
||||||
return AbstractModel::transaction(function () use ($addItem, $webkitRelativePath, $type, $user, $data, $file) {
|
return AbstractModel::transaction(function () use ($overwrite, $addItem, $webkitRelativePath, $type, $user, $data, $file) {
|
||||||
$file->size = $data['size'] * 1024;
|
$file->size = $data['size'] * 1024;
|
||||||
$file->saveBeforePP();
|
$file->saveBeforePP();
|
||||||
//
|
//
|
||||||
@ -321,11 +330,12 @@ class File extends AbstractModel
|
|||||||
$tmpRow->pushMsg('add', $tmpRow);
|
$tmpRow->pushMsg('add', $tmpRow);
|
||||||
//
|
//
|
||||||
$data = File::handleImageUrl($tmpRow->toArray());
|
$data = File::handleImageUrl($tmpRow->toArray());
|
||||||
$data['full_name'] = $webkitRelativePath ?: $data['name'];
|
$data['full_name'] = $webkitRelativePath ?: ($data['name'] . '.' . $data['ext']);
|
||||||
|
$data['overwrite'] = $overwrite ? 1 : 0;
|
||||||
//
|
//
|
||||||
$addItem[] = $data;
|
$addItem[] = $data;
|
||||||
|
|
||||||
return ['data'=>$data,'addItem'=>$addItem];
|
return ['data' => $data, 'addItem' => $addItem];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1536,3 +1536,8 @@ License Key
|
|||||||
|
|
||||||
不显示该会话
|
不显示该会话
|
||||||
昨天
|
昨天
|
||||||
|
|
||||||
|
文件已存在
|
||||||
|
文件(*)已存在,是否替换?
|
||||||
|
保留两者
|
||||||
|
替换
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
"stylus-loader": "^7.1.0",
|
"stylus-loader": "^7.1.0",
|
||||||
"tinymce": "^5.10.3",
|
"tinymce": "^5.10.3",
|
||||||
"tui-calendar-hi": "^1.15.1-5",
|
"tui-calendar-hi": "^1.15.1-5",
|
||||||
"view-design-hi": "^4.7.0-48",
|
"view-design-hi": "^4.7.0-49",
|
||||||
"vite": "^2.9.15",
|
"vite": "^2.9.15",
|
||||||
"vite-plugin-file-copy": "^1.0.0",
|
"vite-plugin-file-copy": "^1.0.0",
|
||||||
"vite-plugin-require": "^1.1.10",
|
"vite-plugin-require": "^1.1.10",
|
||||||
|
|||||||
2
resources/assets/js/app.js
vendored
2
resources/assets/js/app.js
vendored
@ -175,7 +175,7 @@ Vue.prototype.copyText = function (obj) {
|
|||||||
obj.success && $A.messageSuccess(obj.success)
|
obj.success && $A.messageSuccess(obj.success)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.$copyText(text).then(_ => {
|
app.$copyText(obj.text).then(_ => {
|
||||||
obj.success && $A.messageSuccess(obj.success)
|
obj.success && $A.messageSuccess(obj.success)
|
||||||
}).catch(_ => {
|
}).catch(_ => {
|
||||||
obj.error && $A.messageError(obj.error)
|
obj.error && $A.messageError(obj.error)
|
||||||
|
|||||||
@ -233,8 +233,10 @@
|
|||||||
<em v-if="uploadList.find(({status}) => status === 'finished')" @click="uploadClear">{{$L('清空已完成')}}</em>
|
<em v-if="uploadList.find(({status}) => status === 'finished')" @click="uploadClear">{{$L('清空已完成')}}</em>
|
||||||
</div>
|
</div>
|
||||||
<ul class="content">
|
<ul class="content">
|
||||||
<li v-for="(item, index) in uploadList" :key="index" v-if="index < 100">
|
<li v-for="(item, index) in uploadList" :key="index" v-if="index < 100" @click="uploadClick(item)">
|
||||||
<AutoTip class="file-name">{{uploadName(item)}}</AutoTip>
|
<AutoTip class="file-name">
|
||||||
|
<span v-html="uploadName(item)"></span>
|
||||||
|
</AutoTip>
|
||||||
<AutoTip v-if="item.status === 'finished' && item.response && item.response.ret !== 1" class="file-error">{{item.response.msg}}</AutoTip>
|
<AutoTip v-if="item.status === 'finished' && item.response && item.response.ret !== 1" class="file-error">{{item.response.msg}}</AutoTip>
|
||||||
<Progress v-else :percent="uploadPercentageParse(item.percentage)" :stroke-width="5" />
|
<Progress v-else :percent="uploadPercentageParse(item.percentage)" :stroke-width="5" />
|
||||||
<Icon class="file-close" type="ios-close-circle-outline" @click="uploadList.splice(index, 1)"/>
|
<Icon class="file-close" type="ios-close-circle-outline" @click="uploadList.splice(index, 1)"/>
|
||||||
@ -536,6 +538,7 @@ export default {
|
|||||||
uploadList: [],
|
uploadList: [],
|
||||||
uploadFormat: [], // 不限制上传文件类型
|
uploadFormat: [], // 不限制上传文件类型
|
||||||
uploadAccept: '',
|
uploadAccept: '',
|
||||||
|
uploadCover: false,
|
||||||
|
|
||||||
contextMenuItem: {},
|
contextMenuItem: {},
|
||||||
contextMenuVisible: false,
|
contextMenuVisible: false,
|
||||||
@ -781,7 +784,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
actionUrl() {
|
actionUrl() {
|
||||||
return $A.apiUrl('file/content/upload?pid=' + this.pid)
|
return $A.apiUrl('file/content/upload?pid=' + this.pid + '&cover=' + (this.uploadCover ? 1 : 0))
|
||||||
},
|
},
|
||||||
|
|
||||||
headers() {
|
headers() {
|
||||||
@ -879,7 +882,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
compressedSownloadDisabled() {
|
compressedSownloadDisabled() {
|
||||||
return this.fileList?.find((res)=> res._checked && res.permission < 1) ? true : false
|
return !!this.fileList?.find((res) => res._checked && res.permission < 1)
|
||||||
},
|
},
|
||||||
|
|
||||||
maxSize() {
|
maxSize() {
|
||||||
@ -1057,6 +1060,10 @@ export default {
|
|||||||
|
|
||||||
browseFolder(id, shakeId = null) {
|
browseFolder(id, shakeId = null) {
|
||||||
if (id > 0) {
|
if (id > 0) {
|
||||||
|
if (this.$route.params.folderId == id) {
|
||||||
|
this.shakeFile(shakeId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.goForward({name: 'manage-file', params: {folderId: id, fileId: null, shakeId}});
|
this.goForward({name: 'manage-file', params: {folderId: id, fileId: null, shakeId}});
|
||||||
} else {
|
} else {
|
||||||
this.searchKey = '';
|
this.searchKey = '';
|
||||||
@ -1744,8 +1751,30 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
uploadData(item) {
|
||||||
|
const data = $A.getObject(item, 'response.data')
|
||||||
|
if ($A.isArray(data)) {
|
||||||
|
return data[0]
|
||||||
|
} else if ($A.isJson(data)) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
uploadName(item) {
|
uploadName(item) {
|
||||||
return $A.getObject(item, 'response.data.full_name') || item.name
|
const data = this.uploadData(item)
|
||||||
|
if (!data) {
|
||||||
|
return item.name
|
||||||
|
}
|
||||||
|
const fullName = data.full_name || item.name
|
||||||
|
return data.overwrite ? `<em class="overwrite">[${this.$L('替换')}]</em> ${fullName}` : fullName
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadClick(item) {
|
||||||
|
const data = this.uploadData(item)
|
||||||
|
if (!data) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.browseFolder(data.pid, data.id)
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTableSort({key, order}) {
|
handleTableSort({key, order}) {
|
||||||
@ -1948,12 +1977,45 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleBeforeUpload() {
|
handleBeforeUpload(file) {
|
||||||
//上传前判断
|
//上传前判断
|
||||||
|
this.uploadCover = false
|
||||||
|
if (this.uploadDir) {
|
||||||
|
this.handleUploadNext();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return new Promise(resolve => {
|
||||||
|
if (this.fileList.findIndex(item => $A.getFileName(item) === file.name) > -1) {
|
||||||
|
$A.modalConfirm({
|
||||||
|
wait: true,
|
||||||
|
title: '文件已存在',
|
||||||
|
content: '文件 ' + file.name + ' 已存在,是否替换?',
|
||||||
|
cancelText: '保留两者',
|
||||||
|
okText: '替换',
|
||||||
|
closable: true,
|
||||||
|
onOk: () => {
|
||||||
|
this.uploadCover = true
|
||||||
|
this.handleUploadNext();
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
onCancel: (isButton) => {
|
||||||
|
if (isButton) {
|
||||||
|
this.handleUploadNext();
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.handleUploadNext();
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleUploadNext() {
|
||||||
this.uploadShow = true;
|
this.uploadShow = true;
|
||||||
this.packShow = false;
|
this.packShow = false;
|
||||||
return true;
|
}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
5
resources/assets/sass/pages/page-file.scss
vendored
5
resources/assets/sass/pages/page-file.scss
vendored
@ -552,12 +552,17 @@
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
> li {
|
> li {
|
||||||
|
cursor: pointer;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
.file-name {
|
.file-name {
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
|
.overwrite {
|
||||||
|
font-style: normal;
|
||||||
|
color: $flow-status-end-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.file-error {
|
.file-error {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user