mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-26 04:50:18 +00:00
perf: 添加任务模板
This commit is contained in:
parent
6bafa0a6dd
commit
e3312c97a7
@ -2718,7 +2718,6 @@ class ProjectController extends AbstractController
|
||||
return Base::retError('参数错误');
|
||||
}
|
||||
$templates = ProjectTaskTemplate::where('project_id', $projectId)
|
||||
->orderBy('sort')
|
||||
->orderByDesc('id')
|
||||
->get();
|
||||
return Base::retSuccess('success', $templates);
|
||||
@ -2782,7 +2781,6 @@ class ProjectController extends AbstractController
|
||||
if ($templateCount >= 20) {
|
||||
return Base::retError('每个项目最多添加20个模板');
|
||||
}
|
||||
$data['sort'] = ProjectTaskTemplate::where('project_id', $projectId)->max('sort') + 1;
|
||||
$template = ProjectTaskTemplate::create($data);
|
||||
}
|
||||
return Base::retSuccess('保存成功', $template);
|
||||
|
||||
@ -10,7 +10,7 @@ namespace App\Models;
|
||||
* @property string $name 模板名称
|
||||
* @property string|null $title 任务标题
|
||||
* @property string|null $content 任务内容
|
||||
* @property int $sort 排序
|
||||
* @property int $sort 排序(预留)
|
||||
* @property bool $is_default 是否默认模板
|
||||
* @property int $userid 创建人
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
|
||||
@ -12,7 +12,8 @@
|
||||
|
||||
<div class="content">
|
||||
<div v-if="!templates.length" class="empty">
|
||||
<div class="empty-text">{{$L('暂无任务模板')}}</div>
|
||||
<div class="empty-text">{{$L('当前项目暂无任务模板')}}</div>
|
||||
<Button type="primary" icon="md-add" @click="handleAdd">{{$L('新建模板')}}</Button>
|
||||
</div>
|
||||
<div v-else class="template-list">
|
||||
<div v-for="item in templates" :key="item.id" class="template-item">
|
||||
@ -53,15 +54,16 @@
|
||||
v-bind="formOptions"
|
||||
@submit.native.prevent>
|
||||
<FormItem prop="name" :label="$L('模板名称')">
|
||||
<Input ref="templateName" v-model="editingTemplate.name" :placeholder="$L('请输入模板名称')"/>
|
||||
<Input ref="templateName" v-model="editingTemplate.name" :disabled="systemTemplateIsMultiple" :placeholder="$L('请输入模板名称')"/>
|
||||
</FormItem>
|
||||
<FormItem prop="title" :label="$L('任务标题')">
|
||||
<Input v-model="editingTemplate.title" :placeholder="$L('请输入任务标题')"/>
|
||||
<Input v-model="editingTemplate.title" :disabled="systemTemplateIsMultiple" :placeholder="$L('请输入任务标题')"/>
|
||||
</FormItem>
|
||||
<FormItem prop="content" :label="$L('任务内容')">
|
||||
<Input
|
||||
type="textarea"
|
||||
v-model="editingTemplate.content"
|
||||
:disabled="systemTemplateIsMultiple"
|
||||
:placeholder="$L('请输入任务内容')"
|
||||
:autosize="{ minRows: 4, maxRows: 12 }"/>
|
||||
</FormItem>
|
||||
@ -69,14 +71,27 @@
|
||||
<div class="project-task-template-system">
|
||||
<div v-if="!systemTemplateShow" @click="onSystemTemplate" class="tip-title">{{$L('使用示例模板')}}</div>
|
||||
<ul v-else>
|
||||
<li v-for="(item, index) in systemTemplateData" :key="index" @click="useSystemTemplate(item)">{{item.name}}</li>
|
||||
<li
|
||||
:class="{selected:systemTemplateIsMultiple}"
|
||||
@click="systemTemplateIsMultiple=!systemTemplateIsMultiple">
|
||||
<i class="taskfont" v-html="systemTemplateIsMultiple ? '' : ''"></i>
|
||||
{{$L('多选')}}
|
||||
</li>
|
||||
<li
|
||||
v-for="(item, index) in systemTemplateData"
|
||||
:key="index"
|
||||
:class="{selected:systemTemplateIsMultiple && systemTemplateMultipleData.indexOf(item)!==-1}"
|
||||
@click="useSystemTemplate(item)">{{item.name}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
<Button type="default" @click="showEditModal=false">{{$L('取消')}}</Button>
|
||||
<Button type="primary" :loading="loading" @click="handleSave">{{$L('保存')}}</Button>
|
||||
<Button type="primary" :loading="loading" @click="handleSave">
|
||||
{{ $L('保存') }}
|
||||
{{ systemTemplateIsMultiple && systemTemplateMultipleData.length > 0 ? ` (${systemTemplateMultipleData.length})` : '' }}
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
@ -111,6 +126,8 @@ export default {
|
||||
|
||||
systemTemplateShow: false,
|
||||
systemTemplateData: [],
|
||||
systemTemplateIsMultiple: false,
|
||||
systemTemplateMultipleData: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -176,22 +193,40 @@ export default {
|
||||
$A.messageWarning('请输入模板名称')
|
||||
return
|
||||
}
|
||||
let savePromises = []
|
||||
if (this.systemTemplateIsMultiple) {
|
||||
if (this.systemTemplateMultipleData.length === 0) {
|
||||
$A.messageWarning('请选择示例模板')
|
||||
return
|
||||
}
|
||||
savePromises = this.systemTemplateMultipleData.map(item => {
|
||||
const template = { ...this.editingTemplate, id: null, name: item.name, title: item.title, content: item.content }
|
||||
return this.handleSaveCall(template)
|
||||
})
|
||||
} else {
|
||||
savePromises.push(this.handleSaveCall(this.editingTemplate))
|
||||
}
|
||||
|
||||
try {
|
||||
await this.$store.dispatch("call", {
|
||||
url: 'project/task/template_save',
|
||||
data: this.editingTemplate,
|
||||
method: 'post',
|
||||
spinner: 300
|
||||
})
|
||||
$A.messageSuccess('保存成功')
|
||||
const results = await Promise.all(savePromises)
|
||||
$A.messageSuccess(results.length === 1 ? results[0].msg : '全部保存成功')
|
||||
this.showEditModal = false
|
||||
this.loadTemplates()
|
||||
} catch ({msg}) {
|
||||
$A.messageError(msg || '保存失败')
|
||||
} catch (error) {
|
||||
$A.messageError(error.msg || '保存失败')
|
||||
}
|
||||
},
|
||||
|
||||
// 保存模板请求
|
||||
async handleSaveCall(data) {
|
||||
return this.$store.dispatch("call", {
|
||||
url: 'project/task/template_save',
|
||||
data,
|
||||
method: 'post',
|
||||
spinner: 300
|
||||
})
|
||||
},
|
||||
|
||||
// 删除模板
|
||||
async handleDelete(template) {
|
||||
$A.modalConfirm({
|
||||
@ -199,14 +234,14 @@ export default {
|
||||
content: '确定要删除该模板吗?',
|
||||
onOk: async () => {
|
||||
try {
|
||||
await this.$store.dispatch("call", {
|
||||
const {msg} = await this.$store.dispatch("call", {
|
||||
url: 'project/task/template_delete',
|
||||
data: {
|
||||
id: template.id
|
||||
},
|
||||
spinner: 300
|
||||
})
|
||||
$A.messageSuccess('删除成功')
|
||||
$A.messageSuccess(msg || '删除成功')
|
||||
this.loadTemplates()
|
||||
} catch ({msg}) {
|
||||
$A.messageError(msg || '删除失败')
|
||||
@ -218,7 +253,7 @@ export default {
|
||||
// 设置默认模板
|
||||
async handleSetDefault(template) {
|
||||
try {
|
||||
await this.$store.dispatch("call", {
|
||||
const {msg} = await this.$store.dispatch("call", {
|
||||
url: 'project/task/template_default',
|
||||
data: {
|
||||
id: template.id,
|
||||
@ -226,7 +261,7 @@ export default {
|
||||
},
|
||||
spinner: 300
|
||||
})
|
||||
$A.messageSuccess('设置成功')
|
||||
$A.messageSuccess(msg || '设置成功')
|
||||
this.loadTemplates()
|
||||
} catch ({msg}) {
|
||||
$A.messageError(msg || '设置失败')
|
||||
@ -244,6 +279,15 @@ export default {
|
||||
this.editingTemplate.name = item.name
|
||||
this.editingTemplate.title = item.title
|
||||
this.editingTemplate.content = item.content
|
||||
//
|
||||
if (this.systemTemplateIsMultiple) {
|
||||
const index = this.systemTemplateMultipleData.indexOf(item)
|
||||
if (index === -1) {
|
||||
this.systemTemplateMultipleData.push(item)
|
||||
} else {
|
||||
this.systemTemplateMultipleData.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
resources/assets/sass/dark.scss
vendored
10
resources/assets/sass/dark.scss
vendored
@ -631,4 +631,14 @@ body.dark-mode-reverse {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.project-task-template-system {
|
||||
ul {
|
||||
> li {
|
||||
&.selected {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,11 +4,12 @@
|
||||
flex-direction: column;
|
||||
|
||||
.header {
|
||||
padding: 20px 20px 10px;
|
||||
height: 60px;
|
||||
padding: 10px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
|
||||
@media screen and (min-width: 500px) {
|
||||
justify-content: space-between;
|
||||
}
|
||||
@ -30,15 +31,15 @@
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
color: $primary-text-color;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.empty-text {
|
||||
font-size: 14px;
|
||||
flex-direction: column;
|
||||
padding: 20px;
|
||||
color: $primary-text-color;
|
||||
> button {
|
||||
margin-top: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,11 +87,12 @@
|
||||
}
|
||||
|
||||
.template-actions {
|
||||
margin-top: 12px;
|
||||
margin-top: 4px;
|
||||
text-align: right;
|
||||
|
||||
> button {
|
||||
margin-right: 12px;
|
||||
margin-top: 8px;
|
||||
margin-right: 8px;
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
font-size: 13px;
|
||||
@ -128,6 +130,11 @@
|
||||
&:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $primary-color;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user