This commit is contained in:
liuye
2022-07-27 10:54:10 +08:00
15 changed files with 182 additions and 359 deletions

View File

@@ -62,6 +62,9 @@
</el-form-item> </el-form-item>
</template> </template>
<template v-if="form.type==1"> <template v-if="form.type==1">
<el-form-item label="路由名" prop="route">
<span v-text="form.route||'提交保存后会自动生成'"/>
</el-form-item>
<el-form-item label="菜单应用" prop="component"> <el-form-item label="菜单应用" prop="component">
<el-input v-model="form.component" placeholder="请输入" clearable/> <el-input v-model="form.component" placeholder="请输入" clearable/>
</el-form-item> </el-form-item>

View File

@@ -11,7 +11,7 @@
<main-content class="fill"/> <main-content class="fill"/>
</el-row> </el-row>
<div v-if="dialog" class="sign-box"> <div v-if="dialog" class="sign-box">
<ai-sign style="margin: auto" :instance="$axios" :action="{login}" <ai-sign style="margin: auto" :instance="$request" :action="{login}"
visible @login="getToken" :showScanLogin="false"/> visible @login="getToken" :showScanLogin="false"/>
</div> </div>
<el-button type="info" v-if="!showTools" class="fixedBtn" @click="showTools=true">显示工具栏</el-button> <el-button type="info" v-if="!showTools" class="fixedBtn" @click="showTools=true">显示工具栏</el-button>
@@ -54,7 +54,7 @@ export default {
}, },
handleLogin() { handleLogin() {
this.$axios.delete("/auth/token/logout").finally(() => { this.$request.delete("/auth/token/logout").finally(() => {
this.dialog = true this.dialog = true
}) })
}, },

View File

