512 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			512 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template class="commonList">
 | ||
|   <section>
 | ||
|     <ai-list>
 | ||
|       <template slot="content">
 | ||
|         <el-button class="btn" style="margin-bottom: 10px;" type="primary" icon="iconfont iconAdd" size="small" @click="showAdd">添加公共模板</el-button>
 | ||
| 
 | ||
|         <ai-table :tableData="tableData" :col-configs="colConfigs" :total="page.total" :current.sync="page.current" :size.sync="page.size" @getList="getList" :dict="dict" style="height: 610px;overflow: auto;">
 | ||
|           <!-- 消息类型 -->
 | ||
|           <el-table-column slot="msgtype" label="消息类型" align="center">
 | ||
|             <template slot-scope="{ row }">
 | ||
|               <span v-for="(item, index) in types" :key="index">
 | ||
|                 <span v-if="item.label == row.msgtype">
 | ||
|                   {{ item.name }}
 | ||
|                 </span>
 | ||
|               </span>
 | ||
|             </template>
 | ||
|           </el-table-column>
 | ||
| 
 | ||
|           <!-- 消息内容 -->
 | ||
|           <el-table-column slot="content" label="消息内容" align="center">
 | ||
|             <template slot-scope="{ row }">
 | ||
|               <div class="table-left__wrapper">
 | ||
|                 <img :src="row.media.file && row.media.file.accessUrl" v-if="row.media && (row.msgtype == 'image' || row.msgtype == 'news')" class="media" style="width: 40px;height: 40px;" />
 | ||
| 
 | ||
|                 <video :src="row.media.file && row.media.file.accessUrl" v-if="row.media && row.msgtype == 'video'" class="media" style="width: 40px;height: 40px;"></video>
 | ||
| 
 | ||
|                 <ai-audio :src="row.media.file && row.media.file.accessUrl" v-if="row.media && row.msgtype == 'voice'" class="media" style="width: 40px;height: 40px;"></ai-audio>
 | ||
| 
 | ||
|                 <div class="table-left__wrapper--right">
 | ||
|                   <el-tooltip class="item" effect="dark" :content="row.content" placement="top">
 | ||
|                     <div v-if="row.msgtype != 'news'">
 | ||
|                       {{ row.content }}
 | ||
|                     </div>
 | ||
|                   </el-tooltip>
 | ||
|                 </div>
 | ||
|               </div>
 | ||
|             </template>
 | ||
|           </el-table-column>
 | ||
| 
 | ||
|           <!-- 操作 -->
 | ||
|           <el-table-column slot="options" label="操作" align="center" fixed="right" width="200">
 | ||
|             <template slot-scope="{ row }">
 | ||
|               <div class="table-options">
 | ||
|                 <ai-wechat-selecter style="display:inline-block;margin-right:8px ;" v-if="row.status == 1" :instance="instance" @change="(h) => release(h, row)">
 | ||
|                   <el-button type="text">发送</el-button>
 | ||
|                 </ai-wechat-selecter>
 | ||
| 
 | ||
|                 <el-button type="text" @click="remove(row.id)">删除</el-button>
 | ||
|                 <el-button type="text" @click="toEdit(row)">编辑</el-button>
 | ||
|                 <el-button type="text" @click="toDetail(row.id)">详情</el-button>
 | ||
|               </div>
 | ||
|             </template>
 | ||
|           </el-table-column>
 | ||
|         </ai-table>
 | ||
|       </template>
 | ||
|     </ai-list>
 | ||
| 
 | ||
|     <!-- 新增的弹窗 -->
 | ||
|     <ai-dialog :title="dialog.title" :visible.sync="visible" @onCancel="onCancel" @onConfirm="addConfirm" width="800px">
 | ||
|       <div class="form_div">
 | ||
|         <el-form ref="ruleForm" :model="dialogInfo" :rules="formRules" size="small" label-suffix=":" label-width="100px">
 | ||
|           <!-- 新增名称 -->
 | ||
|           <el-form-item label="名称" prop="name">
 | ||
