This commit is contained in:
liuye
2022-09-15 11:37:58 +08:00
11 changed files with 480 additions and 126 deletions

View File

@@ -24,6 +24,9 @@
</div>
</div>
<AiEmpty description="暂无数据" v-if="!list.length"/>
<AiConsole></AiConsole>
<u-popup v-model="filterShow" mode="bottom" border-radius="14">
<div class="popup">
<div class="tips"></div>

View File

@@ -247,6 +247,7 @@ export default {
sendStatus: this.tabIndex==0? this.subIndex0: this.subIndex1,
taskId: this.id,
current: this.current,
size: 3000
},
})
.then((res) => {

View File

@@ -78,6 +78,7 @@
</div>
</div>
</div>
<div class="btn" v-if="data.status==0 && data.haveExaminPower">
<div class="refuse" @click="refuseBtn">审核拒绝</div>
<div class="pass" @click="passBtn">审核通过</div>
@@ -88,6 +89,7 @@
<script>
import { mapState ,mapActions } from "vuex";
export default {
name : "detail",
data() {
return {
id: "",
@@ -110,6 +112,9 @@ export default {
...mapState(['user'])
},
methods: {
toMassDispatch() {
uni.navigateTo({ url: `./massDispatch?id=${this.id}`})
},
getDetail() {
this.$http.post(`/app/appmasssendingtask/queryDetailById?id=${this.id}`).then(res=> {
if (res?.data) {

View File

@@ -0,0 +1,368 @@
<template>
<div class="massDispatch">
<div class="tips">
<u-icon name="error-circle-fill" size="30" color="#ff9900"></u-icon>请于12月13日24点前完成群发任务</div>
<div class="task">
<div class="task_title">群发客户群</div>
<div class="task_content">
<div class="item">
<span>任务名称</span>
<span>{{ data.taskTitle }}</span>
</div>
<div class="item">
<span>创建人</span>
<span>{{ data.createUserName }}</span>
</div>
<!-- <div class="item" v-if="data.enableExamine == 1">
<span>审批人</span>
<span>
<span v-for="(item, index) in approver" :key="index" style="color: #333;">
{{ item.examineUserName }}
<span v-show="index < approver.length - 1"></span>
</span>
</span>
</div>
<div class="item">
<span>所在部门</span>
<span style="display: flex;">
<div v-if="data.createUserDeptName">{{ data.createUserDeptName }}</div>
</span>
</div>
<div class="item">
<span>群发时间</span>
<span>{{ data.choiceTime }}</span>
</div> -->
</div>
<div class="task_results" v-if="data.enableExamine == 1">
<img v-if="data.status == 1" src="./images/refuse.png" alt="">
<img v-if="data.status == 2" src="./images/pass.png" alt="">
</div>
</div>
<div class="info">
<div class="scope">
<span>群发范围</span>
<span>我的全部居民群</span>
<!-- <span v-if="data.sendScope==0">全部{{ data.receiveGroupCount || 0}}个居民群</span> -->
<!-- <span v-if="data.sendScope==1 || data.sendScope==2">按条件筛选的{{ data.receiveGroupCount || 0}}个居民群</span> -->
</div>
<div class="content">
<p>群发内容</p>
<div>
<!-- 文本 -->
<div class="textarea" v-show="content.length">{{ content }}</div>
<!-- 图片 -->
<div class="pictures" v-show="picList.length">
<image v-for="(item, index) in picList" :key="index" :src="item.imgPicUrl" @click.stop="previewImages(picList, item.imgPicUrl)"/>
</div>
<!-- 视频 -->
<div class="video" v-show="videoList.length">
<video v-for="(item, index) in videoList" :key="index" :src="item.imgPicUrl"/>
</div>
<!-- 文件 -->
<div class="file" v-show="fileList.length">
<div class="file_item" v-for="(item,index) in fileList" :key="index" @click="prevFile(item.sysFile)">
<img src="./images/files.png" alt="">
<div>{{ item.sysFile.name }}</div>
</div>
</div>
<!-- 网页 -->
<div class="webpage" v-show="webpage.length">
<p>链接地址</p>
<a v-for="(item, index) in webpage" :key="index" :href="item.linkUrl">
<div v-if="item.linkTitle">{{item.linkTitle}}</div>
<div v-else>{{ item.linkUrl }}</div>
</a>
</div>
<!-- 小程序 -->
<div class="miniapp" v-show="miniapp.length">
<p>小程序</p>
<div v-for="(item, index) in miniapp" :key="index">{{item.mpTitle}}</div>
</div>
</div>
</div>
</div>
<div class="subBtn" @click="toSend">
<div>前往群发</div>
</div>
</div>
</template>
<script>
import { mapState ,mapActions } from "vuex";
export default {
name: "massDispatch",
data() {
return {
id: "",
data: {},
content: '',
picList: [],
videoList: [],
fileList: [],
webpage: [],
miniapp: [],
pictres: [],
options: '',
approver: [], //审批人
}
},
onLoad(o) {
console.log(o)
this.id = o.id
},
computed: {
...mapState(['user'])
},
methods: {
...mapActions(['shareToExternalChat']),
getDetail() {
this.$http.post(`/app/appmasssendingtask/queryDetailById?id=${this.id}`).then(res=> {
if (res?.data) {
this.data = res.data
this.content = res.data.contents.filter(v=> v.msgType == 0)?.[0].content
this.picList = res.data.contents.filter(v=> v.msgType == 1)
this.videoList = res.data.contents.filter(v=> v.msgType == 2)
this.fileList = res.data.contents.filter(v=> v.msgType == 3)
this.webpage = res.data.contents.filter(v=> v.msgType == 4)
this.miniapp = res.data.contents.filter(v=> v.msgType == 5)
this.approver = res.data.examines
}
})
},
previewImages(images, img) {
uni.previewImage({
urls: images.map(v => v.imgPicUrl),
current: img
})
},
...mapActions(['previewFile']),
prevFile(file) {
this.$loading()
this.previewFile({ ...file }).then(()=>{
this.$hideLoading()
})
},
// msgtype: "miniprogram", // 消息类型,必填
// miniprogram: {
// appid: "", // 小程序的appid
// title: "", // 小程序消息的title
// imgUrl : "", //小程序消息的封面图。必须带http或者https协议头
// page: "", //小程序消息打开后的路径,注意要以.html作为后缀否则在微信端打开会提示找不到页面
// },
// },
// {
// msgtype: "file", // 消息类型必填从3.1.12版本开始支持
// file:{
// mediaid:"", // 文件的素材id必填
// },
// },
toSend() {
// 文本
const text = {
content: this.content
}
const attachments = []
// 图片
const imgs = this.picList.map(v =>{
return {
msgtype: "image",
image: {
mediaid: v.mediaId,
imgUrl: v.imgPicUrl,
},
}
})
attachments.push(imgs)
// 视频
const videos = this.videoList.map(v =>{
return {
msgtype: "video",
video:{
mediaid: v.mediaId,
},
}
})
attachments.push(videos)
// 文件
const files = this.fileList.map(v => {
return {
msgtype: "file",
file:{
mediaid: v.mediaId,
},
}
})
attachments.push(files)
// 链接
// const links = this.webpage.map(v =>{
// return {
// msgtype: "link", // 消息类型,必填
// link: {
// title: "", // H5消息标题
// imgUrl: "", // H5消息封面图片URL
// desc: "", // H5消息摘要
// url: "", // H5消息页面url 必填
// },
// }
// })
this.shareToExternalChat({ ...text, ...data })
},
},
onShow() {
document.title = "群发居民群任务"
this.getDetail()
}
}
</script>
<style lang="scss" scoped>
.massDispatch {
padding: 32px 32px 140px 32px;
box-sizing: border-box;
.tips {
width: 100%;
height: 50px;
line-height: 50px;
background: #fff1e8;
border: 1px solid #ff9e61;
border-radius: 8px;
margin-bottom: 16px;
padding: 0 30px;
box-sizing: border-box;
}
.task {
position: relative;
margin-bottom: 24px;
background: #FFF;
border-radius: 8px;
box-shadow: inset 0px -1px 0px 0px #DDDDDD;
.task_title {
padding: 26px 32px;
box-sizing: border-box;
border-bottom: 2px solid #DDDDDD;
}
.task_content {
padding: 0 32px 26px 32px;
box-sizing: border-box;
.item {
display: flex;
padding-top: 26px;
box-sizing: border-box;
span:first-child {
width: 160px;
color: #999999;
}
span:last-child {
width: calc(100% - 160px);
}
}
}
.task_results {
position: absolute;
right: 30px;
top: 30px;
img {
width: 160px;
height: 130px;
}
}
}
.info {
background: #FFF;
border-radius: 8px;
padding: 26px 32px;
box-sizing: border-box;
.scope {
display: flex;
margin-bottom: 16px;
span:first-child {
width: 160px;
color: #999;
}
span:last-child {
width: calc(100% - 160px);
}
}
.content {
p {
color: #999;
}
.textarea,
.pictures,
.video,
.file,
.webpage,
.miniapp {
background: #F9F9F9;
border-radius: 4px;
padding: 20px;
box-sizing: border-box;
margin-top: 26px;
}
.pictures {
margin-top: 16px;
image {
width: 190px;
height: 190px;
margin-right: 4px;
margin-bottom: 4px;
}
image:nth-child(3n) {
margin-right: 0;
}
}
.video {
video {
height: 300px;
}
}
.file {
.file_item {
display: flex;
align-items: center;
img {
width: 96px;
height: 96px;
}
}
}
}
}
.subBtn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 118px;
background: #f4f8fb;
padding: 18px 32px;
box-sizing: border-box;
div {
width: 100%;
height: 80px;
line-height: 80px;
text-align: center;
background: #1365dd;
border-radius: 4px;
font-size: 32px;
color: #fff;
float: right;
}
}
}
</style>

View File

@@ -250,6 +250,8 @@ export const wxwork = {
}
timer.injectJWeixin = setTimeout(() => {
const sdk = wx?.agentConfig ? wx : jWeixin
console.log("agentConfig配置:")
console.log({...state.config, jsApiList})
sdk?.agentConfig({
...state.config, jsApiList,
success: res => resolve(res),

View File

@@ -147,15 +147,13 @@ export default {
this.$dict.load('mstStatus').then(() => {
this.getList()
})
},
toDetail(item) {
if(this.tabIndex == 0) {
uni.navigateTo({url: `./cooperationDetail?id=${item.id}&time=${item.createTime}`})
} else {
alert('hhh')
uni.navigateTo({url: `./circleDetail??id=${item.id}&time=${item.createTime}&type=${this.sendType}`})
}
},
searchBtn() {
this.current = 1

View File

@@ -9,7 +9,7 @@
<div><span class="color_red">*</span><span class="title">发送范围</span></div>
<div @click="toSleectScoped">
<span>
<span class="color_gray" v-if="!form.sendScope || sum==0">请选择</span>
<span class="color_gray" v-if="!form.wxGroups || sum==0">请选择</span>
<span v-if="type=='ResidentsGroup' && form.wxGroups.length">预计送达{{ form.wxGroups.length }}名成员</span>
<span v-if="type!='ResidentsGroup' && sum != 0">预计送达{{ sum }}名成员</span>
<u-icon name="arrow-right" color="#CCD0D3"></u-icon>
@@ -192,7 +192,11 @@ export default {
sendScope: '', // 0全部居民群、1按部门选择、2按网格选择
sendType: '0', // 0立即发送、1定时发送
gender: '', // 性别0-女、1-男、2-全部
filterCriteria: ''
filterCriteria: '',
filterTags: [], //过滤标签id集合
excludeFilterTags: [], // 剔除标签集合
addFromTime: '',
addEndTime: '',
},
enableExamine: false,
isTimedTask: false,
@@ -255,8 +259,15 @@ export default {
upload: [],
midiaIds: [],
sum: '',
girdListIds: [],
deptListIds: [],
// 筛选条件
girdListIds: [], // 网格id集合
deptListIds: [], // 部门id集合
ResidentTags: [], // 居民包含
ResidentTagsRemove: [], // 居民剔除
circleTags: [], // 朋友圈包含
circleTagsRemove: [], // 朋友圈剔除
startTime: '',
endTime: '',
}
},
methods: {
@@ -469,14 +480,11 @@ export default {
if(this.type=='Residents') {
url = `/app/whchatmomentstask/addOrUpdate`
this.forms.filterCriteria = this.girdListIds.toString() || this.deptListIds.toString() || ''
this.forms.filterTags = ''
this.forms.excludeFilterTags = '剔除标签'
formData = this.forms
} else if(this.type=='CircleOfFriends') {
url = `/app/whchatmomentstask/addOrUpdate`
this.forms.filterCriteria = this.girdListIds.toString() || this.deptListIds.toString() || ''
this.forms.filterTags = '过滤标签'
this.forms.excludeFilterTags = '剔除标签'
this.forms.filterTags = this.ResidentTags.toString() || this.circleTags.toString() || ''
this.forms.excludeFilterTags = this.ResidentTagsRemove.toString() || this.circleTagsRemove.toString() || ''
this.forms.gender = this.sex
this.forms.addFromTime = this.startTime
this.forms.addEndTime = this.endTime
formData = this.forms
} else if(this.type=='ResidentsGroup') {
url = `/app/appmasssendingtask/addOrUpdate`
@@ -488,7 +496,7 @@ export default {
this.flag = false
this.$u.toast("新增成功")
setTimeout(() => {
navigateBack()
uni.navigateBack()
}, 600)
}
}).catch((err)=>{
@@ -549,6 +557,19 @@ export default {
if(deptArr.length) {
this.deptListIds = deptArr.map(v=>v.id)
}
// 性别
this.sex = uni.getStorageSync('gender')
// 标签
if(this.sendType == 'Residents') {
this.ResidentTags = uni.getStorageSync('ResidentTags') // 居民包含
this.ResidentTagsRemove = uni.getStorageSync('ResidentTagsRemove') // 居民剔除
} else if(this.sendType == 'CircleOfFriends') {
this.circleTags = uni.getStorageSync('circleTags') // 朋友圈包含
this.circleTagsRemove = uni.getStorageSync('circleTagsRemove') // 朋友圈剔除
}
// 时间
this.startTime = uni.getStorageSync('startTime')
this.endTime = uni.getStorageSync('endTime')
}
}
</script>

View File

@@ -1,19 +1,5 @@
<template>
<div class="circleDetail">
<!-- <AiTopFixed>
<div class="tab-select">
<div
class="item"
:class="tabIndex == index ? 'active' : ''"
v-for="(item, index) in tabs"
:key="index"
@click="tabClick(index)"
>
{{ item }}<span></span>
</div>
</div>
</AiTopFixed> -->
<div class="content">
<div class="header">
<div class="header_left">
@@ -35,27 +21,19 @@
<div id="pieEcharts"></div>
<div class="pie_right">
<div>
<span>{{
tabIndex == 0 ? "计划执行成员:" : "计划送达居民群:"
}}</span>
<span>计划执行成员</span>
<span>{{ info.planCount || 0 }}</span>
</div>
<div>
<span>{{
tabIndex == 0 ? "未执行成员:" : "未送达居民群:"
}}</span>
<span>未执行成员</span>
<span>{{ info.unExecutedCount || 0 }}</span>
</div>
<div>
<span>{{
tabIndex == 0 ? "已执行成员:" : "已送达居民群:"
}}</span>
<span>已执行成员</span>
<span>{{ info.executedCount || 0 }}</span>
</div>
<div>
<span>{{
tabIndex == 0 ? "无法执行成员:" : "无法送达居民群:"
}}</span>
<span>无法执行成员</span>
<span>{{ info.cannotExecuteCount || 0 }}</span>
</div>
</div>
@@ -78,7 +56,7 @@
<AiTable
:data="tableData"
:colConfigs="tabIndex == 0 ? colConfigs0 : colConfigs1"
:colConfigs="colConfigs"
v-if="tableData.length"/>
<AiEmpty v-if="!tableData.length" description="暂无数据"></AiEmpty>
</div>
@@ -95,8 +73,7 @@ export default {
tabs: ["成员统计", "居民群统计"],
tabIndex: 0,
pieEcharts: null,
subIndex0: 0,
subIndex1: 0,
subIndex: 0,
tableData: [],
createTime: "",
id: "",
@@ -112,56 +89,25 @@ export default {
{ name: "无法执行" },
],
update: true,
type: "",
};
},
computed: {
colConfigs0() {
colConfigs() {
return [
{ prop: "groupOwnerName", label: "成员" },
{ label: "预计送达居民", prop: "groupCount" },
];
},
colConfigs1() {
return [
{ label: "居民群", prop: "groupName" },
{ label: "群人数", prop: "memberCount" },
{ slot: "groupOwnerId", label: "群主" },
{ prop: "userName", label: "成员" },
{ prop: "customerCount", label: "预计送达居民"},
];
},
},
onLoad(o) {
this.id = o.id;
this.createTime = o.time;
this.type = o.type
},
methods: {
tabClick(index) {
this.tabIndex = index;
if(this.tabIndex == 0) {
this.subsection = [
{ name: "未执行" },
{ name: "已执行" },
{ name: "无法执行" },
]
this.update0 = true
this.update1 = false
this.$forceUpdate()
} else if(this.tabIndex == 1) {
this.subsection = [
{ name: "未送达" },
{ name: "已送达" },
{ name: "无法送达" },
]
this.update0 = false
this.update1 = true
this.$forceUpdate()
}
this.getStatistics();
},
getDetail() {
this.$http
.post(`/app/appmasssendingtask/queryDetailById?id=${this.id}`)
.then((res) => {
this.$http.post(`/app/whchatmomentstask/queryDetailById?id=${this.id}`).then((res) => {
if (res?.data) {
this.detail = res.data;
}
@@ -169,7 +115,7 @@ export default {
},
toDetail() {
uni.navigateTo({ url: `./detail?id=${this.id}` });
uni.navigateTo({ url: `./detail?id=${this.id}&type=${this.type}` });
},
// 提醒发送
remindSend() {
@@ -184,8 +130,8 @@ export default {
});
this.currentClickTime = +new Date();
let time = this.currentClickTime - this.firstClickTime;
if (time >= 3600000) {
this.$http.post("/app/appmasssendingtask/remindSend", null, {
if (time >= 3600000) {
this.$http.post("/app/whchatmomentstask/remindSend", null, {
params: {
id: this.id,
},
@@ -220,25 +166,23 @@ export default {
},
// 获取数据
getStatistics() {
this.$http
.post(`/app/appmasssendingtask/detailStatistics`, null, {
params: {
type: this.tabIndex,
sendStatus: this.tabIndex==0? this.subIndex0: this.subIndex1,
taskId: this.id,
current: this.current,
size: 3000,
},
})
.then((res) => {
if (res?.data) {
this.info = res.data;
this.tableData = res.data.executedList.records;
setTimeout(()=>{
this.getPieEcharts();
}, 1000)
}
});
this.$http.post('/app/whchatmomentstask/detailStatistics', null, {
params: {
sendStatus: this.subIndex,
taskId: this.id,
current: this.current,
size: 3000,
},
})
.then((res) => {
if (res?.data) {
this.info = res.data
this.tableData = res.data.executedList.records
setTimeout(()=>{
this.getPieEcharts()
}, 1000)
}
});
},
// 饼图
@@ -251,7 +195,7 @@ export default {
color: ["#1684fc", "#ccc"],
series: [
{
name: this.tabIndex == 0 ? "任务完成率" : "群发送达率",
name: "任务完成率",
type: "pie",
radius: ["50%", "70%"],
avoidLabelOverlap: false,
@@ -273,11 +217,7 @@ export default {
show: true,
formatter: ({ name, value }) => {
let num = value / this.info.planCount * 100
if (this.tabIndex == 0) {
return num % 1==0? `{name|任务达成率\n\n}{value|${num}%}`: `{name|任务达成率\n\n}{value|${ num.toFixed(1) }%}`;
} else {
return num % 1==0? `{name|群发送达率\n\n}{value|${num}%}`: `{name|群发送达率\n\n}{value|${ num.toFixed(1) }%}`;
}
return `{name|任务达成率\n\n}{value|${num}%}`
},
textStyle: {
fontSize: 16,

View File

@@ -230,14 +230,18 @@ export default {
}
},
// 切换分段器
changeSub(index) {
this.subIndex = index;
// 切换分段器
changeSub0(index) {
this.subIndex0 = index;
this.getStatistics();
},
changeSub1(index) {
this.subIndex1 = index;
this.getStatistics();
},
// 获取数据
getStatistics() {
this.$http
.post(`/app/appmasssendingtask/detailStatistics`, null, {
this.$http.post(`/app/appmasssendingtask/detailStatistics`, null, {
params: {
type: this.tabIndex,
sendStatus: this.tabIndex==0? this.subIndex0: this.subIndex1,

View File

@@ -103,17 +103,25 @@ export default {
pictres: [],
options: '',
approver: [], //审批人
type: '',
}
},
onLoad(o) {
this.id = o.id
this.type = o.type
},
computed: {
...mapState(['user'])
},
methods: {
getDetail() {
this.$http.post(`/app/appmasssendingtask/queryDetailById?id=${this.id}`).then(res=> {
let url = ''
if(this.type == 'ResidentsGroup') {
url = `/app/appmasssendingtask/queryDetailById?id=${this.id}`
} else {
url = `/app/whchatmomentstask/queryDetailById?id=${this.id}`
}
this.$http.post(url).then(res=> {
if (res?.data) {
this.data = res.data
this.content = res.data.contents.filter(v=> v.msgType == 0)?.[0].content
@@ -159,7 +167,14 @@ export default {
})
},
examine() {
this.$http.post(`/app/appmasssendingtask/examine`,null,{
// /app/whchatmomentstask/examine
let url = ''
if(this.type == 'ResidentsGroup') {
url = `/app/appmasssendingtask/examine`
} else {
url = `/app/whchatmomentstask/examine`
}
this.$http.post(url,null,{
params: {
pass: this.pass,
id: this.id,

View File

@@ -56,19 +56,14 @@ export default {
},
submit() {
if(this.sendType == 'ResidentsGroup') {
this.getWxGroups().then(()=>{
setTimeout(() => {
uni.navigateBack()
}, 600)
})
this.getWxGroups()
} else if(this.sendType == 'Residents' || this.sendType == 'CircleOfFriends') {
this.getSendScope().then(()=>{
setTimeout(() => {
uni.navigateBack()
}, 600)
})
this.getSendScope()
}
uni.setStorageSync('sendScope', this.sendScope)
setTimeout(() => {
uni.navigateBack()
}, 600)
},
// 群发居民群
getWxGroups() {
@@ -120,6 +115,7 @@ export default {
},
onShow() {
this.sendScope = uni.getStorageSync('sendScope') || ''
// 部门、网格
const girdArr = uni.getStorageSync('girdSelect')
if(girdArr.length) {
this.girdListIds = girdArr.map(e=>e.id)
@@ -128,6 +124,7 @@ export default {
if(deptArr.length) {
this.deptListIds = deptArr.map(v=>v.id)
}
// 性别
this.sex = uni.getStorageSync('gender')
// 标签
if(this.sendType == 'Residents') {