123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 |
- <template>
- <div class="create-wrap">
- <!-- S 返回 -->
- <div class="backBox" @click="$router.go(-1)">
- <div class="back">
- <i class="el-icon-back" />
- <span>返回</span>
- </div>
- </div>
- <!-- E 返回 -->
- <!-- S 表单内容 -->
- <div v-loading="loading" class="bg-ffffff createMassMsg" style="padding: 15px 30px;">
- <!-- S 基础信息 -->
- <h3 class="bigTitle">基础信息</h3>
- <div class="regulations">
- <label><em>*</em>渠道名称</label>
- <el-input
- v-model.trim="groupForm.name"
- placeholder="请输入渠道名称"
- style="width:300px"
- maxlength="32"
- size="small"
- show-word-limit
- clearable
- />
- </div>
- <div class="regulations" style="align-items: center">
- <label><em style="opacity: 0;">*</em>选择分组</label>
- <el-select
- v-model="groupForm.group_id"
- size="small"
- clearable
- filterable
- placeholder="请选择分组"
- style="width: 300px"
- >
- <el-option v-for="item in groupOptions" :key="item.id" :label="item.name" :value="item.id" />
- </el-select>
- <div class="newGroupCss" @click="$refs.dialogGroupRef.dialogVisible = true">新建分组</div>
- </div>
- <div class="regulations">
- <label><em>*</em>选择群聊</label>
- <chatGroupOptions
- ref="chatGroupOptions"
- style="margin: 0;"
- width="300px"
- :chatListResult="groupForm.chat_id_list"
- @change="onChangeChatGroup"
- />
- </div>
- <div class="regulations">
- <label><em style="opacity: 0;">*</em>进群方式</label>
- <el-radio-group v-model="groupForm.join_type">
- <el-radio :label="1">顺序进群</el-radio>
- <el-radio :label="2">随机进群</el-radio>
- </el-radio-group>
- </div>
- <div class="regulations" style="align-items: center">
- <label>渠道群管理</label>
- <div @click="handleShowLimitTips" class="limitBox">
- <el-switch
- v-model="groupForm.is_limit"
- :disabled="!groupForm.chat_id_list.length"
- active-color="#13ce66"
- inactive-color="#ddd"
- :active-value="1"
- :inactive-value="0"
- @change="onChangeSwitchLimit"
- />
- </div>
- </div>
- <!-- S 群管理表格 开启"渠道群管理"时显示 -->
- <div v-show="groupForm.is_limit" class="listBox">
- <el-table border :data="groupForm.chat_id_list" tooltip-effect="dark" :header-cell-style="()=>{return { backgroundColor: '#f9f9f9 !important' }}" style="width: 100%">
- <el-table-column label="拖拽排序" width="80" align="center">
- <template slot-scope="{ row }">
- <div class="drag-handler">
- <i class="el-icon-rank" />
- </div>
- </template>
- </el-table-column>
- <el-table-column label="群名称" align="center" prop="name" />
- <el-table-column label="人数上限" align="center">
- <template slot="header" slot-scope="scope">
- <em style="color: #ff0000;">*</em>人数上限
- </template>
- <template slot-scope="{ row }">
- <el-input size="mini" v-model="row.user_limit" />
- </template>
- </el-table-column>
- <el-table-column label="状态" align="center">
- <template slot-scope="{ row }">
- <el-switch
- v-model="row.status"
- :active-value="1"
- :inactive-value="0"
- active-color="#13ce66"
- inactive-color="#ddd"
- />
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" width="80px">
- <template slot-scope="{ row, $index }">
- <div class="c-00B38A pointer lMar8" @click="onClickDelChat(row, $index)">删除</div>
- </template>
- </el-table-column>
- </el-table>
- </div><!-- E 群管理表格 -->
- <!-- E 基础信息 -->
- <!-- S 客服设置 -->
- <div class="line" style="margin-top:20px"></div>
- <h3 class="bigTitle">客服设置</h3>
- <div class="regulations" style="align-items: center">
- <label><em>*</em>生效成员</label>
- <self-customerservice
- title=''
- width="300px"
- source="channelCode"
- ref="selfKefu"
- style="margin:0;"
- :afferent_users="groupForm.user_list"
- @customerDefine="onChangeUserList"
- />
- <div class="user-tips">当客户点击客服时,会引导客户随机添加一名客服成员的企业微信</div>
- </div>
- <div class="regulations">
- <label><em>*</em>引导话术</label>
- <el-input
- v-model.trim="groupForm.leading_words"
- placeholder="请输入引导话术"
- style="width:300px"
- maxlength="20"
- size="small"
- show-word-limit
- clearable
- />
- </div>
- <!-- E 客服设置 -->
- <!-- S 按钮 -->
- <div class="line" style="margin-top:20px" />
- <div style="margin-top: 20px"><el-button type="primary" @click="onClickSave">保存</el-button></div>
- <!-- E 按钮 -->
- </div>
- <!-- E 表单内容 -->
- <!-- S 新建分组 - 弹框 -->
- <dialogGroup
- ref="dialogGroupRef"
- :propsData="{ dialogTitle:'新建' }"
- @init="handleGetGroupOptions"
- />
- <!-- E 新建分组 - 弹框 -->
- </div>
- </template>
- <script>
- import dialogGroup from './components/dialogGroup.vue'
- import chatGroupOptions from './components/chatGroupOptions.vue'
- import selfCustomerservice from '@/components/assembly/screen/customerService.vue'
- import Sortable from 'sortablejs'
- import _lodash from 'lodash'
- export default {
- name: "createGroupCode",
- components: {
- dialogGroup,
- chatGroupOptions,
- selfCustomerservice,
- },
- data() {
- return {
- loading: false,
- groupOptions: [], // 分组选项
- groupForm: {
- name: '', // 渠道名称
- group_id: '', // 分组id
- chat_id_list: [], // 客户群列表
- join_type: 1, // 进群方式
- is_limit: 0, // 渠道群管理(是否设置群上限)
- user_list: [], // 客服(生效成员) 数组回显 'a,b' => ['a', 'b']
- leading_words: '', // 引导话术
- },
- rule_id: this.$route.query.id || '', // 群活码id
- detailFromApi: Object.freeze({}), // 后端返回的详情完整数据
- }
- },
- computed: {
- // 当前操作是否为"编辑"
- isEdit() {
- const { id = '', type = '' } = this.$route.query
- return id && type === 'edit'
- },
- // 当前操作是否为"复制"
- isCopy() {
- const { id = '', type = '' } = this.$route.query
- return id && type === 'copy'
- },
- },
- created() {
- // 获取分组列表
- this.handleGetGroupOptions()
- // 编辑、复制 => 获取群活码详情
- if (this.isEdit || this.isCopy) {
- this.handleGetDetail()
- }
- },
- mounted() {
- // 表格行拖拽
- this.handleRowDrop()
- },
- methods: {
- // 获取群活码详情数据
- async handleGetDetail() {
- try {
- this.loading = true
- const { data: res = {} } = await this.$axios.get(this.URL.BASEURL + this.URL.groupCode_ruleDetail, {
- params: { rule_id: this.rule_id }
- })
- if (res && res.errno == 0) {
- const { rst = {} } = res
- // 备份接口数据
- this.detailFromApi = Object.freeze(_lodash.cloneDeep(rst))
- // 回显数据
- this.setGroupFormData(rst)
- } else if (res.errno != 4002) {
- this.$message.warning(res.err)
- this.$router.go(-1)
- }
- } catch (error) {
- console.log('error => ', error)
- this.loading = false
- } finally {
- // this.loading = false
- }
- },
- // 回显详情数据
- async setGroupFormData(detail) {
- try {
- // 基础属性回显
- const keys = ['name', 'group_id', 'chat_id_list', 'join_type', 'is_limit', 'leading_words']
- keys.forEach(k => {
- this.groupForm[k] = detail[k]
- })
- // 回显生效成员
- this.groupForm.user_list = detail.user_list.split(',')
- await this.$nextTick()
- this.$refs.selfKefu && this.$refs.selfKefu.handleCreatedFn()
- // 回显群聊列表"群名称"
- const { data: res = {} } = await this.$axios.get(this.URL.BASEURL + this.URL.groupCode_chatGroupList, {
- params: { keyword: '' }
- })
- if (res && res.errno == 0 && Array.isArray(res.rst)) {
- detail.chat_id_list.forEach((item, idx) => {
- const isFound = res.rst.find(chat => chat.chat_id === item.chat_id)
- if (isFound) detail.chat_id_list[idx].name = isFound.name
- })
- this.groupForm.chat_id_list = [...detail.chat_id_list]
- }
- } catch (error) {
- console.log('error => ', error)
- } finally {
- this.loading = false
- }
- },
- // 注册表格行拖拽事件
- handleRowDrop() {
- const tbody = document.querySelector('.el-table__body-wrapper tbody')
- const _this = this
- Sortable.create(tbody, {
- handle: '.drag-handler',
- onEnd({ newIndex, oldIndex }) {
- if (newIndex == oldIndex) return
- _this.groupForm.chat_id_list.splice(
- newIndex,
- 0,
- _this.groupForm.chat_id_list.splice(oldIndex, 1)[0]
- )
- const newArray = _this.groupForm.chat_id_list.slice(0)
- _this.groupForm.chat_id_list = []
- _this.$nextTick(() => {
- _this.groupForm.chat_id_list = newArray
- _this.$refs.chatGroupOptions.chatListSelected = [] // 重置群聊组件"已选列表"
- })
- }
- })
- },
- // 点击保存按钮
- async onClickSave() {
- console.log('onClickSave this.groupForm => ', JSON.parse(JSON.stringify(this.groupForm)))
- try {
- // 表单判空校验
- await this.handleFormValidate()
- // 获取请求地址 & 参数
- const { url, params } = this.handleGetParams()
- console.log('params => ', JSON.parse(JSON.stringify(params)))
- console.log('url => ', url)
- this.loading = true
- const { data: res } = await this.$axios.post(url, params)
- console.log('res => ', res)
- if (res && res.errno == 0) {
- this.$message.success('保存成功')
- this.$router.go(-1)
- } else if (res.errno != 4002) {
- this.$message.warning(res.err || '操作失败')
- }
- } catch (error) {
- console.log('error => ', error)
- } finally {
- this.loading = false
- }
- },
- // 表单校验
- handleFormValidate() {
- const { name, chat_id_list, is_limit, user_list, leading_words } = this.groupForm
- const isEmpty = chat_id_list.some(chat => Number(chat.user_limit) === 0)
- return new Promise((resolve, reject) => {
- if (!name) {
- this.$message.warning('请输入渠道名称')
- reject('表单校验未通过')
- } else if (!chat_id_list.length) {
- this.$message.warning('请选择群聊')
- reject('表单校验未通过')
- } else if (is_limit === 1 && isEmpty) {
- this.$message.warning('请输入人数上限')
- reject('表单校验未通过')
- } else if (!user_list.length) {
- this.$message.warning('请选择生效成员')
- reject('表单校验未通过')
- } else if (!leading_words) {
- this.$message.warning('请输入引导话术')
- reject('表单校验未通过')
- } else {
- resolve('表单校验通过')
- }
- })
- },
- // 整理请求参数
- handleGetParams() {
- const url = `${this.URL.BASEURL}${this.URL[this.isEdit ? 'groupCode_editRule' : 'groupCode_setRule']}`
- const { name, group_id, join_type, is_limit, user_list, leading_words, chat_id_list } = this.groupForm
- // 删除后端返回的 sort 属性
- const chatIdList = chat_id_list.map(c => {
- delete c.sort
- return {...c}
- })
- const params = {
- name,
- group_id,
- join_type,
- is_limit,
- user_list: user_list.join(','),
- leading_words,
- }
- if (this.isEdit) {
- params.rule_id = this.rule_id
- params.config_id = this.detailFromApi.config_id
- // 接口返回的原始数据 与 页面显示的数据比对
- this.detailFromApi.chat_id_list.forEach((item, idx) => {
- const isFound = chatIdList.find(c => c.chat_id === item.chat_id)
- // 如果原始数据 在页面中"没"找到 => 证明"已删除"
- if (!isFound) {
- item.enable = 0 // 参数写为0 并追加到数组末
- chatIdList.push(item)
- }
- })
- }
- params.chat_id_list = JSON.stringify(chatIdList)
- return { url, params }
- },
- // 获取分组列表
- async handleGetGroupOptions() {
- const { data: res = {} } = await this.$axios.get(this.URL.BASEURL + this.URL.channel_groupList, {
- params: {
- type: 2, // 1:渠道活码 2:群活码
- page: 1,
- pagesize: 500,
- }
- })
- if (res && res.errno == 0) {
- this.groupOptions = res.rst.data
- } else if (res.errno != 4002) {
- this.$message.warning(res.err)
- }
- },
- // 渠道群管理提示
- handleShowLimitTips() {
- if (!this.groupForm.chat_id_list.length) {
- this.$message.error('请先选择群聊')
- }
- },
- onChangeSwitchLimit(){
- if (!this.groupForm.chat_id_list.length) {
- this.$message.error('请先选择群聊')
- return
- }
- },
- // 渠道群管理列表 - 删除
- onClickDelChat(row, idx) {
- this.groupForm.chat_id_list.splice(idx, 1)
- this.$refs.chatGroupOptions.chatListSelected = [] // 重置群聊组件"已选列表"
- // 列表为空 => 关闭"渠道群管理"按钮
- if (!this.groupForm.chat_id_list.length) {
- this.groupForm.is_limit = 0
- }
- },
- // 监听"选择客服"(生效成员)变化
- onChangeUserList(val) {
- this.groupForm.user_list = Array.isArray(val) && val.length ? val : []
- },
- // 监听"选择群聊"变化
- onChangeChatGroup(selectedChat) {
- const { chat_id_list: currentChats } = this.groupForm
- // 整理数据结构 => 初始化新选择的群聊数据
- const newChats = selectedChat.map(s => ({
- chat_id: s.chat_id,
- name: s.name,
- user_limit: 0,
- enable: 1,
- status: 1,
- }))
- // 在"当前页面的群聊列表"中查找是否已存在 => 去重后得到当前页面新群聊列表
- newChats.forEach((newChat, idx) => {
- const isFoundChat = currentChats.find(c => newChat.chat_id === c.chat_id)
- if (isFoundChat) newChats.splice(idx, 1, isFoundChat)
- })
- this.groupForm.chat_id_list = [...newChats]
- console.log('this.groupForm.chat_id_list => ', this.groupForm.chat_id_list)
- },
- },
- }
- </script>
- <style lang="scss">
- .appendOnly{
- .el-input-group__append{
- padding: 0 20px;
- }
- }
- .limitBox{
- .el-switch.is-disabled .el-switch__core{
- cursor: pointer;
- }
- }
- </style>
- <style lang="scss" scoped>
- .backBox {
- background: #ffffff;
- padding: 15px;
- margin-bottom: 10px;
- .back {
- font-size: 16px;
- font-weight: bold;
- color: #333333;
- cursor: pointer;
- display: inline-block;
- }
- }
- .bigTitle {
- color: #333333;
- font-size: 16px;
- line-height: 22px;
- font-weight: bold;
- }
- .createMassMsg{
- width: 100%;
- min-height: 400px;
- .line {
- width: 730px;
- height: 1px;
- background: #e9e9e9;
- margin: 40px 0 20px;
- }
- .regulations {
- display: flex;
- align-items: flex-start;
- margin-top: 28px;
- label {
- width: 100px;
- color: #333333;
- font-size: 14px;
- line-height: 28px;
- em {
- color: #ff0000;
- }
- }
- .user-tips {
- color: #AAAAAA;
- font-size: 13px;
- margin-left: 20px;
- }
- }
- .regulations2 {
- label {
- width: 70px;
- line-height: 30px;
- }
- }
- }
- .detail_status{
- line-height: 30px;
- height: 30px;
- padding: 3px 10px;
- border-radius: 21px;
- font-size: 12px;
- margin-left: 20px;
- }
- .status_wait{
- background: #FFF2ED;
- border: 1px solid #FF864F;
- color: #FF864F;
- }
- .status_del{
- background: #FFF5F5;
- border: 1px solid #FF604D;
- color: #FF604D;
- }
- .status_fail{
- background: #F4F4F4;
- border: 1px solid #ADADAD;
- color: #ADADAD;
- }
- .status_ing{
- background: #F4FAFF;
- border: 1px solid #007AFE;
- color: #007AFE;
- }
- .status_success{
- background: #EEFFF3;
- border: 1px solid #00B38A;
- color: #00B38A;
- }
- .splitLine {
- width: 100%;
- height: 10px;
- background: #f5f6f8;
- }
- .listBox{
- margin-left: 90px;
- width: 730px;
- margin-top: 10px;
- background-color: #fbfbfb;
- padding: 10px;
- }
- .newGroupCss{
- color: #00b38a;
- font-size: 14px;
- margin-left: 10px;
- cursor: pointer;
- }
- .add_welcom_hint {
- color: #00b38a;
- font-size: 16px;
- font-weight: bold;
- margin-left: 90px;
- margin-top: 10px;
- margin-bottom: 20px;
- cursor: pointer;
- display: inline-block;
- }
- .drag-handler {
- cursor: move;
- }
- </style>
|