|             <el-input clearable placeholder="请输入名称" v-model="dialogInfo.name" show-word-limit :maxlength="128"></el-input>
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <!-- 新增状态 -->
 | ||
|           <el-form-item label="状态" prop="status">
 | ||
|             <ai-select v-model="dialogInfo.status" placeholder="请选择状态" :selectList="$dict.getDict('wxAppMsgTemplateStatus')"></ai-select>
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <!-- 新增消息类型 -->
 | ||
|           <el-form-item label="消息类型" prop="msgtype">
 | ||
|             <el-radio-group v-model="dialogInfo.msgtype" @change="onChange">
 | ||
|               <el-radio :label="item.label" v-for="(item, index) in types" :key="index">{{ item.name }}</el-radio>
 | ||
|             </el-radio-group>
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <!-- 新增图片 -->
 | ||
|           <el-form-item :label="compLabel" prop="sysFileId" v-if="dialogInfo.msgtype == 'image' || dialogInfo.msgtype == 'video' || dialogInfo.msgtype == 'voice' || dialogInfo.msgtype == 'news'">
 | ||
|             <ai-uploader :instance="instance" v-model="fileList" :acceptType="acceptType" :url="'/app/wxcp/upload/uploadFile?type=' + fileTypeList" isWechat :fileType="fileType" :limit="1"></ai-uploader>
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <!-- 新增消息类型对应的消息内容 -->
 | ||
|           <el-form-item label="消息内容" prop="content" v-if="dialogInfo.msgtype == 'text'">
 | ||
|             <el-input type="textarea" placeholder="请输入消息内容" :maxlength="2048" show-word-limit v-model="dialogInfo.content"> </el-input>
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <!-- 新增标题 -->
 | ||
|           <el-form-item label="标题" prop="title" v-if="dialogInfo.msgtype != 'text' && dialogInfo.msgtype != 'image' && dialogInfo.msgtype != 'voice'">
 | ||
|             <el-input clearable placeholder="请输入标题" v-model="dialogInfo.title" show-word-limit :maxlength="128"></el-input>
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <!-- 新增文件描述 -->
 | ||
|           <el-form-item label="文件描述" prop="description" v-if="dialogInfo.msgtype != 'text' && dialogInfo.msgtype != 'image' && dialogInfo.msgtype != 'voice'">
 | ||
|             <el-input clearable placeholder="请输入文件描述" v-model="dialogInfo.description" show-word-limit :maxlength="512" />
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <!-- 新增跳转地址 -->
 | ||
|           <el-form-item label="跳转地址" prop="url" v-if="dialogInfo.msgtype == 'news' || dialogInfo.msgtype == 'textcard'">
 | ||
|             <el-input clearable placeholder="请输入要跳转的链接地址http/https" v-model="dialogInfo.url" show-word-limit :maxlength="128" />
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <!-- 新增图片链接 -->
 | ||
|           <el-form-item label="图片链接" prop="picurl" v-if="dialogInfo.msgtype != 'text' && dialogInfo.msgtype != 'video' && dialogInfo.msgtype != 'textcard' && dialogInfo.msgtype != 'voice' && dialogInfo.msgtype != 'image'">
 | ||
|             <el-input clearable placeholder="请输入图片链接" v-model="dialogInfo.picurl" show-word-limit :maxlength="128" />
 | ||
|           </el-form-item>
 | ||
|         </el-form>
 | ||
|       </div>
 | ||
| 
 | ||
|       <div class="dialog-footer" slot="footer">
 | ||
|         <el-button @click="onCancel" size="medium">取消</el-button>
 | ||
|         <el-button @click="onConfirm('ruleForm')" type="primary" size="medium">确认</el-button>
 | ||
|       </div>
 | ||
|     </ai-dialog>
 | ||
|   </section>
 | ||
| </template>
 | ||
| 
 | ||
| <script>
 | ||
