no message

This commit is contained in:
kuaifan 2024-12-08 19:19:41 +08:00
parent 42234be5cf
commit bca0410a08
4 changed files with 216 additions and 153 deletions

View File

@ -0,0 +1,165 @@
<template>
<Modal
v-model="showEditModal"
:title="editingTag.id ? $L('编辑标签') : $L('新建标签')"
:mask-closable="false">
<Form
ref="editForm"
:model="editingTag"
:rules="formRules"
v-bind="formOptions"
@submit.native.prevent>
<FormItem prop="name" :label="$L('标签名称')">
<Input ref="tagName" v-model="editingTag.name" :disabled="systemTagIsMultiple" :placeholder="$L('请输入标签名称')"/>
</FormItem>
<FormItem prop="desc" :label="$L('标签描述')">
<Input v-model="editingTag.desc" :disabled="systemTagIsMultiple" :placeholder="$L('请输入标签描述')"/>
</FormItem>
<FormItem prop="color" :label="$L('标签颜色')">
<ColorPicker v-model="editingTag.color" :disabled="systemTagIsMultiple" recommend transfer/>
</FormItem>
<FormItem v-if="!editingTag.id">
<div class="project-task-template-system">
<div v-if="!systemTagShow" @click="onSystemTag" class="tip-title">{{$L('使用示例标签')}}</div>
<ul v-else>
<li
:class="{selected:systemTagIsMultiple}"
@click="systemTagIsMultiple=!systemTagIsMultiple">
<i class="taskfont" v-html="systemTagIsMultiple ? '&#xe627;' : '&#xe625;'"></i>
{{$L('多选')}}
</li>
<li
v-for="(item, index) in systemTagData"
:key="index"
:class="{tag: true, selected:systemTagIsMultiple && systemTagMultipleData.indexOf(item)!==-1}"
@click="useSystemTag(item)">
<Tags :tags="item"></Tags>
</li>
</ul>
</div>
</FormItem>
</Form>
<div slot="footer" class="adaption">
<Button type="default" @click="showEditModal=false">{{$L('取消')}}</Button>
<Button type="primary" :loading="loadIng > 0" @click="handleSave">
{{ $L('保存') }}
{{ systemTagIsMultiple && systemTagMultipleData.length > 0 ? ` (${systemTagMultipleData.length})` : '' }}
</Button>
</div>
</Modal>
</template>
<script>
import { mapState } from 'vuex'
import {getLanguage} from "../../../../language";
import {systemTags} from "./utils";
import Tags from "./tags.vue";
export default {
name: "TaskTagAdd",
components: {Tags},
data() {
return {
loadIng: 0,
showEditModal: false,
editingTag: {},
formRules: {
name: [
{ required: true, message: this.$L('请输入标签名称'), trigger: 'blur' }
]
},
systemTagShow: false,
systemTagData: [],
systemTagIsMultiple: false,
systemTagMultipleData: [],
}
},
computed: {
...mapState(['formOptions'])
},
watch: {
showEditModal(val) {
if (!val) {
this.$refs.editForm.resetFields()
this.systemTagShow = false
this.systemTagIsMultiple = false
}
}
},
methods: {
onOpen(tag) {
this.editingTag = { ...tag }
this.showEditModal = true
},
//
async handleSave() {
if (!this.editingTag.name) {
$A.messageWarning('请输入标签名称')
return
}
let savePromises = []
if (this.systemTagIsMultiple) {
if (this.systemTagMultipleData.length === 0) {
$A.messageWarning('请选择示例标签')
return
}
savePromises = this.systemTagMultipleData.map(item => {
const tag = { ...this.editingTag, id: null, name: item.name, desc: item.desc, color: item.color }
return this.handleSaveCall(tag)
})
} else {
savePromises.push(this.handleSaveCall(this.editingTag))
}
try {
const results = await Promise.all(savePromises)
$A.messageSuccess(results.length === 1 ? results[0].msg : '全部保存成功')
this.showEditModal = false
this.$emit('on-save')
} catch (error) {
$A.messageError(error.msg || '保存失败')
}
},
//
async handleSaveCall(data) {
this.loadIng++
try {
return await this.$store.dispatch("call", {
url: 'project/tag/save',
data,
method: 'post',
spinner: 300
})
} finally {
this.loadIng--
}
},
onSystemTag() {
const lang = getLanguage()
this.systemTagData = typeof systemTags[lang] === "undefined" ? systemTags['en'] : systemTags[lang]
this.systemTagShow = true
},
// 使
useSystemTag(item) {
this.editingTag.name = item.name
this.editingTag.desc = item.desc
this.editingTag.color = item.color
//
if (this.systemTagIsMultiple) {
const index = this.systemTagMultipleData.indexOf(item)
if (index === -1) {
this.systemTagMultipleData.push(item)
} else {
this.systemTagMultipleData.splice(index, 1)
}
}
}
}
}
</script>

