feat: 任务加时功能 (模仿可见性的交互,任务延期和修改时间) - 100%

This commit is contained in:
weifashi 2023-11-17 11:04:10 +08:00
parent aef46d4c76
commit d2fe6217a6
4 changed files with 69 additions and 61 deletions

View File

@ -246,9 +246,9 @@
<FormItem v-if="taskDetail.end_at || timeForce"> <FormItem v-if="taskDetail.end_at || timeForce">
<div class="item-label" slot="label"> <div class="item-label" slot="label">
<i class="taskfont">&#xe6e8;</i> <i class="taskfont">&#xe6e8;</i>
<EDropdown ref="eDeadlineRef" trigger="click" placement="bottom" @command="dropDeadline"> <span v-if="!taskDetail.end_at" @click="timeOpen = true" class="visibility-text color">{{$L('截止时间')}}</span>
<span class="visibility-text color">{{$L('截止时间')}} <EDropdown v-else ref="eDeadlineRef" trigger="click" placement="bottom" @command="dropDeadline">
</span> <span class="visibility-text color">{{$L('截止时间')}}</span>
<EDropdownMenu slot="dropdown"> <EDropdownMenu slot="dropdown">
<EDropdownItem :command="1"> <EDropdownItem :command="1">
<div class="task-menu-icon" > <div class="task-menu-icon" >
@ -278,7 +278,8 @@
@on-ok="timeOk" @on-ok="timeOk"
transfer> transfer>
<div class="picker-time"> <div class="picker-time">
<EDropdown ref="eDeadlineRef" trigger="click" placement="bottom" @command="dropDeadline"> <div v-if="!taskDetail.end_at" @click="timeOpen = true" class="time">{{taskDetail.end_at ? cutTime : '--'}}</div>
<EDropdown v-else ref="eDeadlineRef" trigger="click" placement="bottom" @command="dropDeadline">
<div @click="timeOpen = false" class="time">{{taskDetail.end_at ? cutTime : '--'}}</div> <div @click="timeOpen = false" class="time">{{taskDetail.end_at ? cutTime : '--'}}</div>
<EDropdownMenu slot="dropdown"> <EDropdownMenu slot="dropdown">
<EDropdownItem :command="1"> <EDropdownItem :command="1">
@ -494,13 +495,12 @@
width: '90%', width: '90%',
maxWidth: '450px' maxWidth: '450px'
}" }"
@on-ok="onDelay"
> >
<Form ref="formDelayTaskRef" :model="delayTaskForm" :rules="delayTaskRule" label-position="left" label-width="auto" @submit.native.prevent> <Form ref="formDelayTaskRef" :model="delayTaskForm" :rules="delayTaskRule" label-position="left" label-width="auto" @submit.native.prevent>
<FormItem :label="$L('延期时长')" prop="time"> <FormItem :label="$L('延期时长')" prop="time">
<Input type="number" v-model="delayTaskForm.time" :placeholder="$L('请输入时长')" > <Input type="number" v-model="delayTaskForm.time" :placeholder="$L('请输入时长')" >
<template #append> <template #append>
{{$L('时')}} {{$L('时')}}
</template> </template>
</Input> </Input>
</FormItem> </FormItem>
@ -508,6 +508,10 @@
<Input type="textarea" v-model="delayTaskForm.remark" :placeholder="$L('请输入修改备注')"></Input> <Input type="textarea" v-model="delayTaskForm.remark" :placeholder="$L('请输入修改备注')"></Input>
</FormItem> </FormItem>
</Form> </Form>
<div slot="footer">
<Button @click="delayTaskShow=false">{{$L('关闭')}}</Button>
<Button type="primary" @click="onDelay" :loading="delayTaskLoading">{{$L('确定')}}</Button>
</div>
</Modal> </Modal>
</div> </div>
</template> </template>
@ -621,10 +625,10 @@ export default {
updateParams: {}, updateParams: {},
delayTaskLoading: false,
delayTaskShow: false, delayTaskShow: false,
delayTaskLoading: false,
delayTaskForm: { delayTaskForm: {
time: 12, time: "24",
remark: '' remark: ''
}, },
delayTaskRule: { delayTaskRule: {
@ -1689,22 +1693,33 @@ export default {
} }
}, },
onDeforeClose(){
return new Promise((resolve, reject) => {})
},
onDelay(){ onDelay(){
this.delayTaskShow = true
// this.delayTaskLoading = true;
this.$refs['formDelayTaskRef'].validate((valid) => { this.$refs['formDelayTaskRef'].validate((valid) => {
if (valid) { if (!valid) {
this.$Message.success('Success!'); return;
} else {
this.$Message.error('Fail!');
} }
// this.delayTaskLoading = false; this.delayTaskLoading = true;
var date = new Date(this.taskDetail.end_at);
date.setHours(date.getHours() + Number(this.delayTaskForm.time));
this.$store.dispatch("taskUpdate", {
task_id: this.taskDetail.id,
times: [
this.taskDetail.start_at,
$A.formatDate('Y-m-d H:i:s', date),
this.delayTaskForm.remark,
],
}).then(({msg}) => {
$A.messageSuccess(msg);
this.delayTaskLoading = false;
this.delayTaskShow = false;
this.delayTaskForm.time = '24';
this.delayTaskForm.remark = '';
this.$store.dispatch("getTaskOne", this.taskDetail.id).catch(() => {})
}).catch(({msg}) => {
$A.modalError(msg);
this.delayTaskLoading = false;
})
}) })
return true
}, },
updateVisible() { updateVisible() {

View File

@ -247,13 +247,16 @@
<div v-if="packShow && packList.length > 0" class="file-upload-list"> <div v-if="packShow && packList.length > 0" class="file-upload-list">
<div class="upload-wrap"> <div class="upload-wrap">
<div class="title"> <div class="title">
打包列表 ({{packList.length}}) <span>{{$L('打包列表')}}({{packList.length}})</span>
<em v-if="packList.find(({status}) => status === 'finished')" @click="packClear">清空已完成</em> <em v-if="packList.find(({status}) => status === 'finished')" @click="packClear">{{$L('清空已完成')}}</em>
</div> </div>
<ul class="content"> <ul class="content">
<li v-for="(item, index) in packList" :key="index" v-if="index < 100"> <li v-for="(item, index) in packList" :key="index" v-if="index < 100">
<AutoTip class="file-name">{{packName(item)}}</AutoTip> <AutoTip class="file-name">
<AutoTip v-if="item.status === 'finished' && item.response && item.response.ret !== 1" class="file-error">{{item.response.msg}}</AutoTip> <span v-if="item.status !== 'finished'">{{item.name}}</span>
<a v-else href="javascript:void(0)" @click="downloadPackFile(item.name)">{{item.name}}</a>
</AutoTip>
<AutoTip v-if="item.status === 'finished' && item.response && item.response.ret !==1" class="file-error">{{item.response.msg}}</AutoTip>
<Progress v-else :percent="packPercentageParse(item.percentage)" :stroke-width="5" /> <Progress v-else :percent="packPercentageParse(item.percentage)" :stroke-width="5" />
<Icon class="file-close" type="ios-close-circle-outline" @click="packList.splice(index, 1)"/> <Icon class="file-close" type="ios-close-circle-outline" @click="packList.splice(index, 1)"/>
</li> </li>
@ -765,7 +768,7 @@ export default {
}, },
computed: { computed: {
...mapState(['systemConfig', 'userIsAdmin', 'userInfo', 'fileLists', 'wsOpenNum', 'windowWidth']), ...mapState(['systemConfig', 'userIsAdmin', 'userInfo', 'fileLists', 'wsOpenNum', 'windowWidth', 'filePackLists']),
pid() { pid() {
const {folderId} = this.$route.params; const {folderId} = this.$route.params;
@ -960,7 +963,15 @@ export default {
this.wsOpenTimeout = setTimeout(() => { this.wsOpenTimeout = setTimeout(() => {
this.$route.name == 'manage-file' && this.getFileList(); this.$route.name == 'manage-file' && this.getFileList();
}, 5000) }, 5000)
} },
filePackLists: {
handler() {
this.updatePackProgress()
},
deep: true
},
}, },
methods: { methods: {
@ -1446,11 +1457,6 @@ export default {
}, },
/********************文件打包下载部分************************/ /********************文件打包下载部分************************/
packName(item) {
return item.name;
},
packPercentageParse(val) { packPercentageParse(val) {
return parseInt(val, 10); return parseInt(val, 10);
}, },
@ -1465,44 +1471,31 @@ export default {
this.packList.push(file); this.packList.push(file);
this.uploadShow = false; // this.uploadShow = false; //
this.packShow = true; // this.packShow = true; //
},
const downloadInterval = setInterval(async () => { updatePackProgress () {
const pack = this.$store.state.packLists.find(({name}) => name == filePackName) this.packList.forEach(file=>{
const pack = this.filePackLists.find(({name}) => name == file.name)
file.percentage = Math.max(1, pack.progress); file.percentage = Math.max(1, pack.progress);
if (file.percentage >= 100) { if (file.status != 'finished' && file.percentage >= 100) {
file.status = 'finished'; file.status = 'finished';
clearInterval(downloadInterval);
// //
await this.downloadPackFile(filePackName); this.downloadPackFile(file.name);
} }
}, 1000); })
}, },
async downloadPackFile(filePackName) { async downloadPackFile(filePackName) {
// 1
await new Promise(resolve => setTimeout(resolve, 1000));
const downloadUrl = $A.apiUrl(`file/download/confirm?name=${filePackName}&token=${this.userToken}`); const downloadUrl = $A.apiUrl(`file/download/confirm?name=${filePackName}&token=${this.userToken}`);
try { if (!$A.Electron && !$A.isEEUiApp) {
const response = await axios({
url: downloadUrl,
method: 'GET',
responseType: 'blob',
});
if (!response.data) {
console.error('No data received from server');
return;
}
const blob = new Blob([response.data], { type: response.data.type });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.setAttribute('href', downloadUrl);
link.setAttribute('download', `${filePackName}`); link.setAttribute('download', `${filePackName}`);
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
} catch (error) { }else{
this.$store.dispatch('downUrl', downloadUrl)
} }
}, },
@ -1522,7 +1515,7 @@ export default {
okText: '确定', okText: '确定',
onOk: async () => { onOk: async () => {
try { try {
const { msg } = await this.$store.dispatch("call", { await this.$store.dispatch("call", {
url: 'file/download/check', url: 'file/download/check',
data: { ids }, data: { ids },
}); });

View File

@ -929,12 +929,12 @@ export default {
packProgress({state, dispatch}, data) { packProgress({state, dispatch}, data) {
$A.execMainDispatch("packProgress", data) $A.execMainDispatch("packProgress", data)
// //
const index = state.packLists.findIndex(({name}) => name == data.name); const index = state.filePackLists.findIndex(({name}) => name == data.name);
if (index > -1) { if (index > -1) {
state.packLists[index].progress = data.progress; state.filePackLists[index].progress = data.progress;
} else { } else {
state.packLists.push(data); state.filePackLists.push(data);
$A.IDBSave("packLists", state.packLists, 600) $A.IDBSave("filePackLists", state.filePackLists, 600)
} }
}, },

View File

@ -118,7 +118,7 @@ export default {
// 文件 // 文件
fileLists: [], fileLists: [],
fileLinks: [], fileLinks: [],
packLists: [], filePackLists: [],
// 项目任务 // 项目任务
projectId: 0, projectId: 0,