| export default {
 | ||
|   name: 'commonList',
 | ||
|   props: {
 | ||
|     instance: Function,
 | ||
|     dict: Object,
 | ||
|   },
 | ||
| 
 | ||
|   data() {
 | ||
|     var checkAge = (rule, value, callback) => {
 | ||
|       if (this.dialogInfo.msgtype == 'image' && this.fileList.length == 0) {
 | ||
|         return callback(new Error('请上传图片'))
 | ||
|       } else if (this.dialogInfo.msgtype == 'file' && this.fileList.length == 0) {
 | ||
|         return callback(new Error('请上传文件'))
 | ||
|       } else if (this.dialogInfo.msgtype == 'video' && this.fileList.length == 0) {
 | ||
|         return callback(new Error('请上传视频'))
 | ||
|       } else if (this.dialogInfo.msgtype == 'voice' && this.fileList.length == 0) {
 | ||
|         return callback(new Error('请上传音频'))
 | ||
|       } else if (this.dialogInfo.msgtype == 'news' && this.fileList.length == 0) {
 | ||
|         return callback(new Error('请上传图片'))
 | ||
|       } else {
 | ||
|         callback()
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     return {
 | ||
|       visible: false,
 | ||
|       total: 10,
 | ||
|       colConfigs: [
 | ||
|         {
 | ||
|           prop: 'name',
 | ||
|           label: '名称',
 | ||
|         },
 | ||
|         {
 | ||
|           slot: 'msgtype',
 | ||
|           label: '类型',
 | ||
|         },
 | ||
|         // {
 | ||
|         //   slot: 'content',
 | ||
|         //   label: '消息内容'
 | ||
|         // },
 | ||
|         // {
 | ||
|         //   prop: 'title',
 | ||
|         //   label: '标题'
 | ||
|         // },
 | ||
|         {
 | ||
|           prop: 'createUserName',
 | ||
|           label: '创建人',
 | ||
|           'show-overflow-tooltip': true,
 | ||
|         },
 | ||
|         { prop: 'createTime', label: '创建时间' },
 | ||
|         {
 | ||
|           prop: 'status',
 | ||
|           label: '状态',
 | ||
|           dict: 'wxAppMsgTemplateStatus',
 | ||
|         },
 | ||
|         { slot: 'options', label: '操作', align: 'center' },
 | ||
|       ],
 | ||
|       tableData: [],
 | ||
|       page: {
 | ||
|         size: 10,
 | ||
|         current: 1,
 | ||
|         total: 0,
 | ||
|       },
 | ||
|       dialog: {
 | ||
|         title: '',
 | ||
|         visible: false,
 | ||
|       },
 | ||
|       dialogInfo: {
 | ||
|         name: '',
 | ||
|         title: '',
 | ||
|         msgtype: 'text',
 | ||
|         content: '',
 | ||
|         createUserName: '',
 | ||
|         createTime: '',
 | ||
|         status: '',
 | ||
|         id: '',
 | ||
|         isSystem: 0,
 | ||
|         mediaId: '',
 | ||
|         sysFileId: '',
 | ||
|         media: {},
 | ||
|         description: '',
 | ||
|         url: '',
 | ||
|         picurl: '',
 | ||
|       },
 | ||
|       fileList: [],
 | ||
|       formRules: {
 | ||
|         name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
 | ||
|         content: [{ required: true, message: '请输入消息内容', trigger: 'blur' }],
 | ||
|         sysFileId: [{ required: true, validator: checkAge, trigger: 'change' }],
 | ||
|         title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
 | ||
|         description: [{ required: true, message: '请输入文件描述或链接', trigger: 'blur' }],
 | ||
|         url: [
 | ||
|           {
 | ||
|             required: true,
 | ||
|             message: '请输入要跳转的链接地址http/https',
 | ||
|             trigger: 'blur',
 | ||
|           },
 | ||
|         ],
 | ||
|         picurl: [{ required: true, message: '请输入图片链接', trigger: 'blur' }],
 | ||
|         status: [{ required: true, message: '请选择状态', trigger: 'blur' }],
 | ||
|       },
 | ||
|     }
 | ||
|   },
 | ||
|   computed: {
 | ||
|     types() {
 | ||
|       return [
 | ||
|         { name: '文本', label: 'text' },
 | ||
|         { name: '图片', label: 'image' },
 | ||
|         { name: '视频', label: 'video' },
 | ||
|         // { name: '附件', label: 'file' },
 | ||
|         // { name: '音频', label: 'voice' },
 | ||
|         { name: '文本卡片', label: 'textcard' },
 | ||
|         { name: '图文', label: 'news' },
 | ||
|         // { name: '图文消息', label: 'mpnews' }
 | ||
|       ]
 | ||
|     },
 | ||
| 
 | ||
|     compLabel() {
 | ||
|       return this.types.find((e) => e.label == this.dialogInfo.msgtype)?.name
 | ||
|     },
 | ||
|     fileTypeList() {
 | ||
|       var type = ''
 | ||
|       if (this.dialogInfo.msgtype == 'text' || this.dialogInfo.msgtype == 'textcard') {
 | ||
|         type = 'text'
 | ||
|       } else if (this.dialogInfo.msgtype == 'image' || this.dialogInfo.msgtype == 'news') {
 | ||
|         type = 'image'
 | ||
|       } else if (this.dialogInfo.msgtype == 'video') {
 | ||
|         type = 'video'
 | ||
|       } else if (this.dialogInfo.msgtype == 'voice') {
 | ||
|         type = 'voice'
 | ||
|       }
 | ||
|       return type
 | ||
|     },
 | ||
|     fileType() {
 | ||
|       // return this.dialogInfo.msgtype == 'image' ? 'img' : 'file'
 | ||
|       var type = ''
 | ||
|       if (this.dialogInfo.msgtype == 'image' || this.dialogInfo.msgtype == 'news') {
 | ||
|         type = 'img'
 | ||
|       } else {
 | ||
|         type = 'file'
 | ||
|       }
 | ||
|       return type
 | ||
|     },
 | ||
|     acceptType() {
 | ||
|       return {
 | ||
|         image: '.jpg,.png,.jpeg',
 | ||
|         video: '.mp4',
 | ||
|         voice: '.AMR', // 无效的设置
 | ||
|       }[this.dialogInfo.msgtype]
 | ||
|     },
 | ||
|   },
 | ||
| 
 | ||
|   created() {
 | ||
|     this.dict.load('wxAppMsgTemplateStatus').then(() => {
 | ||
|       this.getList()
 | ||
|     })
 | ||
|   },
 | ||
| 
 | ||
|   methods: {
 | ||
|     getList() {
 | ||
|       this.instance
 | ||
|         .post(`/app/wxcp/wxapplicationmsgtemplate/list`, null, {
 | ||
|           params: {
 | ||
|             ...this.page,
 | ||
|             isSystem: 0,
 | ||
|           },
 | ||
|         })
 | ||
|         .then((res) => {
 | ||
|           if (res.code == 0) {
 | ||
|             this.tableData = res.data.records
 | ||
|             this.page.total = res.data.total
 | ||
|           }
 | ||
|         })
 | ||
|     },
 | ||
| 
 | ||
|     // 增加按钮
 | ||
|     showAdd() {
 | ||
|       this.dialog.title = '添加'
 | ||
|       this.dialogInfo.msgtype = 'text'
 | ||
|       this.visible = true
 | ||
|       this.getList()
 | ||
|     },
 | ||
| 
 | ||
|     // 确定增加
 | ||
|     addConfirm() {
 | ||
|       var media = null
 | ||
|       if (this.dialogInfo.msgtype != 'text' && this.fileList.length) {
 | ||
|         media = {
 | ||
|           mediaId: this.fileList[0].media.mediaId,
 | ||
|           createdAt: this.fileList[0].media.createdAt,
 | ||
|           sysFileId: this.fileList[0].id,
 | ||
|           type: this.dialogInfo.msgtype,
 | ||
|           url: this.fileList[0].url,
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       this.$refs['ruleForm'].validate((valid) => {
 | ||
|         if (valid) {
 | ||
|           this.instance
 | ||
|             .post(`/app/wxcp/wxapplicationmsgtemplate/addOrUpdate`, {
 | ||
|               createTime: this.dialogInfo.createTime,
 | ||
|               createUserName: this.dialogInfo.createUserName,
 | ||
|               status: this.dialogInfo.status,
 | ||
|               id: this.dialogInfo.id,
 | ||
|               isSystem: 0,
 | ||
|               msgtype: this.dialogInfo.msgtype,
 | ||
|               // mediaId: this.fileList[0].media.mediaId,
 | ||
|               // sysFileId: this.fileList[0].id
 | ||
|               name: this.dialogInfo.name,
 | ||
|               title: this.dialogInfo.title,
 | ||
|               content: this.dialogInfo.content,
 | ||
|               description: this.dialogInfo.description,
 | ||
|               url: this.dialogInfo.url,
 | ||
|               picurl: this.dialogInfo.picurl,
 | ||
|               media,
 | ||
|             })
 | ||
|             .then((res) => {
 | ||
|               if (res.code == 0) {
 | ||
|                 this.$message.success('操作成功')
 | ||
|                 this.getList()
 | ||
|                 this.visible = false
 | ||
|                 this.infoInit()
 | ||
|               }
 | ||
|             })
 | ||
|             .catch((err) => {})
 | ||
|         }
 | ||
|       })
 | ||
|     },
 | ||
| 
 | ||
|     // 新增完成后初始化页面
 | ||
|     infoInit() {
 | ||
|       for (let key in this.dialogInfo) {
 | ||
|         this.dialogInfo[key] = ''
 | ||
|       }
 | ||
|       this.dialogInfo.msgtype = 'text'
 | ||
|       this.dialogInfo.media = {}
 | ||
|       this.dialogInfo.isSystem = '0'
 | ||
|       this.fileList = []
 | ||
|     },
 | ||
| 
 | ||
|     // 删除
 | ||
|     remove(id) {
 | ||
|       this.$confirm('删除后不可恢复,是否要删除该事项?', {
 | ||
|         type: 'error',
 | ||
|       }).then(() => {
 | ||
|         this.instance.post(`/app/wxcp/wxapplicationmsgtemplate/delete?id=${id}`).then((res) => {
 | ||
|           if (res.code == 0) {
 | ||
|             this.$message.success('删除成功!')
 | ||
|             this.getList()
 | ||
|           }
 | ||
|         })
 | ||
|       })
 | ||
|     },
 | ||
| 
 | ||
|     // 编辑
 | ||
|     toEdit(row) {
 | ||
|       const info = JSON.parse(JSON.stringify(row))
 | ||
|       this.dialog.title = '编辑'
 | ||
|       this.visible = true
 | ||
|       this.dialogInfo = { ...info }
 | ||
|       this.fileList = [
 | ||
|         {
 | ||
|           accessUrl: '',
 | ||
|           url: '',
 | ||
|           id: '',
 | ||
|           media: {
 | ||
|             mediaId: '',
 | ||
|             createdAt: '',
 | ||
|             sysFileId: '',
 | ||
|           },
 | ||
|         },
 | ||
|       ]
 | ||
| 
 | ||
|       if (this.dialogInfo.msgtype != 'text' && this.dialogInfo.msgtype != 'textcard') {
 | ||
|         this.dialogInfo.media == info.media
 | ||
| 
 | ||
|         this.fileList[0].accessUrl = info.media.file.accessUrl
 | ||
|         this.fileList[0].url = info.media.file.url
 | ||
|         this.fileList[0].id = info.media.sysFileId
 | ||
| 
 | ||
|         this.fileList[0].media.mediaId = info.media.mediaId
 | ||
|         this.fileList[0].media.createdAt = info.media.createdAt
 | ||
|         this.fileList[0].media.sysFileId = info.media.sysFileId
 | ||
|       }
 | ||
|     },
 | ||
| 
 | ||
|     // 详情
 | ||
|     toDetail(id) {
 | ||
|       this.$emit('change', {
 | ||
|         type: 'detail',
 | ||
|         params: {
 | ||
|           type: 'commonListDetail',
 | ||
|           id: id,
 | ||
|         },
 | ||
|       })
 | ||
|     },
 | ||
| 
 | ||
|     // 发送
 | ||
|     release(person, row) {
 | ||
|       // let typeList = ['templateId', 'toParty', 'toTag']
 | ||
|       // person[0].type==0?'toParty':'templateId'
 | ||
|       let typeList = ['toUser', 'toParty']
 | ||
|       var type = typeList[person[0].type]
 | ||
|       // console.log(type)
 | ||
| 
 | ||
|       // 姓名id
 | ||
|       const nameList = []
 | ||
|       person.map((item) => {
 | ||
|         if (item.type == 0) {
 | ||
|           nameList.push(item.id)
 | ||
|         }
 | ||
|       })
 | ||
|       var toUser = nameList.join('|')
 | ||
|       // console.log(toUser)
 | ||
| 
 | ||
|       // 部门id
 | ||
|       const typesList = []
 | ||
|       person.map((item) => {
 | ||
|         if (item.type == 1) {
 | ||
|           typesList.push(item.name)
 | ||
|         }
 | ||
|       })
 | ||
|       var typeType = typesList.join('|')
 | ||
|       // console.log(typeType)
 | ||
| 
 | ||
|       this.instance
 | ||
|         .post('/app/wxcp/wxapplicationmsgtemplate/sendByTemplate', {
 | ||
|           type: typesList.join('|'), // 部门id,如果只发送给个人,则此处为空
 | ||
|           toUser: nameList.join('|'),
 | ||
|           templateId: row.id,
 | ||
|         })
 | ||
|         .then((res) => {
 | ||
|           if (res?.code == 0) {
 | ||
|             this.$message.success('发送成功!')
 | ||
|             this.getList()
 | ||
|           }
 | ||
|         })
 | ||
|     },
 | ||
| 
 | ||
|     // radio多选框切换
 | ||
|     onChange() {
 | ||
|       this.$refs['ruleForm'].clearValidate()
 | ||
|       this.dialogInfo.name = ''
 | ||
|       this.dialogInfo.content = ''
 | ||
|       this.dialogInfo.title = ''
 | ||
|       this.dialogInfo.description = ''
 | ||
|       this.dialogInfo.url = ''
 | ||
|       this.dialogInfo.picurl = ''
 | ||
|       this.dialogInfo.status = ''
 | ||
|       this.fileList = []
 | ||
|     },
 | ||
| 
 | ||
|     // 新增弹窗的取消按钮
 | ||
|     onCancel() {
 | ||
|       this.dialogInfo.name = ''
 | ||
|       this.dialogInfo.content = ''
 | ||
|       this.dialogInfo.title = ''
 | ||
|       this.dialogInfo.description = ''
 | ||
|       this.dialogInfo.url = ''
 | ||
|       this.dialogInfo.picurl = ''
 | ||
|       this.dialogInfo.status = ''
 | ||
|       this.fileList = []
 | ||
|     },
 | ||
|   },
 | ||
| }
 | ||
| </script>
 | ||
| 
 | ||
| <style lang="scss">
 | ||
| .commonList {
 | ||
|   // overflow: hidden;
 | ||
|   // white-space: nowrap;
 | ||
|   // text-overflow: ellipsis;
 | ||
|   height: 100%;
 | ||
|   background: #f3f6f9;
 | ||
|   ::v-deep.btn {
 | ||
|     margin-bottom: 10px;
 | ||
|   }
 | ||
|   ::v-deep.cell {
 | ||
|     width: 40px;
 | ||
|     height: 40px;
 | ||
|     ::v-deep.table-left__wrapper {
 | ||
|       ::v-deep .img {
 | ||
|         // object-fit: fill;
 | ||
|         width: 40px;
 | ||
|         height: 40px;
 | ||
|         // vertical-align: middle;
 | ||
|         // box-sizing: content-box;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| </style>
 |