@@ -17,10 +17,8 @@ Vue.use(vcUI);
Vue.use(dvui) Vue.use(dvui)
//富文本编辑器配置 //富文本编辑器配置
Vue.config.productionTip = false; Vue.config.productionTip = false;
Vue.prototype.$axios = axios;
Vue.prototype.$request = axios
Vue.prototype.formatContent = (val) => val.replace(/(\r\n)|(\n)/g, '<br>');
Object.keys(utils).map((e) => (Vue.prototype[e] = utils[e])); Object.keys(utils).map((e) => (Vue.prototype[e] = utils[e]));
Vue.prototype.$request = axios
new Vue({ new Vue({
router, router,
store, store,

View File

@@ -15,15 +15,13 @@ instance.interceptors.request.use(config => {
config.baseURL = "/saas" config.baseURL = "/saas"
} else if (/\/xiushan/.test(location.pathname)) { } else if (/\/xiushan/.test(location.pathname)) {
config.baseURL = "/xsjr" config.baseURL = "/xsjr"
config.url = config.url.replace(/(app|auth|admin)\//, "")
} else if (/project\/oms/.test(location.pathname)) { } else if (/project\/oms/.test(location.pathname)) {
config.baseURL = "/omsapi" config.baseURL = "/omsapi"
config.url = config.url.replace(/(app|auth|admin)\//, "")
} else if (/#url-/.test(location.hash)) { } else if (/#url-/.test(location.hash)) {
config.baseURL = location.hash.replace(/#url-/, '/') config.baseURL = location.hash.replace(/#url-/, '/')
if (["/xsjr", "/omsapi"].includes(config.baseURL)) { }
config.url = config.url.replace(/(app|auth|admin)\//, "") if (["/xsjr", "/omsapi"].includes(config.baseURL)) {
} config.url = config.url.replace(/(app|auth|admin)\//, "")
} }
return config return config
}, error => Message.error(error)) }, error => Message.error(error))

View File

@@ -1,6 +1,6 @@
<template> <template>
<section class="appEntry"> <section class="appEntry">
<component v-if="app" :is="app" :instance="$axios" :dict="$dict" :permissions="$permissions"/> <component v-if="app" :is="app" :instance="$request" :dict="$dict" :permissions="$permissions"/>
<ai-empty v-else>无法找到应用文件</ai-empty> <ai-empty v-else>无法找到应用文件</ai-empty>
</section> </section>
</template> </template>

View File

@@ -95,10 +95,10 @@
<template #left> <template #left>
<el-select v-model="search.joinStatus" placeholder="确认状态" size="small" clearable class="vc-input-160" @change="searchMeetinguser"> <el-select v-model="search.joinStatus" placeholder="确认状态" size="small" clearable class="vc-input-160" @change="searchMeetinguser">
<el-option <el-option
v-for="(item,k) in confirmStatus" v-for="(item,k) in confirmStatus"
:key="k" :key="k"
:label="item.label" :label="item.label"
:value="k"> :value="k">
</el-option> </el-option>
</el-select> </el-select>
</template> </template>
@@ -109,10 +109,10 @@
</template> </template>
</ai-search-bar> </ai-search-bar>
<ai-table <ai-table
:tableData="info.attendees" :tableData="info.attendees"
:colConfigs="colConfigs" :colConfigs="colConfigs"
style="margin-top: 12px;" style="margin-top: 12px;"
:isShowPagination="false"> :isShowPagination="false">
<el-table-column slot="meetingUserName" <el-table-column slot="meetingUserName"
label="姓名" label="姓名"
align="center" align="center"
@@ -201,7 +201,7 @@ export default {
{ {
slot: 'joinStatus', slot: 'joinStatus',
}, },
{ prop: 'signInStatus', align: 'center', label: '签到', formart: v => v === '1' ? '已签到' : '未签到' }, {prop: 'signInStatus', align: 'center', label: '签到', formart: v => v === '1' ? '已签到' : '未签到'},
{ {
slot: 'option', slot: 'option',
} }
@@ -249,11 +249,9 @@ export default {
params: {id} params: {id}
}).then(res => { }).then(res => {
if (res?.data) { if (res?.data) {
this.info = { let {files = [], content} = res.data
...res.data, content = content.replace(/(\r\n)|(\n)/g, "<br>")
content: this.formatContent(res.data.content || ""), this.info = {...res.data, content, files};
files: res.data.files || []
};
this.searchMeetinguser() this.searchMeetinguser()
} }
}); });

View File

@@ -141,12 +141,9 @@
<h2>网格动态</h2> <h2>网格动态</h2>
</div> </div>
<div class="bottom-list"> <div class="bottom-list">
<div class="item" v-for="(item, index) in 3" :key="index"> <div class="item" v-for="item in dynamicList" :key="item.id">
<i>07/19 09:45</i> <i>{{ item.createTime }}</i>
<span>书院社区-张三 </span> <em>{{ item.logDescription }}</em>
<em>添加居民"</em>
<span>蓝天白云</span>
<em>"为好友</em>
</div> </div>
</div> </div>
</div> </div>
@@ -261,7 +258,8 @@
tagInfo: {}, tagInfo: {},
groupNumber: {}, groupNumber: {},
replyPercentage: {}, replyPercentage: {},
groupChatNumber: {} groupChatNumber: {},
dynamicList: []
} }
}, },
@@ -299,6 +297,11 @@
this.replyPercentage = res.data this.replyPercentage = res.data
} }
}) })
this.instance.post(`/app/appUserOperation/list?size=10000`).then(res => {
if (res.code === 0) {
this.dynamicList = res.data.records
}
})
this.instance.post(`/app/wxgroupstatistic/getGroupNumber`).then(res => { this.instance.post(`/app/wxgroupstatistic/getGroupNumber`).then(res => {
if (res.code === 0) { if (res.code === 0) {
this.groupNumber = res.data['居民群统计'] this.groupNumber = res.data['居民群统计']

View File

@@ -2,7 +2,7 @@
<div class="DonutChart" :id="id"> <div class="DonutChart" :id="id">
<canvas :id="canvasId"></canvas> <canvas :id="canvasId"></canvas>
<div class="DonutChart-text"> <div class="DonutChart-text">
<span>{{ ratio }}%</span> <span>{{ ratio || 0 }}%</span>
<i>{{ text }}</i> <i>{{ text }}</i>
</div> </div>
</div> </div>

View File

@@ -1,8 +1,8 @@
<template> <template>
<div class="AppAnnounce"> <div class="AppAnnounce">
<keep-alive :include="['List']"> <!-- <keep-alive :include="['List']"> -->
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
</keep-alive> <!-- </keep-alive> -->
</div> </div>
</template> </template>
@@ -35,7 +35,13 @@
}, },
mounted () { mounted () {
console.log(this.$route)
if (this.$route.params.id) {
this.component = 'Detail'
this.params = {
id: this.$route.params.id
}
}
}, },
methods: { methods: {

View File

@@ -23,24 +23,26 @@
<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' }]">
<div class="AppAnnounceDetail-select"> <div class="AppAnnounceDetail-select">
<el-input size="small" class="AppAnnounceDetail-select__input" placeholder="请选择..." disabled v-model="form.wxGroupsName"></el-input> <el-input size="small" class="AppAnnounceDetail-select__input" placeholder="请选择..." disabled v-model="form.wxGroupsName"></el-input>
<div class="select-left" v-if="form.filterCriteria.length"> <div class="select-left" v-if="form.wxGroups.length">
<span v-for="(item, index) in form.filterCriteria" :key="index"> <span v-for="(item, index) in form.wxGroups" :key="index">
<ai-open-data type="departmentName" :openid="item"></ai-open-data> <ai-open-data type="userName" :openid="item.groupOwnerId"></ai-open-data>
</span> </span>
</div> </div>
<i v-if="!form.filterCriteria.length">请选择</i> <i v-if="!form.wxGroups.length">请选择</i>
<ai-picker <ai-picker
:instance="instance" :instance="instance"
multiple multiple
:ops="{label: form.sendScope === '2' ? 'girdName' : 'name'}"
:action="form.sendScope === '1' ? '/app/wxcp/wxdepartment/departList' : '/app/appgirdinfo/girdList'" :action="form.sendScope === '1' ? '/app/wxcp/wxdepartment/departList' : '/app/appgirdinfo/girdList'"
v-model="form.filterCriteria" v-model="form.filterCriteria"
@pick="onPick"
@change="onSelcetChange"> @change="onSelcetChange">
<div class="select-right">选择</div> <div class="select-right">选择</div>
</ai-picker> </ai-picker>
</div> </div>
<div class="tips"> <div class="tips">
<p>消息预计送达居民群数</p> <p>消息预计送达居民群数</p>
<span>{{ form.filterCriteria.length }}</span> <span>{{ groupLen }}</span>
<el-tooltip <el-tooltip
placement="top" placement="top"
content="任务开始后3天内15分钟更新1次3天后访问页面时触发更新1时间最多刷新1次"> content="任务开始后3天内15分钟更新1次3天后访问页面时触发更新1时间最多刷新1次">
@@ -157,57 +159,7 @@
</ai-card> </ai-card>
</el-form> </el-form>
<div class="right"> <div class="right">
<img class="phone" src="https://cdn.cunwuyun.cn/dvcp/announce/phone.png" /> <Phone :avatar="user.info.avatar" @close="isShowPhone = false" :isShowClose="false" :content="form.content" :fileList="fileList"></Phone>
<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="form.content">
<div class="msg-item__left">
<img v-if="user.info.avatar" :src="user.info.avatar" />
</div>
<div class="msg-item__right">
<div class="msg-wrapper msg-text">
<p>{{ form.content }}</p>
</div>
</div>
</div>
<div class="msg-item" v-for="item in fileList" :key="item.id">
<div class="msg-item__left">
<img v-if="user.info.avatar" :src="user.info.avatar" />
</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="https://cdn.cunwuyun.cn/dvcp/announce/folder.png" />
</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" />
</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> </div>
<ai-dialog <ai-dialog
:visible.sync="isShowAddLink" :visible.sync="isShowAddLink"
@@ -311,6 +263,7 @@
</template> </template>
<script> <script>
import Phone from './Phone'
import { mapActions, mapState } from 'vuex' import { mapActions, mapState } from 'vuex'
export default { export default {
name: 'Add', name: 'Add',
@@ -321,6 +274,10 @@
params: Object params: Object
}, },
components: {
Phone
},
data () { data () {
return { return {
info: {}, info: {},
@@ -360,23 +317,23 @@
taskTitle: '', taskTitle: '',
examinesName: '' examinesName: ''
}, },
girdNames: '',
id: '', id: '',
tagsList: [] tagsList: []
} }
}, },
watch: {
fileList (v) {
if (v.length) {
setTimeout(() => {
document.querySelector('.right-content').scrollTo(0, 999999)
}, 800)
}
}
},
computed: { computed: {
...mapState(['user']) ...mapState(['user']),
groupLen () {
let i = 0
this.form.wxGroups.forEach(v => {
i = i + v.groupIds.split(',').length
})
return i
}
}, },
created () { created () {
@@ -401,6 +358,10 @@
filterCriteria: res.data.filterCriteria.split(',') filterCriteria: res.data.filterCriteria.split(',')
} }
if (res.data.girdNames) {
this.girdNames = res.data.girdNames.split(',')
}
this.dateForm.choiceTime = res.data.choiceTime this.dateForm.choiceTime = res.data.choiceTime
if (res.data.examines && res.data.examines.length) { if (res.data.examines && res.data.examines.length) {
@@ -439,6 +400,10 @@
}, },
onScopeChange (e) { onScopeChange (e) {
this.form.filterCriteria = []
this.form.wxGroups = []
this.girdNames = ''
if (e === '0') { if (e === '0') {
this.getWxGroups() this.getWxGroups()
} else { } else {
@@ -446,6 +411,12 @@
} }
}, },
onPick (e) {
if (this.form.sendScope === '2' && e.length) {
this.girdNames = e.map(v => v.girdName)
}
},
onSelcetChange (e) { onSelcetChange (e) {
if (e.length) { if (e.length) {
this.form.wxGroupsName = '1' this.form.wxGroupsName = '1'
@@ -590,6 +561,10 @@
confirm (sendType) { confirm (sendType) {
this.$refs.form.validate((valid) => { this.$refs.form.validate((valid) => {
if (valid) { if (valid) {
if (!this.form.wxGroups.length) {
return this.$message.error('居民群数量不能为0')
}
if (sendType === 1 && !this.dateForm.choiceTime) { if (sendType === 1 && !this.dateForm.choiceTime) {
this.isShowDate = true this.isShowDate = true
return false return false
@@ -777,223 +752,6 @@
.right { .right {
position: sticky; position: sticky;
top: 0; top: 0;
width: 338px;
height: 675px;
padding: 80px 15px 100px 32px;
.phone {
position: absolute;
left: 13px;
top: 4px;
z-index: 1;
width: 314px;
height: 647px;
}
.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;
background: #2891FF;
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;
}
p {
color: #888888;
font-size: 12px;
}
}
img {
width: 44px;
height: 44px;
border-radius: 2px;
}
}
.msg-link {
width: 206px;
height: 102px;
padding: 12px;
background: #FFFFFF;
border-radius: 5px;
h2 {
margin-bottom: 4px;
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;
}
}
}
}
}
}
} }
.AppAnnounceDetail-select { .AppAnnounceDetail-select {

View File

@@ -7,7 +7,7 @@
<template slot="content"> <template slot="content">
<ai-card title="基础信息"> <ai-card title="基础信息">
<template #right> <template #right>
<div class="right-tips"> <div class="right-tips" v-if="info.status === '4'">
<el-tooltip <el-tooltip
placement="top" placement="top"
content="任务开始后3天内15分钟更新1次3天后访问页面时触发更新1时间最多刷新1次"> content="任务开始后3天内15分钟更新1次3天后访问页面时触发更新1时间最多刷新1次">
@@ -26,15 +26,15 @@
<div class="user"> <div class="user">
<img src="https://cdn.cunwuyun.cn/dvcp/announce/user.png" /> <img src="https://cdn.cunwuyun.cn/dvcp/announce/user.png" />
<span><ai-open-data type="userName" :openid="info.createUserId"></ai-open-data></span> <span><ai-open-data type="userName" :openid="info.createUserId"></ai-open-data></span>
<span v-if="info.createUserSecondDept"><ai-open-data type="departmentName" :openid="info.createUserSecondDept"></ai-open-data>,</span>
<span><ai-open-data type="departmentName" :openid="info.createUserDept"></ai-open-data></span>
</div> </div>
</ai-info-item> </ai-info-item>
<ai-info-item label="审批人"> <ai-info-item label="审批人">
<div class="user-wrapper"> <div class="user-wrapper">
<div class="user" v-for="(item, index) in info.examines" :key="index"> <div class="user" v-for="(item, index) in info.examines" :key="index">
<img src="https://cdn.cunwuyun.cn/dvcp/announce/user.png" /> <img src="https://cdn.cunwuyun.cn/dvcp/announce/user.png" />
<span> <span><ai-open-data type="userName" :openid="item.examineUserId"></ai-open-data></span>
<ai-open-data type="userName" :openid="item.examineUserId"></ai-open-data>
</span>
</div> </div>
</div> </div>
</ai-info-item> </ai-info-item>
@@ -51,14 +51,17 @@
<ai-info-item label="消息内容" isLine> <ai-info-item label="消息内容" isLine>
<div class="msg"> <div class="msg">
<p>{{ content }}</p> <p>{{ content }}</p>
<div class="msg-bottom" v-if="fileList.length"> <div class="msg-bottom">
<div class="left"> <div class="left" v-if="fileList.length">
<img :src="mapIcon(fileList[0].msgType)" /> <img :src="mapIcon(fileList[0].msgType)" />
<span>{{ mapType(fileList[0].msgType) }}{{ fileList[0].mpTitle || fileList[0].name || fileList[0].linkTitle }} </span> <span>{{ mapType(fileList[0].msgType) }}{{ fileList[0].mpTitle || fileList[0].name || fileList[0].linkTitle }} </span>
<i>{{ fileList.length }}</i> <i>{{ fileList.length }}</i>
<span>个附件</span> <span>个附件</span>
</div> </div>
<div class="right">预览消息</div> <div class="left" v-else>
<span>暂无附件</span>
</div>
<div class="right" @click="isShowPhone = true">预览消息</div>
</div> </div>
</div> </div>
</ai-info-item> </ai-info-item>
@@ -201,7 +204,7 @@
:current.sync="search2.current" :current.sync="search2.current"
:size.sync="search2.size" :size.sync="search2.size"
@getList="getGroupInfo"> @getList="getGroupInfo">
<el-table-column slot="user" label="群" align="center"> <el-table-column slot="user" label="群" align="center">
<template slot-scope="{ row }"> <template slot-scope="{ row }">
<div class="userinfo"> <div class="userinfo">
<span> <span>
@@ -230,20 +233,11 @@
tableSize="small" tableSize="small"
:isShowPagination="false" :isShowPagination="false"
@getList="() => {}"> @getList="() => {}">
<el-table-column slot="user" label="群名称" align="center">
<template slot-scope="{ row }">
<div class="userinfo">
<span v-for="(item, index) in row.groupIds" :key="index">
<ai-open-data type="departmentName" :openid="item"></ai-open-data>
</span>
</div>
</template>
</el-table-column>
</ai-table> </ai-table>
</ai-dialog> </ai-dialog>
<div class="detail-phone"> <div class="detail-phone" v-if="isShowPhone">
<div class="mask"></div> <div class="mask"></div>
<Phone :avatar="user.info.avatar" :content="content" :fileList="fileList"></Phone> <Phone :avatar="user.info.avatar" @close="isShowPhone = false" :isShowClose="true" :content="content" :fileList="fileList"></Phone>
</div> </div>
</template> </template>
</ai-detail> </ai-detail>
@@ -269,6 +263,7 @@
return { return {
total1: 0, total1: 0,
isShowGroups: false, isShowGroups: false,
isShowPhone: false,
total2: 0, total2: 0,
user1: [], user1: [],
user2: [], user2: [],
@@ -297,7 +292,7 @@
currIndex: 0, currIndex: 0,
colConfigs3: [ colConfigs3: [
{ prop: 'groupOwnerId', label: '群主', openType: 'userName' }, { prop: 'groupOwnerId', label: '群主', openType: 'userName' },
{ slot: 'user' } { prop: 'groupNames', label: '群名称' }
], ],
colConfigs1: [ colConfigs1: [
{ slot: 'user', label: '成员', openType: 'userName' }, { slot: 'user', label: '成员', openType: 'userName' },
@@ -369,7 +364,12 @@
} }
}).then(res => { }).then(res => {
if (res.code === 0) { if (res.code === 0) {
this.tableData2 = res.data.executedList.records this.tableData2 = res.data.executedList.records.map(v => {
return {
...v,
groupName: v.groupName || '未命名群聊'
}
})
this.total2 = res.data.executedList.total this.total2 = res.data.executedList.total
this.groupInfo = res.data this.groupInfo = res.data
} }

View File

@@ -35,7 +35,7 @@
</el-date-picker> </el-date-picker>
<div class="userSelcet" placeholder="请选择创建人"> <div class="userSelcet" placeholder="请选择创建人">
<span v-if="search.createUserId"><ai-open-data type="userName" :openid="search.createUserId"></ai-open-data></span> <span v-if="search.createUserId"><ai-open-data type="userName" :openid="search.createUserId"></ai-open-data></span>
<span v-else>请选择</span> <span v-else>创建人</span>
<ai-user-get isStrictly :instance="instance" @change="onUserChange" :isMultiple="false" v-model="user"> <ai-user-get isStrictly :instance="instance" @change="onUserChange" :isMultiple="false" v-model="user">
<div class="select-btn">选择</div> <div class="select-btn">选择</div>
</ai-user-get> </ai-user-get>
@@ -77,9 +77,11 @@
<el-table-column slot="options" width="140px" fixed="right" label="操作" align="center"> <el-table-column slot="options" width="140px" fixed="right" label="操作" align="center">
<template slot-scope="{ row }"> <template slot-scope="{ row }">
<div class="table-options"> <div class="table-options">
<el-button type="text" @click="toAdd(row.id)">编辑</el-button> <el-button type="text" @click="remindExamine(row.id)" v-if="['0'].includes(row.status)">催办</el-button>
<el-button type="text" @click="cancel(row.id)" v-if="['0'].includes(row.status)">撤回</el-button>
<el-button type="text" @click="toDetail(row.id)">详情</el-button> <el-button type="text" @click="toDetail(row.id)">详情</el-button>
<el-button type="text" @click="remove(row.id)">删除</el-button> <el-button type="text" @click="toAdd(row.id)" v-if="['1', '3'].includes(row.status)">编辑</el-button>
<!-- <el-button type="text" @click="remove(row.id)">删除</el-button> -->
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@@ -116,8 +118,19 @@
{ prop: 'taskTitle', label: '任务名称' }, { prop: 'taskTitle', label: '任务名称' },
{ prop: 'sendType', label: '群发类型', formart: v => v === '0' ? '立即发送' : '定时发送', align: 'center' }, { prop: 'sendType', label: '群发类型', formart: v => v === '0' ? '立即发送' : '定时发送', align: 'center' },
{ slot: 'user', label: '创建人', openType: 'userName', align: 'center' }, { slot: 'user', label: '创建人', openType: 'userName', align: 'center' },
{ prop: 'createTime', label: '群发时间', align: 'center' }, { prop: 'choiceTime', label: '群发时间', align: 'center' },
{ prop: 'status', label: '状态', formart: v => this.dict.getLabel('mstStatus', v), 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' } { prop: 'completionRate', label: '任务完成率', align: 'center' }
] ]
} }
@@ -164,6 +177,28 @@
}) })
}, },
remindExamine (id) {
this.$confirm('确定催办该数据?').then(() => {
this.instance.post(`/app/appmasssendingtask/remindExamine?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) { remove(id) {
this.$confirm('确定删除该数据?').then(() => { this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appmasssendingtask/delete?ids=${id}`).then(res => { this.instance.post(`/app/appmasssendingtask/delete?ids=${id}`).then(res => {

View File

@@ -1,12 +1,13 @@
<template> <template>
<div class="phone-container"> <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" src="https://cdn.cunwuyun.cn/dvcp/announce/phone.png" />
<img class="phone-wrapper" src="https://cdn.cunwuyun.cn/dvcp/announce/phone-wrapper.png" /> <img class="phone-wrapper" src="https://cdn.cunwuyun.cn/dvcp/announce/phone-wrapper.png" />
<div class="right-content"> <div class="right-content">
<div class="msg-list"> <div class="msg-list">
<div class="msg-item" v-if="content"> <div class="msg-item" v-if="content">
<div class="msg-item__left"> <div class="msg-item__left">
<img v-if="avatar" :src="avatar" /> <img src="https://cdn.cunwuyun.cn/dvcp/announce/avatar.png" />
</div> </div>
<div class="msg-item__right"> <div class="msg-item__right">
<div class="msg-wrapper msg-text"> <div class="msg-wrapper msg-text">
@@ -16,7 +17,7 @@
</div> </div>
<div class="msg-item" v-for="item in fileList" :key="item.id"> <div class="msg-item" v-for="item in fileList" :key="item.id">
<div class="msg-item__left"> <div class="msg-item__left">
<img v-if="avatar" :src="avatar" /> <img src="https://cdn.cunwuyun.cn/dvcp/announce/avatar.png" />
</div> </div>
<div class="msg-item__right" :class="[['1', '2'].indexOf(item.msgType) !== -1 ? 'left-border' : '']"> <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'"> <div class="msg-wrapper msg-img" v-if="item.msgType === '1'">
@@ -56,7 +57,17 @@
<script> <script>
export default { export default {
props: ['fileList', 'avatar', 'content'] props: ['fileList', 'avatar', 'content', 'isShowClose'],
watch: {
fileList (v) {
if (v.length) {
setTimeout(() => {
document.querySelector('.right-content').scrollTo(0, 999999)
}, 800)
}
}
},
} }
</script> </script>
@@ -75,6 +86,22 @@
height: 647px; 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 { .phone-wrapper {
position: absolute; position: absolute;
left: 0; left: 0;
@@ -98,7 +125,6 @@
width: 42px; width: 42px;
height: 42px; height: 42px;
margin-right: 16px; margin-right: 16px;
background: #2891FF;
border-radius: 4px; border-radius: 4px;
flex-shrink: 1; flex-shrink: 1;
overflow: hidden; overflow: hidden;
@@ -172,7 +198,7 @@
font-size: 14px; font-size: 14px;
} }
img { & > img {
width: 100%; width: 100%;
height: 120px; height: 120px;
margin-bottom: 8px; margin-bottom: 8px;

View File

@@ -46,7 +46,7 @@
</div> </div>
<div class="flex-between"> <div class="flex-between">
<div class="item-info">群发类型<span>{{$dict.getLabel('mstSendType', item.sendType) || ''}}</span></div> <div class="item-info">群发类型<span>{{$dict.getLabel('mstSendType', item.sendType) || ''}}</span></div>
<span class="item-btn">详情{{item.sendType}}</span> <span class="item-btn" @click="$router.push({name: '357e228ba8e64008ace90d095a7a0dd7', params: { id: item.id }})">详情{{item.sendType}}</span>
</div> </div>
</el-card> </el-card>
</el-timeline-item> </el-timeline-item>
@@ -213,7 +213,7 @@
this.getCalendarList(year, month) this.getCalendarList(year, month)
this.getEffect() this.getEffect()
this.getDepart() this.getDepart()
this.dict.load('mstSendType') this.dict.load('mstSendType')
}, },
methods: { methods: {
...mapActions(['initOpenData', 'transCanvas']), ...mapActions(['initOpenData', 'transCanvas']),
@@ -561,7 +561,7 @@
width: 70px; width: 70px;
} }
.name{ .name{
width: calc(100% - 70px); width: calc(100% - 70px);
} }
} }
.item-btn{ .item-btn{

View File

@@ -255,11 +255,9 @@ export default {
params: {id} params: {id}
}).then(res => { }).then(res => {
if (res?.data) { if (res?.data) {
this.info = { let {files = [], content} = res.data
...res.data, content = content.replace(/(\r\n)|(\n)/g, "<br>")
content: this.formatContent(res.data.content || ""), this.info = {...res.data, content, files};
files: res.data.files || []
};
this.searchMeetinguser() this.searchMeetinguser()
} }
}); });