群发居民群
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
<el-radio-group v-model="form.sendScope" @change="onScopeChange">
|
<el-radio-group v-model="form.sendScope" @change="onScopeChange">
|
||||||
<el-radio label="0">全部居民群</el-radio>
|
<el-radio label="0">全部居民群</el-radio>
|
||||||
<el-radio label="1">按部门选择</el-radio>
|
<el-radio label="1">按部门选择</el-radio>
|
||||||
<!-- <el-radio label="2">按网格选择</el-radio> -->
|
<el-radio label="2">按网格选择</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="选择群主" v-if="form.sendScope !== '0'" prop="wxGroupsName" style="width: 100%;" :rules="[{ required: true, message: '请选择选择群主', trigger: 'change' }]">
|
<el-form-item label="选择群主" v-if="form.sendScope !== '0'" prop="wxGroupsName" style="width: 100%;" :rules="[{ required: true, message: '请选择选择群主', trigger: 'change' }]">
|
||||||
@@ -131,12 +131,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
|
<!-- <div class="add-material add-item" @click="$refs.ChooseMaterial.open()">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/add.png"/>
|
||||||
|
<span style="color: #2266FF; font-size: 12px;">从素材库选择</span>
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<em>从本地上传,图片最大支持10MB,支持JPG,PNG格式;视频最大支持10MB,支持MP4格式;文件最大支持20MB</em>
|
<em>从本地上传,图片最大支持10MB,支持JPG,PNG格式;视频最大支持10MB,支持MP4格式;文件最大支持20MB</em>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="结束时间" v-if="params.sendChannel === '1'" style="width: 100%;" prop="taskEndTime" :rules="[{ required: true, message: '请选择结束时间', trigger: 'change' }]">
|
<el-form-item label="结束时间" style="width: 100%;" prop="taskEndTime" :rules="[{ required: true, message: '请选择结束时间', trigger: 'change' }]">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
v-model="form.taskEndTime"
|
v-model="form.taskEndTime"
|
||||||
@@ -184,29 +188,29 @@
|
|||||||
<div class="ai-form">
|
<div class="ai-form">
|
||||||
<el-form-item label="标题" style="width: 100%;" prop="linkTitle" :rules="[{ required: true, message: '请输入标题', trigger: 'blur' }]">
|
<el-form-item label="标题" style="width: 100%;" prop="linkTitle" :rules="[{ required: true, message: '请输入标题', trigger: 'blur' }]">
|
||||||
<el-input
|
<el-input
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="请输入标题"
|
placeholder="请输入标题"
|
||||||
maxlength="42"
|
maxlength="42"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
v-model="linkForm.linkTitle">
|
v-model="linkForm.linkTitle">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="链接" style="width: 100%;" prop="linkUrl" :rules="[{ required: true, message: '请输入链接', trigger: 'blur' }]">
|
<el-form-item label="链接" style="width: 100%;" prop="linkUrl" :rules="[{ required: true, message: '请输入链接', trigger: 'blur' }]">
|
||||||
<el-input
|
<el-input
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="请输入链接"
|
placeholder="请输入链接"
|
||||||
maxlength="682"
|
maxlength="682"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
v-model="linkForm.linkUrl">
|
v-model="linkForm.linkUrl">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="描述" style="width: 100%;" prop="linkDesc">
|
<el-form-item label="描述" style="width: 100%;" prop="linkDesc">
|
||||||
<el-input
|
<el-input
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="请输入描述"
|
placeholder="请输入描述"
|
||||||
maxlength="170"
|
maxlength="170"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
v-model="linkForm.linkDesc">
|
v-model="linkForm.linkDesc">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="封面图" prop="linkPicUrl" style="width: 100%;">
|
<el-form-item label="封面图" prop="linkPicUrl" style="width: 100%;">
|
||||||
@@ -216,34 +220,34 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</ai-dialog>
|
</ai-dialog>
|
||||||
<ai-dialog
|
<ai-dialog
|
||||||
:visible.sync="isShowAddMiniapp"
|
:visible.sync="isShowAddMiniapp"
|
||||||
width="920px"
|
width="920px"
|
||||||
title="小程序消息"
|
title="小程序消息"
|
||||||
@close="onClose"
|
@close="onClose"
|
||||||
@onConfirm="onMiniAppForm">
|
@onConfirm="onMiniAppForm">
|
||||||
<el-form ref="miniAppForm" :model="miniAppForm" label-width="130px" label-position="right">
|
<el-form ref="miniAppForm" :model="miniAppForm" label-width="130px" label-position="right">
|
||||||
<div class="ai-form">
|
<div class="ai-form">
|
||||||
<el-form-item label="小程序appid" style="width: 100%;" prop="mpAppid" :rules="[{ required: true, message: '小程序appid', trigger: 'blur' }]">
|
<el-form-item label="小程序appid" style="width: 100%;" prop="mpAppid" :rules="[{ required: true, message: '小程序appid', trigger: 'blur' }]">
|
||||||
<el-input
|
<el-input
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="小程序appid"
|
placeholder="小程序appid"
|
||||||
v-model="miniAppForm.mpAppid">
|
v-model="miniAppForm.mpAppid">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="小程序page路径" style="width: 100%;" prop="mpPage" :rules="[{ required: true, message: '请输入小程序page路径', trigger: 'blur' }]">
|
<el-form-item label="小程序page路径" style="width: 100%;" prop="mpPage" :rules="[{ required: true, message: '请输入小程序page路径', trigger: 'blur' }]">
|
||||||
<el-input
|
<el-input
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="请输入小程序page路径"
|
placeholder="请输入小程序page路径"
|
||||||
v-model="miniAppForm.mpPage">
|
v-model="miniAppForm.mpPage">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="标题" style="width: 100%;" prop="mpTitle" :rules="[{ required: true, message: '请输入标题', trigger: 'blur' }]">
|
<el-form-item label="标题" style="width: 100%;" prop="mpTitle" :rules="[{ required: true, message: '请输入标题', trigger: 'blur' }]">
|
||||||
<el-input
|
<el-input
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="请输入标题"
|
placeholder="请输入标题"
|
||||||
maxlength="20"
|
maxlength="20"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
v-model="miniAppForm.mpTitle">
|
v-model="miniAppForm.mpTitle">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="封面图" prop="media" style="width: 100%;" :rules="[{ required: true, message: '请上传封面图', trigger: 'change' }]">
|
<el-form-item label="封面图" prop="media" style="width: 100%;" :rules="[{ required: true, message: '请上传封面图', trigger: 'change' }]">
|
||||||
@@ -277,6 +281,7 @@
|
|||||||
<el-button @click="onDateForm" type="primary" :loading="isLoading2" style="width: 92px;">确认</el-button>
|
<el-button @click="onDateForm" type="primary" :loading="isLoading2" style="width: 92px;">确认</el-button>
|
||||||
</div>
|
</div>
|
||||||
</ai-dialog>
|
</ai-dialog>
|
||||||
|
<ChooseMaterial ref="ChooseMaterial" :instance="instance" @change="onChooseChange"></ChooseMaterial>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -289,7 +294,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Phone from './Phone'
|
import Phone from './Phone'
|
||||||
import {mapActions, mapState} from 'vuex'
|
import ChooseMaterial from './ChooseMaterial.vue'
|
||||||
|
import { mapActions, mapState } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Add',
|
name: 'Add',
|
||||||
@@ -301,13 +307,15 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Phone
|
Phone,
|
||||||
|
ChooseMaterial
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
info: {},
|
info: {},
|
||||||
department: [],
|
department: [],
|
||||||
|
isShowChoose: false,
|
||||||
isLoading1: false,
|
isLoading1: false,
|
||||||
isLoading2: false,
|
isLoading2: false,
|
||||||
fileList: [],
|
fileList: [],
|
||||||
@@ -382,6 +390,12 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
...mapActions(['initOpenData', 'transCanvas']),
|
...mapActions(['initOpenData', 'transCanvas']),
|
||||||
|
|
||||||
|
onChooseChange (e) {
|
||||||
|
this.form.content = e.filter(v => v.msgType === '0').map(v => v.content).join(' ')
|
||||||
|
|
||||||
|
this.fileList = this.fileList.concat(e.filter(v => v.msgType !== '0'))
|
||||||
|
},
|
||||||
|
|
||||||
getInfo(id) {
|
getInfo(id) {
|
||||||
this.instance.post(`/app/appmasssendingtask/queryDetailById?id=${id}`).then(res => {
|
this.instance.post(`/app/appmasssendingtask/queryDetailById?id=${id}`).then(res => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
@@ -747,6 +761,7 @@ export default {
|
|||||||
|
|
||||||
.add {
|
.add {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
position: relative;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 14px 16px;
|
padding: 14px 16px;
|
||||||
background: #F9F9F9;
|
background: #F9F9F9;
|
||||||
@@ -754,6 +769,13 @@ export default {
|
|||||||
border: 1px solid #D0D4DC;
|
border: 1px solid #D0D4DC;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|
||||||
|
.add-material {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 14px;
|
||||||
|
left: 16px;
|
||||||
|
transform: translateX(120%);
|
||||||
|
}
|
||||||
|
|
||||||
.add-item {
|
.add-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -0,0 +1,221 @@
|
|||||||
|
<template>
|
||||||
|
<div id="ChooseMaterial">
|
||||||
|
<ai-dialog
|
||||||
|
:visible.sync="isShow"
|
||||||
|
width="890px"
|
||||||
|
@onConfirm="onConfirm"
|
||||||
|
title="选择素材">
|
||||||
|
<div class="AppMaterialLibrary-title">
|
||||||
|
<span
|
||||||
|
v-for="(item, index) in typeList"
|
||||||
|
:key="index"
|
||||||
|
:class="[currIndex === index ? 'active' : '']" @click="currIndex = index, search.current = 1, getList()">
|
||||||
|
{{ item }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ai-search-bar class="search-bar">
|
||||||
|
<template #left>
|
||||||
|
</template>
|
||||||
|
<template slot="right">
|
||||||
|
<el-input
|
||||||
|
v-model="search.title"
|
||||||
|
size="small"
|
||||||
|
v-throttle="() => { search.current = 1, getList() }"
|
||||||
|
placeholder="请输入标题、话术内容、添加人"
|
||||||
|
clearable
|
||||||
|
@clear="search.current = 1, search.title = '', getList()"
|
||||||
|
suffix-icon="iconfont iconSearch">
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table
|
||||||
|
v-if="isShow"
|
||||||
|
:tableData="tableData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
:total="total"
|
||||||
|
style="margin-top: 6px; width: 100%;"
|
||||||
|
:current.sync="search.current"
|
||||||
|
:size.sync="search.size"
|
||||||
|
@selection-change="onSelectChange"
|
||||||
|
@getList="getList">
|
||||||
|
</ai-table>
|
||||||
|
</ai-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ChooseMaterial',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
search: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
title: '',
|
||||||
|
},
|
||||||
|
ids: [],
|
||||||
|
isShow: false,
|
||||||
|
id: '',
|
||||||
|
typeList: ['话术', '图片', '小程序', '文件', '视频', '网页'],
|
||||||
|
currIndex: 0,
|
||||||
|
tableData: [],
|
||||||
|
total: 0,
|
||||||
|
value: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
mpTitle () {
|
||||||
|
return {
|
||||||
|
'0': '话术标题',
|
||||||
|
'1': '图片名称',
|
||||||
|
'2': '小程序标题',
|
||||||
|
'3': '文件名称',
|
||||||
|
'4': '视频名称',
|
||||||
|
'5': '网页名称'
|
||||||
|
}[this.currIndex]
|
||||||
|
},
|
||||||
|
|
||||||
|
colConfigs () {
|
||||||
|
if (this.currIndex === 0) {
|
||||||
|
return [
|
||||||
|
{ type: 'selection' },
|
||||||
|
{ prop: 'title', label: this.mpTitle },
|
||||||
|
{ prop: 'content', label: '话术内容', align: 'center' },
|
||||||
|
{ prop: 'createUserName', label: '添加人', align: 'center' },
|
||||||
|
{ prop: 'createTime', label: '添加时间', align: 'center' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currIndex === 2) {
|
||||||
|
return [
|
||||||
|
{ type: 'selection' },
|
||||||
|
{ prop: 'mpTitle', label: this.mpTitle },
|
||||||
|
{ prop: 'mpAppid', label: '小程序APPID', align: 'center' },
|
||||||
|
{ prop: 'createUserName', label: '添加人', align: 'center' },
|
||||||
|
{ prop: 'createTime', label: '添加时间', align: 'center' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currIndex === 5) {
|
||||||
|
return [
|
||||||
|
{ type: 'selection' },
|
||||||
|
{ prop: 'linkTitle', label: this.mpTitle },
|
||||||
|
{ prop: 'linkUrl', label: '外链网页', align: 'center' },
|
||||||
|
{ prop: 'createUserName', label: '添加人', align: 'center' },
|
||||||
|
{ prop: 'createTime', label: '添加时间', align: 'center' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{ type: 'selection' },
|
||||||
|
{ prop: 'title', label: this.mpTitle },
|
||||||
|
{ prop: 'fileSizeStr', label: '文件大小', align: 'center' },
|
||||||
|
{ prop: 'createUserName', label: '添加人', align: 'center' },
|
||||||
|
{ prop: 'createTime', label: '添加时间', align: 'center' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getList() {
|
||||||
|
this.instance.post(`/app/appmaterialinfo/listByMST`, null, {
|
||||||
|
params: {
|
||||||
|
...this.search,
|
||||||
|
mstType: 0,
|
||||||
|
type: this.currIndex
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.tableData = res.data.records
|
||||||
|
this.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onSelectChange (e) {
|
||||||
|
this.value = e
|
||||||
|
},
|
||||||
|
|
||||||
|
onConfirm () {
|
||||||
|
if (!this.value.length) {
|
||||||
|
return this.$message.error('请选择素材')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.value.length > 9) {
|
||||||
|
return this.$message.error('素材不能超过9个')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('change', this.value)
|
||||||
|
this.isShow = false
|
||||||
|
},
|
||||||
|
|
||||||
|
open () {
|
||||||
|
this.value = []
|
||||||
|
this.isShow = true
|
||||||
|
},
|
||||||
|
|
||||||
|
close () {
|
||||||
|
this.isShow = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#ChooseMaterial {
|
||||||
|
:deep( .ai-list__content--right-wrapper ) {
|
||||||
|
padding: 0 20px!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep( .el-dialog__header ) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep( .el-dialog__body ) {
|
||||||
|
padding-top: 0!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppMaterialLibrary-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
|
||||||
|
span {
|
||||||
|
height: 100%;
|
||||||
|
line-height: 56px;
|
||||||
|
margin-right: 32px;
|
||||||
|
color: #888888;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: all ease 0.3s;
|
||||||
|
border-bottom: 3px solid transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #222222;
|
||||||
|
border-bottom: 3px solid #2266FF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -230,6 +230,7 @@
|
|||||||
:visible.sync="isShowGroups"
|
:visible.sync="isShowGroups"
|
||||||
width="890px"
|
width="890px"
|
||||||
title="群发范围"
|
title="群发范围"
|
||||||
|
customFooter
|
||||||
@onConfirm="isShowGroups = false">
|
@onConfirm="isShowGroups = false">
|
||||||
<ai-table
|
<ai-table
|
||||||
:tableData="info.wxGroups"
|
:tableData="info.wxGroups"
|
||||||
@@ -239,6 +240,9 @@
|
|||||||
:isShowPagination="false"
|
:isShowPagination="false"
|
||||||
@getList="() => {}">
|
@getList="() => {}">
|
||||||
</ai-table>
|
</ai-table>
|
||||||
|
<div class="dialog-footer" slot="footer">
|
||||||
|
<el-button @click="isShowGroups = false">关闭</el-button>
|
||||||
|
</div>
|
||||||
</ai-dialog>
|
</ai-dialog>
|
||||||
<div class="detail-phone" v-if="isShowPhone">
|
<div class="detail-phone" v-if="isShowPhone">
|
||||||
<div class="mask"></div>
|
<div class="mask"></div>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<template slot="content">
|
<template slot="content">
|
||||||
<ai-search-bar class="search-bar">
|
<ai-search-bar class="search-bar">
|
||||||
<template #left>
|
<template #left>
|
||||||
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd(0, '')">创建宣发</el-button>
|
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">创建宣发</el-button>
|
||||||
<ai-select
|
<ai-select
|
||||||
v-model="search.status"
|
v-model="search.status"
|
||||||
@change="search.current = 1, getList()"
|
@change="search.current = 1, getList()"
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</ai-table>
|
</ai-table>
|
||||||
<div class="dialog" v-if="isShow">
|
<!-- <div class="dialog" v-if="isShow">
|
||||||
<div class="mask"></div>
|
<div class="mask"></div>
|
||||||
<div class="dialog-wrapper">
|
<div class="dialog-wrapper">
|
||||||
<img src="https://cdn.cunwuyun.cn/dvcp/announce/close1.png" @click="isShow = false" />
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/close1.png" @click="isShow = false" />
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-button style="width: 106px;" size="small" type="primary" icon="iconfont" @click="isShow = false, toAdd(currIndex, '')">去创建</el-button>
|
<el-button style="width: 106px;" size="small" type="primary" icon="iconfont" @click="isShow = false, toAdd(currIndex, '')">去创建</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</template>
|
</template>
|
||||||
</ai-list>
|
</ai-list>
|
||||||
</template>
|
</template>
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
startTime: '',
|
startTime: '',
|
||||||
endTime: ''
|
endTime: ''
|
||||||
},
|
},
|
||||||
currIndex: '0',
|
currIndex: '1',
|
||||||
name: '',
|
name: '',
|
||||||
isShow: false,
|
isShow: false,
|
||||||
user: [],
|
user: [],
|
||||||
@@ -140,6 +140,7 @@
|
|||||||
{ prop: 'typeName', label: '群发类型', align: 'center' },
|
{ prop: 'typeName', label: '群发类型', align: 'center' },
|
||||||
{ slot: 'user', label: '创建人', openType: 'userName', align: 'center' },
|
{ slot: 'user', label: '创建人', openType: 'userName', align: 'center' },
|
||||||
{ prop: 'choiceTime', label: '群发时间', align: 'center' },
|
{ prop: 'choiceTime', label: '群发时间', align: 'center' },
|
||||||
|
{ prop: 'taskEndTime', label: '群发结束时间', align: 'center' },
|
||||||
{
|
{
|
||||||
prop: 'status',
|
prop: 'status',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
@@ -248,12 +249,12 @@
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
toAdd(type, id) {
|
toAdd(id) {
|
||||||
this.$emit('change', {
|
this.$emit('change', {
|
||||||
type: 'Add',
|
type: 'Add',
|
||||||
params: {
|
params: {
|
||||||
id,
|
id: id || '',
|
||||||
sendChannel: type
|
sendChannel: 0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -329,12 +330,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dialog-list {
|
.dialog-list {
|
||||||
display: flex;
|
// display: flex;
|
||||||
justify-content: space-between;
|
// justify-content: space-between;
|
||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
flex: 1;
|
// flex: 1;
|
||||||
|
width: 216px;
|
||||||
|
margin-left: 120px;
|
||||||
height: 280px;
|
height: 280px;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
|
|||||||
@@ -24,14 +24,14 @@
|
|||||||
<img :src="item.imgPicUrl" />
|
<img :src="item.imgPicUrl" />
|
||||||
</div>
|
</div>
|
||||||
<div class="msg-wrapper msg-video" v-if="item.msgType === '2'">
|
<div class="msg-wrapper msg-video" v-if="item.msgType === '2'">
|
||||||
<video controls :src="item.url"></video>
|
<video controls :src="item.url || item.fileUrl"></video>
|
||||||
</div>
|
</div>
|
||||||
<div class="msg-wrapper msg-file" v-if="item.msgType === '3'">
|
<div class="msg-wrapper msg-file" v-if="item.msgType === '3'">
|
||||||
<div class="msg-left">
|
<div class="msg-left">
|
||||||
<h2>{{ item.name }}</h2>
|
<h2>{{ item.name || item.title }}</h2>
|
||||||
<p>{{ item.fileSizeStr }}</p>
|
<p>{{ item.fileSizeStr }}</p>
|
||||||
</div>
|
</div>
|
||||||
<img :src="mapIcon(item.name)" />
|
<img :src="mapIcon(item.name || item.fileUrl)" />
|
||||||
</div>
|
</div>
|
||||||
<div class="msg-wrapper msg-link" v-if="item.msgType === '4'">
|
<div class="msg-wrapper msg-link" v-if="item.msgType === '4'">
|
||||||
<h2>{{ item.linkTitle }}</h2>
|
<h2>{{ item.linkTitle }}</h2>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="msg-wrapper msg-miniapp" v-if="item.msgType === '5'">
|
<div class="msg-wrapper msg-miniapp" v-if="item.msgType === '5'">
|
||||||
<h2>{{ item.mpTitle }}</h2>
|
<h2>{{ item.mpTitle }}</h2>
|
||||||
<img :src="item.url" />
|
<img :src="item.url || item.pictureUrl" />
|
||||||
<div class="msg-bottom">
|
<div class="msg-bottom">
|
||||||
<i>小程序</i>
|
<i>小程序</i>
|
||||||
<img src="https://cdn.cunwuyun.cn/dvcp/announce/miniapp.png">
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/miniapp.png">
|
||||||
|
|||||||
79
project/qianxinan/AnnounceOld/AppAnnounce/AppAnnounce.vue
Normal file
79
project/qianxinan/AnnounceOld/AppAnnounce/AppAnnounce.vue
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<div class="AppAnnounce">
|
||||||
|
<!-- <keep-alive :include="['List']"> -->
|
||||||
|
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||||
|
<!-- </keep-alive> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import List from './components/List'
|
||||||
|
import Add from './components/Add'
|
||||||
|
import Detail from './components/Detail'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AppAnnounce',
|
||||||
|
label: '群发居民群',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
component: 'List',
|
||||||
|
params: {},
|
||||||
|
include: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
Add,
|
||||||
|
List,
|
||||||
|
Detail
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
if (this.$route.params.id) {
|
||||||
|
this.component = 'Detail'
|
||||||
|
this.params = {
|
||||||
|
id: this.$route.params.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onChange (data) {
|
||||||
|
if (data.type === 'Add') {
|
||||||
|
this.component = 'Add'
|
||||||
|
this.params = data.params
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'Detail') {
|
||||||
|
this.component = 'Detail'
|
||||||
|
this.params = data.params
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'list') {
|
||||||
|
this.component = 'List'
|
||||||
|
this.params = data.params
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (data.isRefresh) {
|
||||||
|
this.$refs.component.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.AppAnnounce {
|
||||||
|
height: 100%;
|
||||||
|
background: #F3F6F9;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
934
project/qianxinan/AnnounceOld/AppAnnounce/components/Add.vue
Normal file
934
project/qianxinan/AnnounceOld/AppAnnounce/components/Add.vue
Normal file
@@ -0,0 +1,934 @@
|
|||||||
|
<template>
|
||||||
|
<ai-detail class="AppAnnounceAdd">
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title :title="id ? '编辑群发居民群' : '添加群发居民群'" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||||
|
</ai-title>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<div class="AppAnnounceDetail-container">
|
||||||
|
<el-form ref="form" class="left" :model="form" label-width="110px" label-position="right">
|
||||||
|
<ai-card title="基本信息">
|
||||||
|
<template #content>
|
||||||
|
<div class="ai-form">
|
||||||
|
<el-form-item label="任务名称" prop="taskTitle" style="width: 100%;" :rules="[{ required: true, message: '请输入任务名称', trigger: 'blur' }]">
|
||||||
|
<el-input size="small" placeholder="请输入任务名称" v-model="form.taskTitle" :maxlength="15" show-word-limit></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="发送范围" style="width: 100%;" prop="sendScope" :rules="[{ required: true, message: '请选择发送范围', trigger: 'change' }]">
|
||||||
|
<el-radio-group v-model="form.sendScope" @change="onScopeChange">
|
||||||
|
<el-radio label="0">全部居民群</el-radio>
|
||||||
|
<el-radio label="1">按部门选择</el-radio>
|
||||||
|
<!-- <el-radio label="2">按网格选择</el-radio> -->
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="选择群主" v-if="form.sendScope !== '0'" prop="wxGroupsName" style="width: 100%;" :rules="[{ required: true, message: '请选择选择群主', trigger: 'change' }]">
|
||||||
|
<ai-picker
|
||||||
|
:instance="instance"
|
||||||
|
multiple
|
||||||
|
:dialogTitle="form.sendScope === '2' ? '选择网格' : '选择部门'"
|
||||||
|
:ops="{label: form.sendScope === '2' ? 'girdName' : 'name'}"
|
||||||
|
:pageTitle="form.sendScope === '2' ? '网格' : '部门'"
|
||||||
|
:action="form.sendScope === '1' ? '/app/wxcp/wxdepartment/departList' : '/app/appgirdinfo/girdList'"
|
||||||
|
v-model="form.filterCriteria"
|
||||||
|
@pick="onPick"
|
||||||
|
@change="onSelcetChange">
|
||||||
|
<div class="AppAnnounceDetail-select">
|
||||||
|
<el-input size="small" class="AppAnnounceDetail-select__input" placeholder="请选择..." disabled v-model="form.wxGroupsName"></el-input>
|
||||||
|
<div class="select-left" v-if="form.wxGroups.length">
|
||||||
|
<span v-for="(item, index) in form.wxGroups" :key="index" v-if="index < 9">{{ item.groupOwnerName }}</span>
|
||||||
|
<em v-if="form.wxGroups.length > 9">等{{ form.wxGroups.length }}个</em>
|
||||||
|
</div>
|
||||||
|
<i v-if="!form.wxGroups.length">请选择</i>
|
||||||
|
<div class="select-right">{{ form.filterCriteria.length ? '重新选择' : '选择' }}</div>
|
||||||
|
</div>
|
||||||
|
</ai-picker>
|
||||||
|
<div class="tips">
|
||||||
|
<p>消息预计送达居民群数:</p>
|
||||||
|
<span>{{ groupLen }}</span>
|
||||||
|
<el-tooltip
|
||||||
|
placement="top"
|
||||||
|
content="将由指定群主发送给TA作为群主的所有的群,由于企业微信限制,当超过1000个时将只发送到最近活跃的1000个群">
|
||||||
|
<i class="iconfont iconModal_Warning"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="发送内容" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请输入发送内容', trigger: 'blur' }]">
|
||||||
|
<el-input size="small" type="textarea" :rows="6" maxlength="1300" show-word-limit placeholder="请输入文本内容..." v-model="form.content"></el-input>
|
||||||
|
<div class="add">
|
||||||
|
<div class="fileList" v-if="fileList.length">
|
||||||
|
<div class="add-item" v-for="(item, index) in fileList" :key="index">
|
||||||
|
<div class="left">
|
||||||
|
<img :src="mapIcon(item.msgType)"/>
|
||||||
|
<span>{{ item.mpTitle || item.name || item.linkTitle }}</span>
|
||||||
|
</div>
|
||||||
|
<i @click="removeFile(index)">删除</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-popover
|
||||||
|
placement="top"
|
||||||
|
width="340"
|
||||||
|
offset="0"
|
||||||
|
trigger="hover">
|
||||||
|
<div class="add-item" slot="reference" style="width: max-content;">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/add.png"/>
|
||||||
|
<span style="color: #2266FF; font-size: 12px;">添加附件类型</span>
|
||||||
|
</div>
|
||||||
|
<div class="AppAnnounceDetail-content-wrapper">
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
multiple
|
||||||
|
:file-list="fileList"
|
||||||
|
:show-file-list="false"
|
||||||
|
:before-upload="v => handleChange(v, 10, '.jpg,.png,.jpeg')"
|
||||||
|
:limit="9"
|
||||||
|
action="/app/wxcp/upload/uploadFile"
|
||||||
|
accept=".jpg,.png,.jpeg"
|
||||||
|
:on-exceed="onExceed"
|
||||||
|
:http-request="v => submitUpload(v, '1')">
|
||||||
|
<div class="content-item" trigger>
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/big-img.png"/>
|
||||||
|
<p>图片</p>
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
multiple
|
||||||
|
:file-list="fileList"
|
||||||
|
:show-file-list="false"
|
||||||
|
:before-upload="v => handleChange(v, 10, '.mp4')"
|
||||||
|
:limit="9"
|
||||||
|
action="/app/wxcp/upload/uploadFile"
|
||||||
|
accept=".mp4"
|
||||||
|
:on-exceed="onExceed"
|
||||||
|
:http-request="v => submitUpload(v, '2')">
|
||||||
|
<div class="content-item" trigger>
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/big-video.png"/>
|
||||||
|
<p>视频</p>
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
multiple
|
||||||
|
:file-list="fileList"
|
||||||
|
:show-file-list="false"
|
||||||
|
:before-upload="v => handleChange(v, 20, '.zip,.rar,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt')"
|
||||||
|
:limit="9"
|
||||||
|
:on-exceed="onExceed"
|
||||||
|
action="/app/wxcp/upload/uploadFile"
|
||||||
|
accept=".zip,.rar,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt"
|
||||||
|
:http-request="v => submitUpload(v, '3')">
|
||||||
|
<div class="content-item" trigger>
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/folder.png"/>
|
||||||
|
<p>文件</p>
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
<div class="content-item" @click="isShowAddLink = true">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/site.png"/>
|
||||||
|
<p>网页</p>
|
||||||
|
</div>
|
||||||
|
<div class="content-item" @click="isShowAddMiniapp = true">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/miniapp.png"/>
|
||||||
|
<p>小程序</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
<div class="tips">
|
||||||
|
<em>从本地上传,图片最大支持10MB,支持JPG,PNG格式;视频最大支持10MB,支持MP4格式;文件最大支持20MB</em>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束时间" v-if="params.sendChannel === '1'" style="width: 100%;" prop="taskEndTime" :rules="[{ required: true, message: '请选择结束时间', trigger: 'change' }]">
|
||||||
|
<el-date-picker
|
||||||
|
style="width: 100%;"
|
||||||
|
v-model="form.taskEndTime"
|
||||||
|
type="datetime"
|
||||||
|
size="small"
|
||||||
|
:picker-options="pickerOptions"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
placeholder="请选择结束时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="宣发审批" prop="enableExamine" style="width: 100%;" :rules="[{ required: true, message: '请输入任务名称', trigger: 'blur' }]">
|
||||||
|
<el-switch
|
||||||
|
v-model="form.enableExamine"
|
||||||
|
active-value="1"
|
||||||
|
inactive-value="0"
|
||||||
|
active-text="开启后,创建的群发任务需要审批人进行审批">
|
||||||
|
</el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="form.enableExamine === '1'" label="审批人员" prop="examines" style="width: 100%;" :rules="[{ required: true, message: '请选择审批人员', trigger: 'change' }]">
|
||||||
|
<ai-user-selecter :instance="instance" v-model="form.examines" @change="onUserChange">
|
||||||
|
<div class="AppAnnounceDetail-select">
|
||||||
|
<el-input class="AppAnnounceDetail-select__input" size="small" placeholder="请选择..." v-model="form.examinesName"></el-input>
|
||||||
|
<div class="select-left" v-if="form.examines.length">
|
||||||
|
<span v-for="(item, index) in form.examines" :key="index">{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
<i v-if="!form.examines.length">请选择</i>
|
||||||
|
<div class="select-right">{{ form.examines.length ? '重新选择' : '选择' }}</div>
|
||||||
|
</div>
|
||||||
|
</ai-user-selecter>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</el-form>
|
||||||
|
<div class="right">
|
||||||
|
<Phone :avatar="user.info.avatar" @close="isShowPhone = false" :isShowClose="false" :content="form.content" :fileList="fileList"></Phone>
|
||||||
|
</div>
|
||||||
|
<ai-dialog
|
||||||
|
:visible.sync="isShowAddLink"
|
||||||
|
width="920px"
|
||||||
|
title="链接消息"
|
||||||
|
@close="onClose"
|
||||||
|
@onConfirm="onLinkConfirm">
|
||||||
|
<el-form ref="linkForm" :model="linkForm" label-width="110px" label-position="right">
|
||||||
|
<div class="ai-form">
|
||||||
|
<el-form-item label="标题" style="width: 100%;" prop="linkTitle" :rules="[{ required: true, message: '请输入标题', trigger: 'blur' }]">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
placeholder="请输入标题"
|
||||||
|
maxlength="42"
|
||||||
|
show-word-limit
|
||||||
|
v-model="linkForm.linkTitle">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="链接" style="width: 100%;" prop="linkUrl" :rules="[{ required: true, message: '请输入链接', trigger: 'blur' }]">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
placeholder="请输入链接"
|
||||||
|
maxlength="682"
|
||||||
|
show-word-limit
|
||||||
|
v-model="linkForm.linkUrl">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="描述" style="width: 100%;" prop="linkDesc">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
placeholder="请输入描述"
|
||||||
|
maxlength="170"
|
||||||
|
show-word-limit
|
||||||
|
v-model="linkForm.linkDesc">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="封面图" prop="linkPicUrl" style="width: 100%;">
|
||||||
|
<ai-uploader :instance="instance" v-model="linkForm.linkPicUrl" :limit="1"></ai-uploader>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</ai-dialog>
|
||||||
|
<ai-dialog
|
||||||
|
:visible.sync="isShowAddMiniapp"
|
||||||
|
width="920px"
|
||||||
|
title="小程序消息"
|
||||||
|
@close="onClose"
|
||||||
|
@onConfirm="onMiniAppForm">
|
||||||
|
<el-form ref="miniAppForm" :model="miniAppForm" label-width="130px" label-position="right">
|
||||||
|
<div class="ai-form">
|
||||||
|
<el-form-item label="小程序appid" style="width: 100%;" prop="mpAppid" :rules="[{ required: true, message: '小程序appid', trigger: 'blur' }]">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
placeholder="小程序appid"
|
||||||
|
v-model="miniAppForm.mpAppid">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="小程序page路径" style="width: 100%;" prop="mpPage" :rules="[{ required: true, message: '请输入小程序page路径', trigger: 'blur' }]">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
placeholder="请输入小程序page路径"
|
||||||
|
v-model="miniAppForm.mpPage">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="标题" style="width: 100%;" prop="mpTitle" :rules="[{ required: true, message: '请输入标题', trigger: 'blur' }]">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
placeholder="请输入标题"
|
||||||
|
maxlength="20"
|
||||||
|
show-word-limit
|
||||||
|
v-model="miniAppForm.mpTitle">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="封面图" prop="media" style="width: 100%;" :rules="[{ required: true, message: '请上传封面图', trigger: 'change' }]">
|
||||||
|
<ai-uploader url="/app/wxcp/upload/uploadFile?type=image" :instance="instance" isWechat v-model="miniAppForm.media" :limit="1"></ai-uploader>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</ai-dialog>
|
||||||
|
<ai-dialog
|
||||||
|
:visible.sync="isShowDate"
|
||||||
|
width="590px"
|
||||||
|
title="定时发送"
|
||||||
|
customFooter>
|
||||||
|
<el-form ref="dateForm" :model="dateForm" label-width="130px" label-position="right">
|
||||||
|
<div class="ai-form">
|
||||||
|
<el-form-item label="定时发送时间" style="width: 100%;" prop="choiceTime" :rules="[{ required: true, message: '请选择定时发送时间', trigger: 'change' }]">
|
||||||
|
<el-date-picker
|
||||||
|
style="width: 100%;"
|
||||||
|
v-model="dateForm.choiceTime"
|
||||||
|
type="datetime"
|
||||||
|
size="small"
|
||||||
|
:picker-options="pickerOptions"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
placeholder="请选择定时发送时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
<div class="dialog-footer" slot="footer">
|
||||||
|
<el-button @click="onClose">取消</el-button>
|
||||||
|
<el-button @click="onDateForm" type="primary" :loading="isLoading2" style="width: 92px;">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</ai-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="cancel">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirm(0)" :loading="isLoading1" style="width: 120px;">通知成员发送</el-button>
|
||||||
|
<el-button type="primary" @click="confirm(1)">定时发送</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Phone from './Phone'
|
||||||
|
import {mapActions, mapState} from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Add',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
params: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
Phone
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
info: {},
|
||||||
|
department: [],
|
||||||
|
isLoading1: false,
|
||||||
|
isLoading2: false,
|
||||||
|
fileList: [],
|
||||||
|
isShowAddLink: false,
|
||||||
|
isShowAddMiniapp: false,
|
||||||
|
isShowDate: false,
|
||||||
|
isLoading: false,
|
||||||
|
linkForm: {
|
||||||
|
linkPicUrl: [],
|
||||||
|
linkDesc: '',
|
||||||
|
linkTitle: '',
|
||||||
|
linkUrl: ''
|
||||||
|
},
|
||||||
|
dateForm: {
|
||||||
|
choiceTime: ''
|
||||||
|
},
|
||||||
|
miniAppForm: {
|
||||||
|
mpAppid: '',
|
||||||
|
mpPage: '',
|
||||||
|
mpTitle: '',
|
||||||
|
media: []
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
content: '',
|
||||||
|
choiceTime: '',
|
||||||
|
contents: [],
|
||||||
|
enableExamine: '0',
|
||||||
|
taskEndTime: '',
|
||||||
|
examines: [],
|
||||||
|
wxGroups: [],
|
||||||
|
wxGroupsName: '',
|
||||||
|
sendScope: '0',
|
||||||
|
sendType: 0,
|
||||||
|
name: '',
|
||||||
|
filterCriteria: [],
|
||||||
|
taskTitle: '',
|
||||||
|
examinesName: ''
|
||||||
|
},
|
||||||
|
girdNames: '',
|
||||||
|
id: '',
|
||||||
|
tagsList: [],
|
||||||
|
pickerOptions: {
|
||||||
|
disabledDate: e => {
|
||||||
|
return e.getTime() < (Date.now() - 60 * 1000 * 60 * 24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user']),
|
||||||
|
|
||||||
|
groupLen() {
|
||||||
|
let i = 0
|
||||||
|
this.form.wxGroups.forEach(v => {
|
||||||
|
i = i + v.groupIds.split(',').length
|
||||||
|
})
|
||||||
|
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.params && this.params.id) {
|
||||||
|
this.id = this.params.id
|
||||||
|
this.getInfo(this.params.id)
|
||||||
|
} else {
|
||||||
|
this.getWxGroups()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
...mapActions(['initOpenData', 'transCanvas']),
|
||||||
|
|
||||||
|
getInfo(id) {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/queryDetailById?id=${id}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.form = {
|
||||||
|
...this.form,
|
||||||
|
...res.data,
|
||||||
|
wxGroupsName: '1',
|
||||||
|
filterCriteria: res.data.filterCriteria.split(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.data.girdNames) {
|
||||||
|
this.girdNames = res.data.girdNames.split(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dateForm.choiceTime = ''
|
||||||
|
|
||||||
|
if (res.data.examines && res.data.examines.length) {
|
||||||
|
this.form.examines = res.data.examines.map(v => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
wxOpenUserId: v.examineUserId,
|
||||||
|
id: v.examineUserId,
|
||||||
|
name: v.examineUserName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.form.examinesName = '1'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const content = res.data.contents.filter(v => v.msgType === '0')
|
||||||
|
|
||||||
|
if (content.length) {
|
||||||
|
this.$set(this.form, 'content', content[0].content)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fileList = res.data.contents.filter(v => v.msgType !== '0').map(v => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
...v.sysFile
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onUserChange(e) {
|
||||||
|
if (e.length) {
|
||||||
|
this.form.examinesName = '1'
|
||||||
|
} else {
|
||||||
|
this.form.wxGroupsName = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onScopeChange(e) {
|
||||||
|
this.form.filterCriteria = []
|
||||||
|
this.form.wxGroups = []
|
||||||
|
this.girdNames = ''
|
||||||
|
|
||||||
|
if (e === '0') {
|
||||||
|
this.getWxGroups()
|
||||||
|
} else {
|
||||||
|
this.form.filterCriteria = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onPick(e) {
|
||||||
|
if (this.form.sendScope === '2' && e.length) {
|
||||||
|
this.girdNames = e.map(v => v.girdName)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onSelcetChange(e) {
|
||||||
|
if (e.length) {
|
||||||
|
this.form.wxGroupsName = '1'
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getWxGroups()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.form.wxGroupsName = ''
|
||||||
|
this.form.wxGroups = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getWxGroups() {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/queryWxGroups?sendScope=${this.form.sendScope}`, {
|
||||||
|
filterCriteria: this.form.filterCriteria.join(',')
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.form.wxGroups = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onLinkConfirm() {
|
||||||
|
this.$refs.linkForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.fileList.push({
|
||||||
|
...this.linkForm,
|
||||||
|
linkPicUrl: this.linkForm.linkPicUrl.length ? this.linkForm.linkPicUrl[0].url : '',
|
||||||
|
msgType: '4'
|
||||||
|
})
|
||||||
|
|
||||||
|
this.isShowAddLink = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onMiniAppForm() {
|
||||||
|
this.$refs.miniAppForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.fileList.push({
|
||||||
|
...this.miniAppForm,
|
||||||
|
msgType: '5',
|
||||||
|
...this.miniAppForm.media[0],
|
||||||
|
mediaId: this.miniAppForm.media[0].media.mediaId,
|
||||||
|
sysFileId: this.miniAppForm.media[0].id
|
||||||
|
})
|
||||||
|
|
||||||
|
this.isShowAddMiniapp = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onClose() {
|
||||||
|
this.linkForm.linkPicUrl = []
|
||||||
|
this.linkForm.linkDesc = ''
|
||||||
|
this.linkForm.linkTitle = ''
|
||||||
|
this.linkForm.linkUrl = ''
|
||||||
|
this.miniAppForm.mpAppid = ''
|
||||||
|
this.miniAppForm.mpPage = ''
|
||||||
|
this.miniAppForm.mpTitle = ''
|
||||||
|
this.dateForm.choiceTime = ''
|
||||||
|
|
||||||
|
this.isShowDate = false
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFile(index) {
|
||||||
|
this.fileList.splice(index, 1)
|
||||||
|
},
|
||||||
|
|
||||||
|
mapIcon(type) {
|
||||||
|
return {
|
||||||
|
1: 'https://cdn.cunwuyun.cn/dvcp/announce/img.png',
|
||||||
|
2: 'https://cdn.cunwuyun.cn/dvcp/announce/video.png',
|
||||||
|
3: 'https://cdn.cunwuyun.cn/dvcp/announce/folder.png',
|
||||||
|
4: 'https://cdn.cunwuyun.cn/dvcp/announce/site.png',
|
||||||
|
5: 'https://cdn.cunwuyun.cn/dvcp/announce/miniapp.png'
|
||||||
|
}[type]
|
||||||
|
},
|
||||||
|
|
||||||
|
onBeforeUpload(event) {
|
||||||
|
return this.onOverSize(event)
|
||||||
|
},
|
||||||
|
|
||||||
|
getExtension(name) {
|
||||||
|
return name.substring(name.lastIndexOf('.'))
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChange(e, size, accept) {
|
||||||
|
const isLt10M = e.size / 1024 / 1024 < size
|
||||||
|
const suffixName = this.getExtension(e.name)
|
||||||
|
const suffixNameList = accept.split(',')
|
||||||
|
|
||||||
|
if (suffixNameList.indexOf(`${suffixName.toLowerCase()}`) === -1) {
|
||||||
|
this.$message.error(`不支持该格式`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isLt10M) {
|
||||||
|
this.$message.error(`大小不超过${10}MB!`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
|
||||||
|
onExceed() {
|
||||||
|
this.$message.error(`最多上传9个附件`)
|
||||||
|
},
|
||||||
|
|
||||||
|
submitUpload(file, type) {
|
||||||
|
const fileType = {
|
||||||
|
'1': 'image',
|
||||||
|
'2': 'video',
|
||||||
|
'3': 'file'
|
||||||
|
}[type]
|
||||||
|
let formData = new FormData()
|
||||||
|
formData.append('file', file.file)
|
||||||
|
formData.append('type', fileType)
|
||||||
|
let loading = this.$loading()
|
||||||
|
this.instance.post(`/app/wxcp/upload/uploadFile`, formData, {
|
||||||
|
withCredentials: false
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.fileList.push({
|
||||||
|
...res.data.file,
|
||||||
|
media: res.data.media,
|
||||||
|
msgType: type,
|
||||||
|
sysFileId: res.data.file.id,
|
||||||
|
imgPicUrl: res.data.file.url,
|
||||||
|
mediaId: res.data.media.mediaId
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$message.success('上传成功')
|
||||||
|
}
|
||||||
|
}).finally(() => loading.close())
|
||||||
|
},
|
||||||
|
|
||||||
|
onDateForm() {
|
||||||
|
this.$refs.dateForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
if (new Date(this.dateForm.choiceTime).getTime() < Date.now()) {
|
||||||
|
return this.$message.error('定时发送时间不得早于当前时间')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.params.sendChannel === '1' && new Date(this.dateForm.choiceTime).getTime() > new Date(this.form.taskEndTime).getTime()) {
|
||||||
|
return this.$message.error('定时发送时间不得晚于结束时间')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.confirm(1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
confirm(sendType) {
|
||||||
|
this.$refs.form.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
if (!this.form.wxGroups.length) {
|
||||||
|
return this.$message.error('居民群数量不能为0')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.params.sendChannel === '1' && new Date(this.form.taskEndTime).getTime() < Date.now()) {
|
||||||
|
return this.$message.error('结束时间不得早于当前时间')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sendType === 1 && !this.dateForm.choiceTime) {
|
||||||
|
this.isShowDate = true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const contents = [
|
||||||
|
{
|
||||||
|
content: this.form.content,
|
||||||
|
msgType: '0'
|
||||||
|
},
|
||||||
|
...this.fileList
|
||||||
|
]
|
||||||
|
|
||||||
|
if (sendType === 0) {
|
||||||
|
this.isLoading1 = true
|
||||||
|
} else {
|
||||||
|
this.isLoading2 = true
|
||||||
|
}
|
||||||
|
this.instance.post(`/app/appmasssendingtask/addOrUpdate`, {
|
||||||
|
...this.form,
|
||||||
|
id: this.params.id,
|
||||||
|
wxGroups: this.form.wxGroups,
|
||||||
|
contents,
|
||||||
|
sendType,
|
||||||
|
sendChannel: this.params.sendChannel,
|
||||||
|
choiceTime: this.dateForm.choiceTime,
|
||||||
|
filterCriteria: this.form.filterCriteria.join(','),
|
||||||
|
examines: this.form.examines.length ? this.form.examines.map(v => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
examineUserId: v.id,
|
||||||
|
examineUserName: v.name
|
||||||
|
}
|
||||||
|
}) : []
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('提交成功')
|
||||||
|
setTimeout(() => {
|
||||||
|
this.cancel(true)
|
||||||
|
}, 600)
|
||||||
|
} else {
|
||||||
|
this.isLoading1 = false
|
||||||
|
this.isLoading2 = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch(() => {
|
||||||
|
this.isLoading1 = false
|
||||||
|
this.isLoading2 = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel(isRefresh) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'list',
|
||||||
|
isRefresh: !!isRefresh
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.el-tooltip__popper.is-dark {
|
||||||
|
max-width: 240px;
|
||||||
|
}
|
||||||
|
.AppAnnounceDetail-content-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.content-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
line-height: 1;
|
||||||
|
margin-right: 4px;
|
||||||
|
text-align: center;
|
||||||
|
background: #F9F9F9;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #222;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppAnnounceAdd {
|
||||||
|
.ai-detail__content {
|
||||||
|
.ai-detail__content--wrapper {
|
||||||
|
position: relative;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-form {
|
||||||
|
textarea {
|
||||||
|
border-radius: 4px 4px 0 0!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 14px 16px;
|
||||||
|
background: #F9F9F9;
|
||||||
|
border-radius: 0px 0px 4px 4px;
|
||||||
|
border: 1px solid #D0D4DC;
|
||||||
|
border-top: none;
|
||||||
|
|
||||||
|
.add-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #222;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileList {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
.add-item {
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-style: normal;
|
||||||
|
color: red;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppAnnounceDetail-container {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0 20px;
|
||||||
|
overflow: auto;
|
||||||
|
overflow: overlay;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppAnnounceDetail-select {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 32px;
|
||||||
|
line-height: 1;
|
||||||
|
background: #F5F5F5;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #D0D4DC;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #26f;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > i {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 32px;
|
||||||
|
padding: 0 12px;
|
||||||
|
color: #888888;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
border-right: 1px solid #D0D4DC;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppAnnounceDetail-select__input {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-right {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0 12px;
|
||||||
|
color: #222222;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all ease 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-left {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex: 1;
|
||||||
|
padding: 5px 0 0px 12px;
|
||||||
|
border-right: 1px solid #D0D4DC;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
em {
|
||||||
|
height: 22px;
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 0 4px 5px 0;
|
||||||
|
color: #222222;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
height: 22px;
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 0 4px 5px 0;
|
||||||
|
padding: 0 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #222222;
|
||||||
|
background: #F3F4F7;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid #D0D4DC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #222222;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin: 0 3px;
|
||||||
|
color: #2266FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
color: #8899bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
line-height: 20px;
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #888888;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
777
project/qianxinan/AnnounceOld/AppAnnounce/components/Detail.vue
Normal file
777
project/qianxinan/AnnounceOld/AppAnnounce/components/Detail.vue
Normal file
@@ -0,0 +1,777 @@
|
|||||||
|
<template>
|
||||||
|
<ai-detail class="AppAnnounceDetail">
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title title="群发居民群详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||||
|
</ai-title>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-card title="基础信息">
|
||||||
|
<template #right>
|
||||||
|
<div class="right-tips" v-if="info.status === '4'">
|
||||||
|
<el-tooltip
|
||||||
|
placement="top"
|
||||||
|
content="任务开始后,3天内15分钟更新1次,3天后访问页面时触发更新,1小时最多刷新1次">
|
||||||
|
<i class="iconfont iconDetails"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
<span>数据更新于{{ info.dataUpdateTime }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<ai-wrapper>
|
||||||
|
<ai-info-item label="任务名称" isLine :value="info.taskTitle"></ai-info-item>
|
||||||
|
<ai-info-item label="任务状态" isLine>
|
||||||
|
<span :style="{ color: dict.getColor('mstStatus', info.status) }">{{ dict.getLabel('mstStatus', info.status) }}</span>
|
||||||
|
</ai-info-item>
|
||||||
|
<ai-info-item label="创建人" isLine>
|
||||||
|
<div class="user">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/user.png" />
|
||||||
|
<span>{{ info.createUserName }}</span>
|
||||||
|
(<span>{{ info.createUserDeptName }}</span>)
|
||||||
|
</div>
|
||||||
|
</ai-info-item>
|
||||||
|
<ai-info-item label="审批人" isLine v-if="info.enableExamine === '1'">
|
||||||
|
<div class="user-wrapper">
|
||||||
|
<div class="user" v-for="(item, index) in info.examines" :key="index">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/user.png" />
|
||||||
|
<span>{{ item.examineUserName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ai-info-item>
|
||||||
|
<ai-info-item label="发送方式" isLine>
|
||||||
|
<span>{{ info.sendChannel === '1' ? '通知员工转发' : '成员一键群发' }}</span>
|
||||||
|
</ai-info-item>
|
||||||
|
<ai-info-item label="创建时间" :value="info.createTime"></ai-info-item>
|
||||||
|
<ai-info-item label="群发时间" :value="info.choiceTime"></ai-info-item>
|
||||||
|
<ai-info-item label="结束时间" :value="info.taskEndTime" v-if="info.sendChannel === '1'"></ai-info-item>
|
||||||
|
<ai-info-item label="群发范围" isLine>
|
||||||
|
<div class="text">
|
||||||
|
<span>{{ info.sendScope === '0' ? '全部' : '按条件筛选的' }}</span>
|
||||||
|
<i>{{ groups.length }}</i>
|
||||||
|
<span>个居民群</span>
|
||||||
|
<em @click="isShowGroups = true">详情</em>
|
||||||
|
</div>
|
||||||
|
</ai-info-item>
|
||||||
|
<ai-info-item label="消息内容" isLine>
|
||||||
|
<div class="msg">
|
||||||
|
<p>{{ content }}</p>
|
||||||
|
<div class="msg-bottom">
|
||||||
|
<div class="left" v-if="fileList.length">
|
||||||
|
<img :src="mapIcon(fileList[0].msgType)" />
|
||||||
|
<span>{{ mapType(fileList[0].msgType) }}{{ fileList[0].mpTitle || fileList[0].name || fileList[0].linkTitle }} 等</span>
|
||||||
|
<i>{{ fileList.length }}</i>
|
||||||
|
<span>个附件</span>
|
||||||
|
</div>
|
||||||
|
<div class="left" v-else>
|
||||||
|
<span>暂无附件</span>
|
||||||
|
</div>
|
||||||
|
<div class="right" @click="isShowPhone = true">预览消息</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ai-info-item>
|
||||||
|
</ai-wrapper>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card>
|
||||||
|
<template #title>
|
||||||
|
<div class="AppAnnounceDetail-title">
|
||||||
|
<span :class="[currIndex === 0 ? 'active' : '']" @click="currIndex = 0">成员统计</span>
|
||||||
|
<span :class="[currIndex === 1 ? 'active' : '']" @click="currIndex = 1">居民群统计</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<div class="content-item" v-if="currIndex === 0">
|
||||||
|
<div class="top">
|
||||||
|
<div class="top-item">
|
||||||
|
<div class="top-item__title">
|
||||||
|
<h3>计划执行成员</h3>
|
||||||
|
</div>
|
||||||
|
<p>{{ memberInfo.planCount || 0 }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="top-item">
|
||||||
|
<div class="top-item__title">
|
||||||
|
<h3>未执行成员</h3>
|
||||||
|
</div>
|
||||||
|
<p>{{ memberInfo.unExecutedCount || 0 }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="top-item">
|
||||||
|
<div class="top-item__title">
|
||||||
|
<h3>已执行成员</h3>
|
||||||
|
</div>
|
||||||
|
<p>{{ memberInfo.executedCount || 0 }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="top-item" v-if="info.sendChannel === '0'">
|
||||||
|
<div class="top-item__title">
|
||||||
|
<h3>无法执行成员</h3>
|
||||||
|
<el-tooltip
|
||||||
|
placement="top"
|
||||||
|
content="由于员工不在可见范围、离职、客户群接收已达到上限等原因,无法执行群发任务的成员总数">
|
||||||
|
<i class="iconfont iconDetails"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
<p>{{ memberInfo.cannotExecuteCount || 0 }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bottom">
|
||||||
|
<div class="bottom-search">
|
||||||
|
<div class="left">
|
||||||
|
<el-radio-group v-model="search1.sendStatus" size="small" @change="search1.current = 1, getMemberInfo()">
|
||||||
|
<el-radio-button size="small" label="0">未执行</el-radio-button>
|
||||||
|
<el-radio-button size="small" label="1">已执行</el-radio-button>
|
||||||
|
<el-radio-button size="small" label="2" v-if="info.sendChannel === '0'">无法执行</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<ai-picker
|
||||||
|
dialogTitle="选择部门"
|
||||||
|
action="/app/wxcp/wxdepartment/departList"
|
||||||
|
:instance="instance"
|
||||||
|
@pick="e => onUserChange(e, 'search1')" :multiple="false" v-model="user1">
|
||||||
|
<div class="userSelcet">
|
||||||
|
<span style="color: #606266;" v-if="search1.deptartId">{{ name1 }}</span>
|
||||||
|
<span v-else>部门</span>
|
||||||
|
<i class="el-icon-arrow-up" v-if="!search1.deptartId"></i>
|
||||||
|
<i class="el-icon-circle-close" v-if="search1.deptartId" @click.stop="user1 = [], search1.deptartId = '', search1.current = 1, getMemberInfo()"></i>
|
||||||
|
</div>
|
||||||
|
</ai-picker>
|
||||||
|
</div>
|
||||||
|
<el-button :type="isDisabled ? '' : 'primary'" :disabled="isDisabled" @click="sendMsg(0)" v-if="info.status === '4'">{{ isDisabled ? min + '分钟后可再次提醒' : '提醒成员发送' }}</el-button>
|
||||||
|
</div>
|
||||||
|
<ai-table
|
||||||
|
:tableData="tableData1"
|
||||||
|
:col-configs="colConfigs1"
|
||||||
|
:total="total1"
|
||||||
|
border
|
||||||
|
tableSize="small"
|
||||||
|
:current.sync="search1.current"
|
||||||
|
:size.sync="search1.size"
|
||||||
|
@getList="getMemberInfo">
|
||||||
|
<el-table-column slot="user" label="成员" align="left">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<div class="userinfo">
|
||||||
|
<span>{{ row.groupOwnerName }}</span>
|
||||||
|
<span style="color: #999">{{ row.mainDepartmentName }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-item" v-if="currIndex === 1">
|
||||||
|
<div class="top">
|
||||||
|
<div class="top-item">
|
||||||
|
<div class="top-item__title">
|
||||||
|
<h3>计划送达居民群</h3>
|
||||||
|
</div>
|
||||||
|
<p>{{ groupInfo.planCount || 0 }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="top-item">
|
||||||
|
<div class="top-item__title">
|
||||||
|
<h3>未送达居民群</h3>
|
||||||
|
</div>
|
||||||
|
<p>{{ groupInfo.unExecutedCount || 0 }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="top-item">
|
||||||
|
<div class="top-item__title">
|
||||||
|
<h3>已送达居民群</h3>
|
||||||
|
</div>
|
||||||
|
<p>{{ groupInfo.executedCount || 0 }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="top-item" v-if="info.sendChannel === '0'">
|
||||||
|
<div class="top-item__title">
|
||||||
|
<h3>无法送达居民群</h3>
|
||||||
|
</div>
|
||||||
|
<p>{{ groupInfo.cannotExecuteCount || 0 }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bottom">
|
||||||
|
<div class="bottom-search">
|
||||||
|
<div class="left">
|
||||||
|
<el-radio-group v-model="search2.sendStatus" size="small" @change="search2.current = 1, getGroupInfo()">
|
||||||
|
<el-radio-button size="small" label="0">未送达</el-radio-button>
|
||||||
|
<el-radio-button size="small" label="1">已送达</el-radio-button>
|
||||||
|
<el-radio-button size="small" label="2" v-if="info.sendChannel === '0'">无法送达</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<ai-picker
|
||||||
|
dialogTitle="选择部门"
|
||||||
|
action="/app/wxcp/wxdepartment/departList"
|
||||||
|
:instance="instance"
|
||||||
|
@pick="e => onUserChange(e, 'search2')" :multiple="false" v-model="user2">
|
||||||
|
<div class="userSelcet">
|
||||||
|
<span style="color: #606266;" v-if="search2.deptartId">{{ name2 }}</span>
|
||||||
|
<span v-else>部门</span>
|
||||||
|
<i class="el-icon-arrow-up" v-if="!search2.deptartId"></i>
|
||||||
|
<i class="el-icon-circle-close" v-if="search2.deptartId" @click.stop="user1 = [], search2.deptartId = '', search2.current = 1, getGroupInfo()"></i>
|
||||||
|
</div>
|
||||||
|
</ai-picker>
|
||||||
|
</div>
|
||||||
|
<el-button :type="isDisabled ? '' : 'primary'" :disabled="isDisabled" @click="sendMsg(1)" v-if="info.status === '4'">{{ isDisabled ? min + '分钟后可再次提醒' : '提醒成员发送' }}</el-button>
|
||||||
|
</div>
|
||||||
|
<ai-table
|
||||||
|
:tableData="tableData2"
|
||||||
|
:col-configs="colConfigs2"
|
||||||
|
:total="total2"
|
||||||
|
border
|
||||||
|
tableSize="small"
|
||||||
|
:current.sync="search2.current"
|
||||||
|
:size.sync="search2.size"
|
||||||
|
@getList="getGroupInfo">
|
||||||
|
<el-table-column slot="user" label="群主" align="center">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<div class="userinfo">
|
||||||
|
<span>{{ row.groupOwnerName }}</span>
|
||||||
|
<span style="color: #999">{{ row.mainDepartmentName }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-dialog
|
||||||
|
:visible.sync="isShowGroups"
|
||||||
|
width="890px"
|
||||||
|
title="群发范围"
|
||||||
|
@onConfirm="isShowGroups = false">
|
||||||
|
<ai-table
|
||||||
|
:tableData="info.wxGroups"
|
||||||
|
:col-configs="colConfigs3"
|
||||||
|
border
|
||||||
|
tableSize="small"
|
||||||
|
:isShowPagination="false"
|
||||||
|
@getList="() => {}">
|
||||||
|
</ai-table>
|
||||||
|
</ai-dialog>
|
||||||
|
<div class="detail-phone" v-if="isShowPhone">
|
||||||
|
<div class="mask"></div>
|
||||||
|
<Phone :avatar="user.info.avatar" @close="isShowPhone = false" :isShowClose="true" :content="content" :fileList="fileList"></Phone>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
import Phone from './Phone'
|
||||||
|
export default {
|
||||||
|
name: 'Detail',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
params: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
Phone
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
total1: 0,
|
||||||
|
isShowGroups: false,
|
||||||
|
isShowPhone: false,
|
||||||
|
total2: 0,
|
||||||
|
user1: [],
|
||||||
|
user2: [],
|
||||||
|
name1: '',
|
||||||
|
name2: '',
|
||||||
|
radio1: '未执行',
|
||||||
|
search1: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
deptartId: '',
|
||||||
|
type: 0,
|
||||||
|
sendStatus: '0'
|
||||||
|
},
|
||||||
|
search2: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
deptartId: '',
|
||||||
|
type: 1,
|
||||||
|
sendStatus: '0'
|
||||||
|
},
|
||||||
|
memberInfo: {},
|
||||||
|
groupInfo: {},
|
||||||
|
tableData1: [],
|
||||||
|
fileList: [],
|
||||||
|
tableData2: [],
|
||||||
|
info: {},
|
||||||
|
content: '',
|
||||||
|
currIndex: 0,
|
||||||
|
colConfigs3: [
|
||||||
|
{ prop: 'groupOwnerName', label: '群主' },
|
||||||
|
{ prop: 'groupNames', label: '群名称' }
|
||||||
|
],
|
||||||
|
colConfigs1: [
|
||||||
|
{ slot: 'user', label: '成员' },
|
||||||
|
{ prop: 'groupCount', label: '预计送达居民群', align: 'center' }
|
||||||
|
],
|
||||||
|
colConfigs2: [
|
||||||
|
{ prop: 'groupName', label: '居民群' },
|
||||||
|
{ prop: 'memberCount', label: '群人数', align: 'center' },
|
||||||
|
{ slot: 'user', label: '群主', align: 'center' },
|
||||||
|
],
|
||||||
|
groups: [],
|
||||||
|
timer: null,
|
||||||
|
min: 60,
|
||||||
|
isDisabled: false,
|
||||||
|
rejecterId: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user'])
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.getInfo(this.params.id)
|
||||||
|
this.getMemberInfo()
|
||||||
|
this.getGroupInfo()
|
||||||
|
},
|
||||||
|
|
||||||
|
destroyed () {
|
||||||
|
clearInterval(this.timer)
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getMemberInfo () {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/detailStatistics`, null, {
|
||||||
|
params: {
|
||||||
|
...this.search1,
|
||||||
|
taskId: this.params.id
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.tableData1 = res.data.executedList.records
|
||||||
|
this.total1 = res.data.executedList.total
|
||||||
|
this.memberInfo = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onUserChange (e, search) {
|
||||||
|
if (e.length) {
|
||||||
|
search === 'search1' ? this.name1 = e[0].name : this.name2 = e[0].name
|
||||||
|
this[search].deptartId = e[0].id
|
||||||
|
} else {
|
||||||
|
this[search].deptartId = ''
|
||||||
|
search === 'search1' ? this.name1 = '' : this.name2 = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
this[search].current = 1
|
||||||
|
if (search === 'search1') {
|
||||||
|
this.getMemberInfo()
|
||||||
|
} else {
|
||||||
|
this.getGroupInfo()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sendMsg () {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/remindSend?id=${this.params.id}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success('提醒成功')
|
||||||
|
this.getInfo(this.params.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getGroupInfo () {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/detailStatistics`, null, {
|
||||||
|
params: {
|
||||||
|
...this.search2,
|
||||||
|
taskId: this.params.id
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.tableData2 = res.data.executedList.records.map(v => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
groupName: v.groupName || '未命名群聊'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.total2 = res.data.executedList.total
|
||||||
|
this.groupInfo = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
countdown () {
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
const nowTime = this.$moment(new Date())
|
||||||
|
const min = nowTime.diff(this.info.remindTime, 'minute')
|
||||||
|
this.min = (60 - min)
|
||||||
|
|
||||||
|
if (this.min <= 0) {
|
||||||
|
this.isDisabled = false
|
||||||
|
clearInterval(this.timer)
|
||||||
|
} else {
|
||||||
|
this.isDisabled = true
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
|
||||||
|
getInfo (id) {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/queryDetailById?id=${id}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.info = res.data
|
||||||
|
if (res.data.status === '4' && res.data.remindTime) {
|
||||||
|
this.countdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = res.data.contents.filter(v => v.msgType === '0')
|
||||||
|
|
||||||
|
if (content.length) {
|
||||||
|
this.content = content[0].content
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fileList = res.data.contents.filter(v => v.msgType !== '0').map(v => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
...v.sysFile
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.info.wxGroups = res.data.wxGroups.map(v => {
|
||||||
|
this.groups.push(...v.groupIds.split(','))
|
||||||
|
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
groupIds: v.groupIds.split(',')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res.data.examines && res.data.examines.length) {
|
||||||
|
const user = res.data.examines.filter(v => v.examineStatus === '2')
|
||||||
|
|
||||||
|
if (user.length) {
|
||||||
|
this.rejecterId = user[0].examineUserId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
mapType (type) {
|
||||||
|
return {
|
||||||
|
1: '图片',
|
||||||
|
2: '视频',
|
||||||
|
3: '文件',
|
||||||
|
4: '网站',
|
||||||
|
5: '小程序'
|
||||||
|
}[type]
|
||||||
|
},
|
||||||
|
|
||||||
|
mapIcon (type) {
|
||||||
|
return {
|
||||||
|
1: 'https://cdn.cunwuyun.cn/dvcp/announce/img.png',
|
||||||
|
2: 'https://cdn.cunwuyun.cn/dvcp/announce/video.png',
|
||||||
|
3: 'https://cdn.cunwuyun.cn/dvcp/announce/folder.png',
|
||||||
|
4: 'https://cdn.cunwuyun.cn/dvcp/announce/site.png',
|
||||||
|
5: 'https://cdn.cunwuyun.cn/dvcp/announce/miniapp.png'
|
||||||
|
}[type]
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel (isRefresh) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'list',
|
||||||
|
isRefresh: !!isRefresh
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.AppAnnounceDetail {
|
||||||
|
position: relative;
|
||||||
|
.user-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-phone {
|
||||||
|
position: fixed;
|
||||||
|
left: 0%;
|
||||||
|
top: 0%;
|
||||||
|
z-index: 11;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1;
|
||||||
|
background: rgba($color: #000000, $alpha: 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep( .phone-container ){
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
z-index: 11;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.userSelcet {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 215px;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
margin-left: 12px;
|
||||||
|
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: #26f;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.userinfo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
span:first-child {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.user {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 1;
|
||||||
|
margin-right: 8px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
color: #222222;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
i {
|
||||||
|
color: #2266FF;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #2266FF;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all ease 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg {
|
||||||
|
background: #F9F9F9;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid #D0D4DC;
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 1;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
line-height: 38px;
|
||||||
|
padding: 0px 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-bottom {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 38px;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-top: 1px solid #D0D4DC;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #222222;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
color: #2266FF;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
color: #2266FF;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep( .AppAnnounceDetail-title ){
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
height: 100%;
|
||||||
|
line-height: 56px;
|
||||||
|
margin-right: 32px;
|
||||||
|
color: #888888;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: all ease 0.3s;
|
||||||
|
border-bottom: 3px solid transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #222222;
|
||||||
|
border-bottom: 3px solid #2266FF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-item {
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.top-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 1;
|
||||||
|
height: 90px;
|
||||||
|
margin-right: 16px;
|
||||||
|
padding: 0 16px;
|
||||||
|
background: #F9F9F9;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-item__title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
margin-left: 4px;
|
||||||
|
color: #8899bb;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: #222222;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #2266FF;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-search {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep( .right-tips ){
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
i {
|
||||||
|
margin-right: 4px;
|
||||||
|
color: #8899bb;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #888888;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
435
project/qianxinan/AnnounceOld/AppAnnounce/components/List.vue
Normal file
435
project/qianxinan/AnnounceOld/AppAnnounce/components/List.vue
Normal file
@@ -0,0 +1,435 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="AppAnnounce">
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title title="群发居民群" isShowBottomBorder>
|
||||||
|
<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(0, '')">创建宣发</el-button>
|
||||||
|
<ai-select
|
||||||
|
v-model="search.status"
|
||||||
|
@change="search.current = 1, getList()"
|
||||||
|
placeholder="任务状态"
|
||||||
|
:selectList="dict.getDict('mstStatus')">
|
||||||
|
</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="user">
|
||||||
|
<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="user = [], 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="close(row.id)" v-if="['4'].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.sendChannel, row.id)" v-if="['1', '3'].includes(row.status)">编辑</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
<div class="dialog" v-if="isShow">
|
||||||
|
<div class="mask"></div>
|
||||||
|
<div class="dialog-wrapper">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/close1.png" @click="isShow = false" />
|
||||||
|
<h2>选择群发方式</h2>
|
||||||
|
<p>可根据不同的使用需求,选择相应的群发方式</p>
|
||||||
|
<div class="dialog-list">
|
||||||
|
<div class="item" :class="[currIndex === '0' ? 'active' : '']" @click="currIndex = '0'">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/icon1.png" />
|
||||||
|
<h3>成员一键群发</h3>
|
||||||
|
<p>成员收到通知后,可一键直接群发到居民群,任务开始后不支持关闭</p>
|
||||||
|
</div>
|
||||||
|
<div class="item" :class="[currIndex === '1' ? 'active' : '']" @click="currIndex = '1'">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/icon2.png" />
|
||||||
|
<h3>通知成员群发</h3>
|
||||||
|
<p>员工收到通知后,需通过群发助手发送至居民群,任务到期后自动关闭,未完成的成员无法再执行</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-button style="width: 106px;" size="small" type="primary" icon="iconfont" @click="isShow = false, toAdd(currIndex, '')">去创建</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'List',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
search: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
status: '',
|
||||||
|
createUserId: '',
|
||||||
|
taskTitle: '',
|
||||||
|
startTime: '',
|
||||||
|
endTime: ''
|
||||||
|
},
|
||||||
|
currIndex: '0',
|
||||||
|
name: '',
|
||||||
|
isShow: false,
|
||||||
|
user: [],
|
||||||
|
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: 'status',
|
||||||
|
align: 'center',
|
||||||
|
label: '状态',
|
||||||
|
render: (h, {row}) => {
|
||||||
|
return h('span', {
|
||||||
|
style: {
|
||||||
|
color: this.dict.getColor('mstStatus', row.status)
|
||||||
|
}
|
||||||
|
}, this.dict.getLabel('mstStatus', row.status))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ prop: 'completionRate', label: '任务完成率', align: 'center', format: v => v ? v === '0.0' ? '0%' : `${v}%` : '-' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.dict.load('mstStatus', 'mstSendType').then(() => {
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onUserChange (e) {
|
||||||
|
if (e.length) {
|
||||||
|
this.name = e[0].name
|
||||||
|
this.search.createUserId = e[0].openId
|
||||||
|
} else {
|
||||||
|
this.search.createUserId = ''
|
||||||
|
this.name = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
this.search.current = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
|
||||||
|
getList() {
|
||||||
|
this.loading = true
|
||||||
|
this.instance.post(`/app/appmasssendingtask/list`, null, {
|
||||||
|
params: {
|
||||||
|
...this.search,
|
||||||
|
}
|
||||||
|
}).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/appmasssendingtask/remindExamine?id=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('催办成功!')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
close (id) {
|
||||||
|
this.$confirm('确认关闭该群发任务?').then(() => {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/closeTask?id=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('关闭成功!')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel (id) {
|
||||||
|
this.$confirm('确认撤回该群发任务?').then(() => {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/cancel?id=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('撤回成功!')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
remove(id) {
|
||||||
|
this.$confirm('确定删除该数据?').then(() => {
|
||||||
|
this.instance.post(`/app/appmasssendingtask/delete?ids=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('删除成功!')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
toAdd(type, id) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'Add',
|
||||||
|
params: {
|
||||||
|
id,
|
||||||
|
sendChannel: type
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
toDetail (id) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'Detail',
|
||||||
|
params: {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
344
project/qianxinan/AnnounceOld/AppAnnounce/components/Phone.vue
Normal file
344
project/qianxinan/AnnounceOld/AppAnnounce/components/Phone.vue
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
<template>
|
||||||
|
<div class="phone-container">
|
||||||
|
<img class="close" @click="$emit('close')" v-if="isShowClose" src="https://cdn.cunwuyun.cn/dvcp/announce/close.png" />
|
||||||
|
<img class="phone" src="https://cdn.cunwuyun.cn/dvcp/announce/phone.png" />
|
||||||
|
<img class="phone-wrapper" src="https://cdn.cunwuyun.cn/dvcp/announce/phone-wrapper.png" />
|
||||||
|
<div class="right-content">
|
||||||
|
<div class="msg-list">
|
||||||
|
<div class="msg-item" v-if="content">
|
||||||
|
<div class="msg-item__left">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/avatar.png" />
|
||||||
|
</div>
|
||||||
|
<div class="msg-item__right">
|
||||||
|
<div class="msg-wrapper msg-text">
|
||||||
|
<p>{{ content }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="msg-item" v-for="item in fileList" :key="item.id">
|
||||||
|
<div class="msg-item__left">
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/avatar.png" />
|
||||||
|
</div>
|
||||||
|
<div class="msg-item__right" :class="[['1', '2'].indexOf(item.msgType) !== -1 ? 'left-border' : '']">
|
||||||
|
<div class="msg-wrapper msg-img" v-if="item.msgType === '1'">
|
||||||
|
<img :src="item.imgPicUrl" />
|
||||||
|
</div>
|
||||||
|
<div class="msg-wrapper msg-video" v-if="item.msgType === '2'">
|
||||||
|
<video controls :src="item.url"></video>
|
||||||
|
</div>
|
||||||
|
<div class="msg-wrapper msg-file" v-if="item.msgType === '3'">
|
||||||
|
<div class="msg-left">
|
||||||
|
<h2>{{ item.name }}</h2>
|
||||||
|
<p>{{ item.fileSizeStr }}</p>
|
||||||
|
</div>
|
||||||
|
<img :src="mapIcon(item.name)" />
|
||||||
|
</div>
|
||||||
|
<div class="msg-wrapper msg-link" v-if="item.msgType === '4'">
|
||||||
|
<h2>{{ item.linkTitle }}</h2>
|
||||||
|
<div class="msg-right">
|
||||||
|
<p>{{ item.linkDesc }}</p>
|
||||||
|
<img :src="item.linkPicUrl || 'https://cdn.cunwuyun.cn/dvcp/announce/html.png'" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="msg-wrapper msg-miniapp" v-if="item.msgType === '5'">
|
||||||
|
<h2>{{ item.mpTitle }}</h2>
|
||||||
|
<img :src="item.url" />
|
||||||
|
<div class="msg-bottom">
|
||||||
|
<i>小程序</i>
|
||||||
|
<img src="https://cdn.cunwuyun.cn/dvcp/announce/miniapp.png">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['fileList', 'avatar', 'content', 'isShowClose'],
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
fileList (v) {
|
||||||
|
if (v.length) {
|
||||||
|
setTimeout(() => {
|
||||||
|
document.querySelector('.right-content').scrollTo(0, 999999)
|
||||||
|
}, 800)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
mapIcon (fileName) {
|
||||||
|
if (['.zip', '.rar'].indexOf(this.getExtension(fileName)) !== -1) {
|
||||||
|
return 'https://cdn.cunwuyun.cn/dvcp/announce/zip.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['.doc', '.docx'].indexOf(this.getExtension(fileName)) !== -1) {
|
||||||
|
return 'https://cdn.cunwuyun.cn/dvcp/announce/world.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['.xls', '.xlsx'].indexOf(this.getExtension(fileName)) !== -1) {
|
||||||
|
return 'https://cdn.cunwuyun.cn/dvcp/announce/xls.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['.txt'].indexOf(this.getExtension(fileName)) !== -1) {
|
||||||
|
return 'https://cdn.cunwuyun.cn/dvcp/announce/txt.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['.pdf'].indexOf(this.getExtension(fileName)) !== -1) {
|
||||||
|
return 'https://cdn.cunwuyun.cn/dvcp/announce/pdf.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['.ppt', '.pptx'].indexOf(this.getExtension(fileName)) !== -1) {
|
||||||
|
return 'https://cdn.cunwuyun.cn/dvcp/announce/ppt.png'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getExtension(name) {
|
||||||
|
return name.substring(name.lastIndexOf('.'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.phone-container {
|
||||||
|
width: 338px;
|
||||||
|
height: 675px;
|
||||||
|
padding: 80px 15px 100px 32px;
|
||||||
|
|
||||||
|
.phone {
|
||||||
|
position: absolute;
|
||||||
|
left: 13px;
|
||||||
|
top: 4px;
|
||||||
|
z-index: 1;
|
||||||
|
width: 314px;
|
||||||
|
height: 647px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 111;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all ease 0.5s;
|
||||||
|
transform: translate(100%, -50%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.phone-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 2;
|
||||||
|
width: 338px;
|
||||||
|
height: 675px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-content {
|
||||||
|
position: relative;
|
||||||
|
z-index: 11;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.msg-item {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.msg-item__left {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
margin-right: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
flex-shrink: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-item__right {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 16px;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-right: 6px solid #fff;
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-bottom: 6px solid transparent;
|
||||||
|
border-top: 6px solid transparent;
|
||||||
|
content: " ";
|
||||||
|
transform: translate(-100%, 0%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.left-border::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-img img {
|
||||||
|
max-width: 206px;
|
||||||
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-video video {
|
||||||
|
max-width: 206px;
|
||||||
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-text {
|
||||||
|
max-width: 206px;
|
||||||
|
width: max-content;
|
||||||
|
line-height: 1.3;
|
||||||
|
padding: 12px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 5px;
|
||||||
|
word-break: break-all;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #222222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-miniapp {
|
||||||
|
width: 206px;
|
||||||
|
padding: 0 12px;
|
||||||
|
text-align: justify;
|
||||||
|
font-size: 0;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #222222;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
line-height: 1.2;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
color: #222222;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > img {
|
||||||
|
width: 100%;
|
||||||
|
height: 120px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-bottom {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 4px 0;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
|
||||||
|
i {
|
||||||
|
margin-right: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-file {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 206px;
|
||||||
|
padding: 12px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.msg-left {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 18px;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
display: -webkit-box;
|
||||||
|
flex: 1;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 1;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #222222;
|
||||||
|
font-size: 14px;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #888888;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-link {
|
||||||
|
width: 206px;
|
||||||
|
padding: 12px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: #222222;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: -webkit-box;
|
||||||
|
flex: 1;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-right: 10px;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #888;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,752 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="AppAnnounceStatistics">
|
||||||
|
<template slot="content">
|
||||||
|
<div class="statistics-content">
|
||||||
|
<ai-title title="宣发日历"></ai-title>
|
||||||
|
<div class="flex-content">
|
||||||
|
<div class="flex-left">
|
||||||
|
<div class="date-header">
|
||||||
|
<p>{{chooseYear}}年{{chooseMonth}}月</p>
|
||||||
|
<div>
|
||||||
|
<el-date-picker size="small"
|
||||||
|
v-model="searchMonth"
|
||||||
|
type="month" value-format="yyyy-MM"
|
||||||
|
placeholder="选择日期" @change="searchMonthChange">
|
||||||
|
</el-date-picker>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-calendar v-model="calendarDate">
|
||||||
|
<template
|
||||||
|
slot="dateCell"
|
||||||
|
slot-scope="{date, data}">
|
||||||
|
<div class="flex-date">
|
||||||
|
<span>{{Number(data.day.substring(8, 10))}}</span>
|
||||||
|
<span class="tips" v-if="data.day.substring(5, 7) == chooseMonth && dateList[Number(data.day.substring(8, 10))] && dateList[Number(data.day.substring(8, 10))].taskList.length">{{dateList[Number(data.day.substring(8, 10))].taskList.length}}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-calendar>
|
||||||
|
</div>
|
||||||
|
<div class="flex-right">
|
||||||
|
<div class="title">{{chooseMonth}}月{{chooseDay}}日宣发内容</div>
|
||||||
|
<div class="list-content" v-if="taskList.length">
|
||||||
|
<el-timeline >
|
||||||
|
<el-timeline-item v-for="(item, index) in taskList" :key="index">
|
||||||
|
<el-card>
|
||||||
|
<div class="flex-between">
|
||||||
|
<p class="item-title">{{item.taskTitle}}</p>
|
||||||
|
<span class="item-time" v-if="item.choiceTime">{{item.choiceTime.substring(10, 16)}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="item-info item-created">
|
||||||
|
<span class="label">创建人:</span>{{item.createUserName}}
|
||||||
|
</div>
|
||||||
|
<div class="item-info item-dept">
|
||||||
|
<span class="label">创建部门:</span>{{item.createUserDeptName}}
|
||||||
|
</div>
|
||||||
|
<div class="flex-between">
|
||||||
|
<!-- <div class="item-info">群发类型:<span>{{$dict.getLabel('mstSendType', item.sendType) || ''}}</span></div> -->
|
||||||
|
<div class="item-info"><span class="label">群发类型:</span><span>群发居民群</span></div>
|
||||||
|
<span class="item-btn" @click="$router.push({name: '357e228ba8e64008ace90d095a7a0dd7', params: { id: item.id }})">详情</span>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-timeline-item>
|
||||||
|
</el-timeline>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<ai-empty v-if="!taskList.length" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="statistics-content">
|
||||||
|
<div class="flex-between mar-b16">
|
||||||
|
<ai-title title="宣发效果"></ai-title>
|
||||||
|
<div class="right-search">
|
||||||
|
<div class="time-select" :class="effectType == index ? 'active' : ''" v-for="(item, index) in dateTypeList" :key="index" @click="changeEffectType(index)">{{item}}</div>
|
||||||
|
<ai-picker :instance="instance" @pick="e => onUserChange(e)" :multiple="false" dialogTitle="选择部门" action="/app/wxcp/wxdepartment/departList">
|
||||||
|
<div class="time-select">
|
||||||
|
<span class="dept-name" style="color:#999;" v-if="deptList && !deptList.length">宣发部门</span>
|
||||||
|
<span class="dept-name" v-else>{{deptList[0].name}}</span>
|
||||||
|
<i class="el-icon-arrow-down"></i>
|
||||||
|
</div>
|
||||||
|
</ai-picker>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="line-content">
|
||||||
|
<div class="flex1">
|
||||||
|
<div class="header">
|
||||||
|
<p>累计创建宣发任务数</p>
|
||||||
|
<h2>{{effectData.createCount}}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="chart-content">
|
||||||
|
<div class="chart-title">宣发任务数</div>
|
||||||
|
<div class="chart-box" id="createChart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex1">
|
||||||
|
<div class="header">
|
||||||
|
<p>累计执行宣发次数</p>
|
||||||
|
<h2>{{effectData.executeCount}}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="chart-content">
|
||||||
|
<div class="chart-title">宣发次数</div>
|
||||||
|
<div class="chart-box" id="executeChart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex1 mar-r0">
|
||||||
|
<div class="header">
|
||||||
|
<p>累计触达人次</p>
|
||||||
|
<h2>{{effectData.receiveCount}}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="chart-content">
|
||||||
|
<div class="chart-title">触达人次</div>
|
||||||
|
<div class="chart-box" id="receiveChart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="statistics-content">
|
||||||
|
<div class="flex-between mar-b16">
|
||||||
|
<ai-title title="宣发明细"></ai-title>
|
||||||
|
<div class="right-search">
|
||||||
|
<div class="time-select" :class="departType == index ? 'active' : ''" v-for="(item, index) in dateTypeList" :key="index" @click="changeDepartType(index)">{{item}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="departBarChart" v-if="isDepartData"></div>
|
||||||
|
<ai-empty v-if="!isDepartData"></ai-empty>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ai-dialog :visible.sync="dialogDate" title="选择时间" width="500px" customFooter>
|
||||||
|
<el-date-picker v-model="timeList" size="small" type="daterange" value-format="yyyy-MM-dd"
|
||||||
|
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
|
||||||
|
</el-date-picker>
|
||||||
|
<el-button slot="footer" @click="selectDete" type="primary">确认</el-button>
|
||||||
|
</ai-dialog>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
import { mapActions, mapState } from 'vuex';
|
||||||
|
export default {
|
||||||
|
name: 'AppAnnounceStatistics',
|
||||||
|
label: '协同宣发统计',
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
calendarDate: new Date(),
|
||||||
|
dateList: {},
|
||||||
|
chooseYear: '',
|
||||||
|
chooseMonth: '',
|
||||||
|
chooseDay: '',
|
||||||
|
searchMonth: '',
|
||||||
|
taskList: [],
|
||||||
|
effectType: 0, // 宣发效果类型 0:近七天、1:近30天、2:近一年、3:自定义
|
||||||
|
effectData: {},
|
||||||
|
createChart: null,
|
||||||
|
executeChart: null,
|
||||||
|
receiveChart: null,
|
||||||
|
departType: 0, // 宣发明细类型 0:近七天、1:近30天、2:近一年、3:自定义
|
||||||
|
dateTypeList: ['近7天', '近30天', '近1年', '自定义'],
|
||||||
|
departData: {},
|
||||||
|
departBarChart: null,
|
||||||
|
dialogDate: false,
|
||||||
|
timeListEffect: '',
|
||||||
|
timeListDepart: '',
|
||||||
|
timeList: '',
|
||||||
|
isEffectTimeSelect: false,
|
||||||
|
deptList: [],
|
||||||
|
selectDeptName: '',
|
||||||
|
isDepartData: true,
|
||||||
|
departBarData: [],
|
||||||
|
type: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(['user']),
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
calendarDate: function() {
|
||||||
|
var year = '' , month = '', date = ''
|
||||||
|
if(this.calendarDate.length == 9) { // 月份选择器触发
|
||||||
|
year = this.calendarDate.substring(0, 4)
|
||||||
|
month = this.calendarDate.substring(5, 7)
|
||||||
|
date = this.calendarDate.substring(8, 10)
|
||||||
|
}else { // 日历点击
|
||||||
|
year = this.calendarDate.getFullYear();
|
||||||
|
month = this.calendarDate.getMonth() + 1;
|
||||||
|
date = this.calendarDate.getDate()
|
||||||
|
if (month >= 1 && month <= 9) {
|
||||||
|
month = "0" + month;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.chooseMonth != month) { // 日历点击不同月
|
||||||
|
this.searchMonth = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chooseDay = date
|
||||||
|
|
||||||
|
if(this.chooseMonth != month || this.chooseYear != year) { // 不同年/不同月重新请求日历列表
|
||||||
|
this.getCalendarList(year, month)
|
||||||
|
} else {
|
||||||
|
this.getTaskList(date)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chooseMonth = month
|
||||||
|
this.chooseYear = year
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
var year = this.calendarDate.getFullYear();
|
||||||
|
var month = this.calendarDate.getMonth() + 1;
|
||||||
|
var date = this.calendarDate.getDate()
|
||||||
|
if (month >= 1 && month <= 9) {
|
||||||
|
month = "0" + month;
|
||||||
|
}
|
||||||
|
this.chooseMonth = month
|
||||||
|
this.chooseYear = year
|
||||||
|
this.chooseDay = date
|
||||||
|
this.getCalendarList(year, month)
|
||||||
|
this.getEffect()
|
||||||
|
this.getDepart()
|
||||||
|
this.dict.load('mstSendType')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(['initOpenData', 'transCanvas']),
|
||||||
|
onUserChange (e) {
|
||||||
|
this.deptList = e
|
||||||
|
this.getEffect()
|
||||||
|
},
|
||||||
|
selectDete() {
|
||||||
|
if(!this.timeList || !this.timeList.length) {
|
||||||
|
return this.$message.error('请选择自定义时间');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.isEffectTimeSelect) { //宣发效果
|
||||||
|
this.timeListEffect = this.timeList
|
||||||
|
this.effectType = 3
|
||||||
|
this.getEffect()
|
||||||
|
} else { //宣发明细
|
||||||
|
this.timeListDepart = this.timeList
|
||||||
|
this.departType = 3
|
||||||
|
this.getDepart()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dialogDate = false
|
||||||
|
},
|
||||||
|
searchMonthChange() {
|
||||||
|
this.calendarDate = this.searchMonth + '-1'
|
||||||
|
},
|
||||||
|
getCalendarList(year, month){
|
||||||
|
this.instance.post(`/app/appmasssendingtask/statisticsCalendar?yyyyMM=${year}${month}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.dateList = res.data
|
||||||
|
this.getTaskList(this.chooseDay)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getTaskList(day) {
|
||||||
|
this.taskList = this.dateList[day].taskList
|
||||||
|
},
|
||||||
|
changeEffectType(type) {
|
||||||
|
if(this.effectType != 3) {
|
||||||
|
this.timeList = []
|
||||||
|
}else {
|
||||||
|
this.timeList = this.timeListEffect
|
||||||
|
}
|
||||||
|
if(type == 3) {
|
||||||
|
this.isEffectTimeSelect = true
|
||||||
|
this.dialogDate = true
|
||||||
|
}else {
|
||||||
|
this.effectType = type
|
||||||
|
this.getEffect()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getEffect() {
|
||||||
|
var startTime = this.timeListEffect[0] || '' , endTime = this.timeListEffect[1] || '', departId = ''
|
||||||
|
if(this.deptList && this.deptList.length) {
|
||||||
|
departId = this.deptList[0].id
|
||||||
|
}
|
||||||
|
this.instance.post(`/app/appmasssendingtask/statisticsEffect?type=${this.effectType}&startTime=${startTime}&endTime=${endTime}&departId=${departId}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.effectData = res.data
|
||||||
|
var xData = [], createData = [], executeData = [], receiveData = []
|
||||||
|
res.data.trend.map(e => {
|
||||||
|
if(this.effectType == 0 || this.effectType == 1) {
|
||||||
|
e.ymd = e.ymd.substring(5, 10)
|
||||||
|
}
|
||||||
|
xData.push(e.ymd)
|
||||||
|
createData.push(e.createCount)
|
||||||
|
executeData.push(e.executeCount)
|
||||||
|
receiveData.push(e.receiveCount)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.setLineChart(xData, createData, 'createChart', ['#2891FF'])
|
||||||
|
this.setLineChart(xData, executeData, 'executeChart', ['#FFB865'])
|
||||||
|
this.setLineChart(xData, receiveData, 'receiveChart', ['#26D52B'])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setLineChart(xData, yData, id, colorList) {
|
||||||
|
this[id] = echarts.init(document.querySelector(`#${id}`))
|
||||||
|
var option = {
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: xData
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '10px',
|
||||||
|
right: '28px',
|
||||||
|
bottom: '14px',
|
||||||
|
top: '30px',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
type: "plain"
|
||||||
|
},
|
||||||
|
color: colorList,
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data: yData,
|
||||||
|
type: 'line'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
this[id].setOption(option)
|
||||||
|
},
|
||||||
|
changeDepartType(type) {
|
||||||
|
if(this.departType != 3) {
|
||||||
|
this.timeList = []
|
||||||
|
}else {
|
||||||
|
this.timeList = this.timeListDepart
|
||||||
|
}
|
||||||
|
if(type == 3) {
|
||||||
|
this.isEffectTimeSelect = false
|
||||||
|
this.dialogDate = true
|
||||||
|
}else {
|
||||||
|
this.departType = type
|
||||||
|
this.getDepart()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getDepart() {
|
||||||
|
var startTime = this.timeListDepart[0] || '' , endTime = this.timeListDepart[1] || ''
|
||||||
|
this.instance.post(`/app/appmasssendingtask/statisticsDepart?type=${this.departType}&startTime=${startTime}&endTime=${endTime}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
if(res.data && res.data.length) {
|
||||||
|
this.isDepartData = true
|
||||||
|
var xData = [], yData = []
|
||||||
|
res.data.map((item) => {
|
||||||
|
this.departBarData.push(item)
|
||||||
|
xData.push(item.deptName)
|
||||||
|
yData.push(item.taskCount)
|
||||||
|
})
|
||||||
|
this.setBarChart(xData, yData)
|
||||||
|
}else {
|
||||||
|
this.isDepartData = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setBarChart(xData, yData) {
|
||||||
|
this.departBarChart = echarts.init(document.querySelector(`#departBarChart`))
|
||||||
|
var option = {
|
||||||
|
color: ['#2891FF'],
|
||||||
|
grid: {
|
||||||
|
top: '10%',
|
||||||
|
left: '2%',
|
||||||
|
right: '2%',
|
||||||
|
bottom: 90,
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
// toolbox: {
|
||||||
|
// feature: {
|
||||||
|
// dataZoom: {
|
||||||
|
// yAxisIndex: false
|
||||||
|
// },
|
||||||
|
// saveAsImage: {
|
||||||
|
// pixelRatio: 2
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
},
|
||||||
|
formatter: (data) => {
|
||||||
|
var index = data[0].dataIndex
|
||||||
|
return `<ww-open-data type="departmentName" openid="${this.departBarData[index].deptId}"></ww-open-data><br/>宣发任务数:${data[0].value}`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataZoom: [
|
||||||
|
{
|
||||||
|
type: 'inside'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'slider'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
xAxis: {
|
||||||
|
data: xData,
|
||||||
|
silent: false,
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
splitArea: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
splitArea: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
data: yData,
|
||||||
|
barWidth: 20,
|
||||||
|
barGap: '250%',
|
||||||
|
large: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// {
|
||||||
|
// tooltip: {
|
||||||
|
// trigger: 'axis',
|
||||||
|
// axisPointer: {
|
||||||
|
// type: 'shadow'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// grid: {
|
||||||
|
// top: '10%',
|
||||||
|
// left: '2%',
|
||||||
|
// right: '2%',
|
||||||
|
// bottom: '2%',
|
||||||
|
// containLabel: true
|
||||||
|
// },
|
||||||
|
// color: ['#2891FF'],
|
||||||
|
// xAxis: {
|
||||||
|
// type: 'category',
|
||||||
|
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||||
|
// },
|
||||||
|
// yAxis: {
|
||||||
|
// type: 'value'
|
||||||
|
// },
|
||||||
|
// series: [
|
||||||
|
// {
|
||||||
|
// data: [120, 200, 150, 80, 70, 110, 130],
|
||||||
|
// type: 'bar',
|
||||||
|
// barWidth: 20,
|
||||||
|
// barGap: '250%',
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// };
|
||||||
|
this.departBarChart.setOption(option)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppAnnounceStatistics {
|
||||||
|
height: 100%;
|
||||||
|
.flex-between{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.mar-b16{
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.mar-r0{
|
||||||
|
margin-right: 0!important;
|
||||||
|
}
|
||||||
|
.statistics-content{
|
||||||
|
padding: 0 24px 24px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0px 4px 6px -2px rgba(15,15,21,0.1500);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
.flex-content{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
margin-top: 16px;
|
||||||
|
.flex-left{
|
||||||
|
width: 50%;
|
||||||
|
.date-header{
|
||||||
|
padding: 12px 16px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
p{
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.flex-date{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.tips{
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 4px;
|
||||||
|
height: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #2891FF;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: ArialMT;
|
||||||
|
color: #FFF;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.flex-right{
|
||||||
|
width: 50%;
|
||||||
|
margin-left: 16px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
.title{
|
||||||
|
line-height: 56px;
|
||||||
|
border-bottom: 1px solid #EEE;
|
||||||
|
padding-left: 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: MicrosoftYaHeiSemibold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.list-content{
|
||||||
|
padding: 16px;
|
||||||
|
height: 339px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow-y: scroll;
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.item-title{
|
||||||
|
width: calc(100% - 100px);
|
||||||
|
word-break: break-all;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: MicrosoftYaHeiSemibold;
|
||||||
|
color: #222;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
.item-time{
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: ArialMT;
|
||||||
|
color: #888;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
.item-info{
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: MicrosoftYaHei;
|
||||||
|
color: #222;
|
||||||
|
line-height: 22px;
|
||||||
|
span{
|
||||||
|
display: inline-block;
|
||||||
|
color: #222;
|
||||||
|
word-break: break-all;
|
||||||
|
// vertical-align: text-top;
|
||||||
|
}
|
||||||
|
.label{
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-created{
|
||||||
|
width: 152px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
.label{
|
||||||
|
width: 56px;
|
||||||
|
}
|
||||||
|
.name{
|
||||||
|
width: calc(100% - 56px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-dept{
|
||||||
|
width: calc(100% - 152px);
|
||||||
|
.label{
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
.name{
|
||||||
|
width: calc(100% - 70px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-btn{
|
||||||
|
color: #26f;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-search{
|
||||||
|
margin-top: 10px;
|
||||||
|
div{
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.time-select{
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: MicrosoftYaHei;
|
||||||
|
color: #222;
|
||||||
|
line-height: 22px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid #D0D4DC;
|
||||||
|
margin-right: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
.dept-name{
|
||||||
|
display: inline-block;
|
||||||
|
width: 200px;
|
||||||
|
height: 22px;
|
||||||
|
overflow:hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
.el-icon-arrow-down{
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.active{
|
||||||
|
border: 1px solid #26f;
|
||||||
|
color: #26f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.line-content{
|
||||||
|
display: flex;
|
||||||
|
.flex1{
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 16px;
|
||||||
|
.header{
|
||||||
|
padding: 16px;
|
||||||
|
width: 100%;
|
||||||
|
height: 90px;
|
||||||
|
background: #F9F9F9;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
p{
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: MicrosoftYaHeiSemibold;
|
||||||
|
color: #222;
|
||||||
|
line-height: 22px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
h2{
|
||||||
|
font-size: 24px;
|
||||||
|
font-family: DINAlternate-Bold, DINAlternate;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #26F;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.chart-content{
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px;
|
||||||
|
background: #F9F9F9;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.chart-title{
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: MicrosoftYaHeiSemibold;
|
||||||
|
color: #333;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
.chart-box{
|
||||||
|
width: 100%;
|
||||||
|
height: 280px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#departBarChart{
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
:deep( .el-calendar-table:not(.is-range) td.next),
|
||||||
|
:deep( .el-calendar-table:not(.is-range) td.prev ){
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
:deep( .el-calendar-table .el-calendar-day){
|
||||||
|
height: 48px;
|
||||||
|
line-height: 32px;
|
||||||
|
padding-left: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: ArialMT;
|
||||||
|
}
|
||||||
|
.el-calendar-table:not(.is-range) td .current{
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
:deep( .el-calendar__header){
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
:deep( .el-calendar__body){
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
:deep( .el-calendar-table thead th:nth-of-type(1)){
|
||||||
|
border-left: 1px solid #eee;
|
||||||
|
}
|
||||||
|
:deep( .el-calendar-table thead th:nth-of-type(7)){
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
}
|
||||||
|
:deep( .el-calendar-table tr td:first-child ){
|
||||||
|
border-left: 1px solid #eee;
|
||||||
|
}
|
||||||
|
:deep( .el-calendar-table tr:first-child td ){
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
}
|
||||||
|
:deep( .el-calendar-table td ){
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
}
|
||||||
|
:deep( .el-timeline-item__timestamp.is-top){
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
:deep( .el-timeline-item__node){
|
||||||
|
background-color: #26F;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
:deep( .el-card){
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
:deep( .el-card__body){
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep( .ai-list__content ){
|
||||||
|
padding: 0!important;
|
||||||
|
|
||||||
|
.ai-list__content--right-wrapper {
|
||||||
|
background: transparent!important;
|
||||||
|
box-shadow: none!important;
|
||||||
|
margin: 0!important;
|
||||||
|
padding: 0 0 0!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep( .AiPicker){
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user