View File

@ -2,7 +2,10 @@
<template> <template>
<div class="project-task-template"> <div class="project-task-template">
<div class="header"> <div class="header">
<div class="title">{{$L('任务标签')}}</div> <div class="title">
{{$L('任务标签')}}
<Loading v-if="loadIng > 0"/>
</div>
<div class="actions"> <div class="actions">
<Button type="primary" icon="md-add" @click="handleAdd"> <Button type="primary" icon="md-add" @click="handleAdd">
{{$L('新建标签')}} {{$L('新建标签')}}
@ -36,66 +39,19 @@
</div> </div>
<!-- 编辑标签弹窗 --> <!-- 编辑标签弹窗 -->
<Modal <TaskTagAdd ref="addTag" @on-save="loadTags"/>
v-model="showEditModal"
:title="editingTag.id ? $L('编辑标签') : $L('新建标签')"
:mask-closable="false">
<Form
ref="editForm"
:model="editingTag"
:rules="formRules"
v-bind="formOptions"
@submit.native.prevent>
<FormItem prop="name" :label="$L('标签名称')">
<Input ref="tagName" v-model="editingTag.name" :disabled="systemTagIsMultiple" :placeholder="$L('请输入标签名称')"/>
</FormItem>
<FormItem prop="desc" :label="$L('标签描述')">
<Input v-model="editingTag.desc" :disabled="systemTagIsMultiple" :placeholder="$L('请输入标签描述')"/>
</FormItem>
<FormItem prop="color" :label="$L('标签颜色')">
<ColorPicker v-model="editingTag.color" :disabled="systemTagIsMultiple" recommend transfer/>
</FormItem>
<FormItem v-if="!editingTag.id">
<div class="project-task-template-system">
<div v-if="!systemTagShow" @click="onSystemTag" class="tip-title">{{$L('使用示例标签')}}</div>
<ul v-else>
<li
:class="{selected:systemTagIsMultiple}"
@click="systemTagIsMultiple=!systemTagIsMultiple">
<i class="taskfont" v-html="systemTagIsMultiple ? '&#xe627;' : '&#xe625;'"></i>
{{$L('多选')}}
</li>
<li
v-for="(item, index) in systemTagData"
:key="index"
:class="{tag: true, selected:systemTagIsMultiple && systemTagMultipleData.indexOf(item)!==-1}"
@click="useSystemTag(item)">
<Tags :tags="item"></Tags>
</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('保存') }}
{{ systemTagIsMultiple && systemTagMultipleData.length > 0 ? ` (${systemTagMultipleData.length})` : '' }}
</Button>
</div>
</Modal>
</div> </div>
</template> </template>
<script> <script>
import {mapState} from 'vuex' import {mapState} from 'vuex'
import {systemTags} from "./utils";
import Tags from "./tags.vue"; import Tags from "./tags.vue";
import {getLanguage} from "../../../../language"; import TaskTagAdd from "./add.vue";
export default { export default {
name: 'ProjectTaskTag', name: 'ProjectTaskTag',
components: { components: {
TaskTagAdd,
Tags Tags
}, },
props: { props: {
@ -106,20 +62,8 @@ export default {
}, },
data() { data() {
return { return {
loading: false, loadIng: 0,
tags: [], tags: [],
showEditModal: false,
editingTag: this.getEmptyTag(),
formRules: {
name: [
{ required: true, message: this.$L('请输入标签名称'), trigger: 'blur' }
]
},
systemTagShow: false,
systemTagData: [],
systemTagIsMultiple: false,
systemTagMultipleData: [],
} }
}, },
computed: { computed: {
@ -128,15 +72,6 @@ export default {
created() { created() {
this.loadTags() this.loadTags()
}, },
watch: {
showEditModal(val) {
if (!val) {
this.$refs.editForm.resetFields()
this.systemTagShow = false
this.systemTagIsMultiple = false
}
}
},
methods: { methods: {
// //
getEmptyTag() { getEmptyTag() {
@ -151,7 +86,7 @@ export default {
// //
async loadTags() { async loadTags() {
this.loading = true this.loadIng++
try { try {
const {data} = await this.$store.dispatch("call", { const {data} = await this.$store.dispatch("call", {
url: 'project/tag/list', url: 'project/tag/list',
@ -163,60 +98,19 @@ export default {
this.tags = data || [] this.tags = data || []
} catch ({msg}) { } catch ({msg}) {
$A.messageError(msg || '加载标签失败') $A.messageError(msg || '加载标签失败')
} finally {
this.loadIng--
} }
this.loading = false
}, },
// //
handleAdd() { handleAdd() {
this.editingTag = this.getEmptyTag() this.$refs.addTag.onOpen(this.getEmptyTag())
this.showEditModal = true
}, },
// //
handleEdit(tag) { handleEdit(tag) {
this.editingTag = { ...tag } this.$refs.addTag.onOpen(tag)
this.showEditModal = true
},
//
async handleSave() {
if (!this.editingTag.name) {
$A.messageWarning('请输入标签名称')
return
}
let savePromises = []
if (this.systemTagIsMultiple) {
if (this.systemTagMultipleData.length === 0) {
$A.messageWarning('请选择示例标签')
return
}
savePromises = this.systemTagMultipleData.map(item => {
const tag = { ...this.editingTag, id: null, name: item.name, desc: item.desc, color: item.color }
return this.handleSaveCall(tag)
})
} else {
savePromises.push(this.handleSaveCall(this.editingTag))
}
try {
const results = await Promise.all(savePromises)
$A.messageSuccess(results.length === 1 ? results[0].msg : '全部保存成功')
this.showEditModal = false
this.loadTags()
} catch (error) {
$A.messageError(error.msg || '保存失败')
}
},
//
async handleSaveCall(data) {
return this.$store.dispatch("call", {
url: 'project/tag/save',
data,
method: 'post',
spinner: 300
})
}, },
// //
@ -225,6 +119,7 @@ export default {
title: '确认删除', title: '确认删除',
content: '确定要删除该标签吗?', content: '确定要删除该标签吗?',
onOk: async () => { onOk: async () => {
this.loadIng++
try { try {
const {msg} = await this.$store.dispatch("call", { const {msg} = await this.$store.dispatch("call", {
url: 'project/tag/delete', url: 'project/tag/delete',
@ -237,32 +132,12 @@ export default {
this.loadTags() this.loadTags()
} catch ({msg}) { } catch ({msg}) {
$A.messageError(msg || '删除失败') $A.messageError(msg || '删除失败')
} finally {
this.loadIng--
} }
} }
}) })
}, },
onSystemTag() {
const lang = getLanguage()
this.systemTagData = typeof systemTags[lang] === "undefined" ? systemTags['en'] : systemTags[lang]
this.systemTagShow = true
},
// 使
useSystemTag(item) {
this.editingTag.name = item.name
this.editingTag.desc = item.desc
this.editingTag.color = item.color
//
if (this.systemTagIsMultiple) {
const index = this.systemTagMultipleData.indexOf(item)
if (index === -1) {
this.systemTagMultipleData.push(item)
} else {
this.systemTagMultipleData.splice(index, 1)
}
}
}
} }
} }
</script> </script>

View File

@ -2,7 +2,10 @@
<template> <template>
<div class="project-task-template"> <div class="project-task-template">
<div class="header"> <div class="header">
<div class="title">{{$L('任务模板')}}</div> <div class="title">
{{$L('任务模板')}}
<Loading v-if="loadIng > 0"/>
</div>
<div class="actions"> <div class="actions">
<Button type="primary" icon="md-add" @click="handleAdd"> <Button type="primary" icon="md-add" @click="handleAdd">
{{$L('新建模板')}} {{$L('新建模板')}}
@ -88,7 +91,7 @@
</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"> <Button type="primary" :loading="loadIng > 0" @click="handleSave">
{{ $L('保存') }} {{ $L('保存') }}
{{ systemTemplateIsMultiple && systemTemplateMultipleData.length > 0 ? ` (${systemTemplateMultipleData.length})` : '' }} {{ systemTemplateIsMultiple && systemTemplateMultipleData.length > 0 ? ` (${systemTemplateMultipleData.length})` : '' }}
</Button> </Button>
@ -114,7 +117,7 @@ export default {
}, },
data() { data() {
return { return {
loading: false, loadIng: 0,
templates: [], templates: [],
showEditModal: false, showEditModal: false,
editingTemplate: this.getEmptyTemplate(), editingTemplate: this.getEmptyTemplate(),
@ -160,7 +163,7 @@ export default {
// //
async loadTemplates() { async loadTemplates() {
this.loading = true this.loadIng++
try { try {
const {data} = await this.$store.dispatch("call", { const {data} = await this.$store.dispatch("call", {
url: 'project/task/template_list', url: 'project/task/template_list',
@ -172,8 +175,9 @@ export default {
this.templates = data || [] this.templates = data || []
} catch ({msg}) { } catch ({msg}) {
$A.messageError(msg || '加载模板失败') $A.messageError(msg || '加载模板失败')
} finally {
this.loadIng--
} }
this.loading = false
}, },
// //
@ -220,12 +224,17 @@ export default {
// //
async handleSaveCall(data) { async handleSaveCall(data) {
return this.$store.dispatch("call", { this.loadIng++
url: 'project/task/template_save', try {
data, return await this.$store.dispatch("call", {
method: 'post', url: 'project/task/template_save',
spinner: 300 data,
}) method: 'post',
spinner: 300
})
} finally {
this.loadIng--
}
}, },
// //
@ -234,6 +243,7 @@ export default {
title: '确认删除', title: '确认删除',
content: '确定要删除该模板吗?', content: '确定要删除该模板吗?',
onOk: async () => { onOk: async () => {
this.loadIng++
try { try {
const {msg} = await this.$store.dispatch("call", { const {msg} = await this.$store.dispatch("call", {
url: 'project/task/template_delete', url: 'project/task/template_delete',
@ -246,6 +256,8 @@ export default {
this.loadTemplates() this.loadTemplates()
} catch ({msg}) { } catch ({msg}) {
$A.messageError(msg || '删除失败') $A.messageError(msg || '删除失败')
} finally {
this.loadIng--
} }
} }
}) })
@ -253,6 +265,7 @@ export default {
// //
async handleSetDefault(template) { async handleSetDefault(template) {
this.loadIng++
try { try {
const {msg} = await this.$store.dispatch("call", { const {msg} = await this.$store.dispatch("call", {
url: 'project/task/template_default', url: 'project/task/template_default',
@ -266,6 +279,8 @@ export default {
this.loadTemplates() this.loadTemplates()
} catch ({msg}) { } catch ({msg}) {
$A.messageError(msg || '设置失败') $A.messageError(msg || '设置失败')
} finally {
this.loadIng--
} }
}, },

View File

@ -20,12 +20,20 @@
font-weight: 500; font-weight: 500;
line-height: 1; line-height: 1;
padding-right: 24px; padding-right: 24px;
display: flex;
align-items: center;
.common-loading {
margin-left: 8px;
width: 20px;
height: 20px;
}
} }
} }
.content { .content {
flex: 1; flex: 1;
padding: 10px 20px 20px; padding: 0 20px 20px;
overflow-y: auto; overflow-y: auto;
position: relative; position: relative;