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