Files
dvcp_v2_webapp/packages/xbot/AppSeatManagementXbot/components/AnnounceList.vue
2023-12-28 17:15:19 +08:00

437 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<ai-list class="AppAnnounce">
<template slot="title">
<ai-title title="群发居民群" isShowBack isShowBottomBorder @onBackClick="cancel(true)">
<template #sub>
<span>管理员统一创建宣发任务选择要发送的居民群后通知群主发送群主确认后即可群发到居民群群主向同一个居民群每天最多可群发10条消息</span>
</template>
</ai-title>
</template>
<template slot="content">
<ai-search-bar class="search-bar">
<template #left>
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">创建宣发</el-button>
<ai-select
v-model="search.status"
@change="search.current = 1, getList()"
placeholder="任务状态"
:selectList="dict.getDict('mstXbotStatus')">
</ai-select>
<el-date-picker
v-model="search.startTime"
type="date"
size="small"
value-format="yyyy-MM-dd"
@change="search.current = 1, getList()"
placeholder="选择群发开始日期">
</el-date-picker>
<el-date-picker
v-model="search.endTime"
type="date"
size="small"
value-format="yyyy-MM-dd"
@change="search.current = 1, getList()"
placeholder="选择群发结束日期">
</el-date-picker>
<ai-user-selecter :instance="instance" @change="onUserChange" :isMultiple="false" v-model="userList" :actions="{tree: `/app/wxcp/wxdepartment/listAll?wxMainDepartmentId=${user.info.wxMainDepartmentId}`}" >
<div class="userSelcet">
<span style="color: #606266;" v-if="search.createUserId">{{ name }}</span>
<span v-else>创建人</span>
<i class="el-icon-arrow-up" v-if="!search.createUserId"></i>
<i class="el-icon-circle-close" v-if="search.createUserId" @click.stop="userList = [], search.createUserId = '', name = '', search.current = 1, getList()"></i>
</div>
</ai-user-selecter>
</template>
<template slot="right">
<el-input
v-model="search.taskTitle"
size="small"
v-throttle="() => { search.current = 1, getList() }"
placeholder="请输入任务名称"
clearable
@clear="search.current = 1, search.taskTitle = '', getList()"
suffix-icon="iconfont iconSearch">
</el-input>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
v-loading="loading"
style="margin-top: 6px; width: 100%;"
:current.sync="search.current"
:size.sync="search.size"
@getList="getList">
<el-table-column slot="user" width="140px" label="创建人" align="center">
<template slot-scope="{ row }">
<div class="userinfo">
<span>{{ row.createUserName }}</span>
<span style="color: #999">{{ row.createUserDeptName }}</span>
</div>
</template>
</el-table-column>
<el-table-column slot="options" width="140px" fixed="right" label="操作" align="center">
<template slot-scope="{ row }">
<div class="table-options">
<!-- <el-button type="text" @click="remindExamine(row.id)" v-if="['0'].includes(row.status)">催办</el-button> -->
<el-button type="text" @click="remove(row.id)" v-if="['0'].includes(row.status)">删除</el-button>
<el-button type="text" @click="close(row.id)" v-if="['0'].includes(row.status)">关闭</el-button>
<!-- <el-button type="text" @click="cancel(row.id)" v-if="['0'].includes(row.status)">撤回</el-button> -->
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
<el-button type="text" @click="toAdd(row.id)" v-if="['1', '3'].includes(row.status)">编辑</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'List',
props: {
instance: Function,
dict: Object,
params: Object
},
data() {
return {
search: {
current: 1,
size: 10,
status: '',
createUserId: '',
taskTitle: '',
startTime: '',
endTime: '',
markTag: ''
},
currIndex: '1',
name: '',
isShow: false,
userList: [],
tableData: [],
loading: false,
total: 0,
colConfigs: [
{ prop: 'taskTitle', label: '任务名称' },
{ prop: 'typeName', label: '群发类型', align: 'center' },
{ slot: 'user', label: '创建人', openType: 'userName', align: 'center' },
{ prop: 'choiceTime', label: '群发时间', align: 'center' },
{ prop: 'taskEndTime', label: '群发结束时间', align: 'center' },
{
prop: 'status',
align: 'center',
label: '状态',
render: (h, {row}) => {
return h('span', {
style: {
color: this.dict.getColor('mstXbotStatus', row.status)
}
}, this.dict.getLabel('mstXbotStatus', row.status))
}
},
{ prop: 'completionRate', label: '任务完成率', align: 'center', format: v => v ? v === '0.0' ? '0%' : `${v}%` : '-' }
]
}
},
computed: {
...mapState(['user']),
},
created () {
this.dict.load('mstXbotStatus', 'mstSendType', 'mstTag').then(() => {
this.getList()
})
},
methods: {
onUserChange (e) {
if (e.length) {
this.name = e[0].name
this.search.createUserId = e[0].id
} else {
this.search.createUserId = ''
this.name = ''
}
this.search.current = 1
this.getList()
},
getList() {
this.loading = true
this.instance.post(`/app/appmasssendingtaskxbot/list`, null, {
params: {
...this.search,
clientInfoId: this.params.id,
markTag: this.search.markTag ? this.search.markTag.join(',') : ''
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records.map(v => {
return {
...v,
typeName: '群发居民群'
}
})
this.total = res.data.total
this.$nextTick(() => {
this.loading = false
})
} else {
this.loading = false
}
}).catch(() => {
this.loading = false
})
},
remindExamine (id) {
this.$confirm('确认再次通知任务审核人员?').then(() => {
this.instance.post(`/app/appmasssendingtaskxbot/remindExamine?id=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('催办成功!')
this.getList()
}
})
})
},
close (id) {
this.$confirm('确认关闭该群发任务?').then(() => {
this.instance.post(`/app/appmasssendingtaskxbot/closeTask?id=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('关闭成功!')
this.getList()
}
})
})
},
cancel (id) {
this.$confirm('确认撤回该群发任务?').then(() => {
this.instance.post(`/app/appmasssendingtaskxbot/cancel?id=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('撤回成功!')
this.getList()
}
})
})
},
remove(id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appmasssendingtaskxbot/delete?id=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
toAdd(id) {
this.$emit('change', {
type: 'Add',
params: {
id: id || '',
clientInfoId: this.params.id,
sendChannel: 0
}
})
},
toDetail (id) {
this.$emit('change', {
type: 'Detail',
params: {
id
}
})
},
cancel(isRefresh) {
this.$emit('change', {
type: 'List',
isRefresh: !!isRefresh
})
}
}
}
</script>
<style lang="scss" scoped>
.AppAnnounce {
height: 100%;
.dialog {
position: fixed;
left: 0;
top: 0;
z-index: 111;
width: 100%;
height: 100%;
.mask {
position: fixed;
left: 0;
top: 0;
z-index: 1;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
}
.dialog-wrapper {
position: absolute;
left: 50%;
top: 50%;
z-index: 2;
width: 600px;
height: 532px;
padding: 40px 64px;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 4px;
text-align: center;
transform: translate(-50%, -50%);
& > img {
position: absolute;
right: 16px;
top: 16px;
z-index: 2;
width: 16px;
height: 16px;
cursor: pointer;
}
h2 {
margin-bottom: 12px;
font-size: 24px;
color: #222;
}
& > p {
margin-bottom: 40px;
font-size: 12px;
color: #888888;
}
.dialog-list {
// display: flex;
// justify-content: space-between;
margin-bottom: 40px;
& > div {
// flex: 1;
width: 216px;
margin-left: 120px;
height: 280px;
padding: 24px;
background: #FFFFFF;
border: 1px solid #D0D4DC;
border-radius: 8px;
text-align: left;
cursor: pointer;
transition: all ease 0.3s;
&.active, &:hover {
background: #F7FAFF;
border: 1px solid #2266FF;
}
img {
width: 80px;
height: 80px;
margin-bottom: 32px;
}
p {
line-height: 22px;
font-size: 14px;
color: #888;
text-align: center;
}
h3 {
margin-bottom: 8px;
font-size: 18px;
color: #222;
font-weight: 600;
text-align: center;
}
&:first-child {
margin-right: 40px;
}
}
}
}
}
.userinfo {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
line-height: 1;
span:first-child {
margin-bottom: 4px;
}
}
.userSelcet {
display: flex;
align-items: center;
justify-content: space-between;
width: 215px;
height: 32px;
line-height: 32px;
border-radius: 4px;
border: 1px solid #d0d4dc;
overflow: hidden;
cursor: pointer;
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
&:hover {
border-color: $placeholderColor;
}
i {
display: flex;
position: relative;
align-items: center;
justify-content: center;
width: 30px;
height: 100%;
line-height: 32px;
font-size: 14px;
text-align: center;
color: #d0d4dc;
transform: rotateZ(180deg);
}
.el-icon-circle-close:hover {
opacity: 0.6;
}
span {
flex: 1;
padding: 0 15px;
font-size: 12px;
color: $placeholderColor;
}
}
:deep .AiTitle .iconBack_Large {
line-height: 22px!important;
}
}
</style>