| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969 |
- <template>
- <div class="app-container">
-
- <div v-if="opType == 0" style="margin: 30px;"> 添加自动化任务</div>
- <div v-else-if="opType == 1" style="margin: 30px;"> 修改自动化任务</div>
- <div v-else style="margin: 30px;"> 查看自动化任务</div>
- <div style="margin-top: 10px;margin-left: 50px;margin-right: 100px;margin-bottom: 30px;">
- <el-form ref="form" :model="form" :rules="rules" label-width="100px">
- <el-form-item label="规则名称" prop="name">
- <el-input v-model="form.name" placeholder="请输入规则名称" />
- </el-form-item>
- <el-form-item label="状态" prop="status">
- <dict-tag :options="statusOptions" :value="form.status"></dict-tag>
- </el-form-item>
- <el-form-item label="筛选方式" prop="filterMode">
- <el-radio-group v-model="form.filterMode">
- <el-radio :label="1">标签
- </el-radio>
- <el-radio :label="2" v-show="false">群聊
- </el-radio>
- </el-radio-group>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;" v-if="form.filterMode == 1">
- <i class="el-icon-info"></i>
- 标签:根据客户的标签筛选客户进入自动化
- </div>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;" v-if="form.filterMode == 2">
- <i class="el-icon-info"></i>
- 群聊:选择用户所属的群聊,并且只能选择科普模板,科普模板里面第一条规则是发送到群聊,其他规则提醒会发送到群里面的个人
- </div>
- </el-form-item>
-
- <el-form-item label="次要节点天数" prop="minConversionDay" v-if="/*form.type != 3 && */form.filterMode == 1">
- <!-- <el-input-number v-model="form.minConversionDay" :min="1" :max="100"></el-input-number> -->
- <el-input style="width: 220px;" v-model="form.minConversionDay" placeholder="请输入次要节点天数" />
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 第一次提醒客服,去联系客户,在【提醒看板】处显示,哪些需要联系的客户,多个使用英文逗号隔开
- </div>
- </el-form-item>
- <el-form-item label="重要节点天数" prop="maxConversionDay" v-if="/*form.type != 3 && */form.filterMode == 1">
- <el-input style="width: 220px;" v-model="form.maxConversionDay" placeholder="请输入重要节点天数" />
- <!-- <el-input-number v-model="form.maxConversionDay" :min="1" :max="100"></el-input-number> -->
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 第二次提醒客服,去联系客户,在【提醒看板】处显示,哪些需要联系的客户,多个使用英文逗号隔开
- </div>
- </el-form-item>
- <div v-if="form.filterMode == 1">
- <el-form-item label="推送方式 ">
- <el-radio-group v-model="form.sendType" @input="handleSendTypeChange">
- <el-radio v-for="dict in sopSendTypeOptions" :key="dict.dictValue"
- :label="parseInt(dict.dictValue)">{{ dict.dictLabel }}</el-radio>
- </el-radio-group>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 群发助手 则是正常的自动化任务,新客对话 是客户进线当天,根据【新客对话模板】的内容,给客户发送相应的消息
- </div>
- </el-form-item>
- <el-form-item label="选择客服" prop="appCustomerId" style="margin-top: 2%">
- <div>
- <el-button size="medium" icon="el-icon-circle-plus-outline" plain
- @click="openSelectCustomerPage(form.type, form.sendType)">请选择客服</el-button>
- </div>
- <div>
- <el-tag style="margin-left: 5px" size="medium" :key="s.id" v-for="s in selected" closable
- :disable-transitions="false" @close="handleCloseCustomer(s)">
- <span>{{ s.roleName }}</span>
- </el-tag>
- </div>
- </el-form-item>
- <el-form-item label="标签规则" prop="filterType">
- <el-radio-group v-model="form.filterType">
- <el-radio :label="1">含全部标签</el-radio>
- <el-radio :label="2">含任意标签</el-radio>
- </el-radio-group>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 【含全部标签】:客户要完全一对一匹配上选择标签,ps:多一个少一个都不行
- 【含任意标签】:客户只要有一个标签匹配上即可
- </div>
- </el-form-item>
- <el-form-item label="选择的标签" prop="tags">
- <div @click="hangleChangeTags()"
- style="cursor: pointer; border: 1px solid #e6e6e6; background-color: white; overflow: hidden; flex-grow: 1;width: 390px">
- <div style="min-height: 35px; max-height: 200px; overflow-y: auto;">
- <el-tag type="success" closable :disable-transitions="false"
- v-for="list in selectTagDialog.selected" :key="list.id" @close="handleCloseTags(list)"
- style="margin: 3px;">{{ list.name }}
- </el-tag>
- </div>
- </div>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 选择创建的自动化任务的标签
- </div>
- </el-form-item>
- </div>
- <el-form-item label="开始时间" prop="startTime">
- <el-date-picker clearable size="small" v-model="form.startTime" type="date" value-format="yyyy-MM-dd"
- placeholder="选择开始时间" @change="clearAutoDatesIfNeeded">
- </el-date-picker>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 任务的开始时间,客户进线在开始时间之前就符合此自动化任务的,都会进入到开始时间的营期里
- </div>
- </el-form-item>
- <el-form-item label="任务过期时间" prop="expiryTime">
- <el-row>
- <el-input-number v-model="form.expiryTime" :min="3" :max="100"></el-input-number>
- (小时)
- </el-row>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 发送自动化任务消息的过期时间,超过这个时间,消息将不再发送(作废),比如:9点的消息,设置3个小时过期,12点之后还未发送 则这条消息将过期且不再发送
- </div>
- </el-form-item>
- <el-form-item v-if="form.sendType == 2 && form.sendType != 4 && form.type != 3 && form.filterMode == 1"
- label="自动添加自动化" prop="autoSopTime.autoSopType">
- <el-radio-group v-model="form.autoSopTime.autoSopType">
- <el-radio :label="Number(dict.dictValue)" v-for="dict in autoSopTypeOptions">{{ dict.dictLabel }}</el-radio>
- </el-radio-group>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 这个选项仅作用于【新客户】进线时或【给客户打标签时】,是进入当日的营期 还是 次日的营期或者分营期
- </div>
- </el-form-item>
- <div style="display: flex; align-items: center; flex-wrap: nowrap;">
- <div v-if="form.autoSopTime.autoSopType == 1 && form.filterMode == 1"
- style="display: flex; align-items: center">
- <el-form-item label="起始时间" prop="autoStartTime" label-width="100px"
- style="margin: 2% 0;align-items: center;">
- <el-time-select style="width: 120px;" placeholder="起始时间" v-model="form.autoSopTime.autoStartTime"
- :picker-options="{
- start: '00:00',
- step: '00:15',
- end: '24:00'
- }">
- </el-time-select>
- </el-form-item>
- <el-form-item label="结束时间" prop="autoEndTime" label-width="100px"
- style="margin: 2% 0; align-items: center; ">
- <el-time-select style="width: 120px;" placeholder="结束时间" v-model="form.autoSopTime.autoEndTime"
- :picker-options="{
- start: '00:00',
- step: '00:15',
- end: '24:00',
- minTime: form.autoSopTime.autoEndTime
- }">
- </el-time-select>
- </el-form-item>
- </div>
- </div>
-
- <el-form-item v-if="form.autoSopTime.autoSopType == 1" label="过期消息是否发送" prop="autoSopSend" label-width="130px">
- <el-radio-group v-model="form.autoSopTime.autoSopSend">
- <el-radio :label="1">是</el-radio>
- <el-radio :label="2">否</el-radio>
- </el-radio-group>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 起始时间-结束时间之内的进线客户,进入【当日营期】,时间之外的,进入【次日营期】
- </div>
- </el-form-item>
- <div style="display: flex; align-items: center; flex-wrap: nowrap;"
- v-if="form.autoSopTime.autoSopType == 3 || form.autoSopTime.autoSopType == 4">
- <el-form-item label="选择一个或多个日期" prop="autoDateTime" label-width="150px">
- <el-date-picker size="large" type="dates" style="width: 600px" v-model="form.autoSopTime.autoDateTime"
- value-format="yyyy-MM-dd" placeholder="选择一个或多个日期【ps:请先选择开始时间,不得小于任务开始时间】"
- @change="sortSelectedDates(form.autoSopTime.autoDateTime)" :disabled="!form.startTime">
- </el-date-picker>
- </el-form-item>
- </div>
- <el-form-item label="模板" prop="tempId">
- <div @click="selectListSopTemp(form.sendType)"
- style="cursor: pointer; border: 1px solid #e6e6e6; background-color: white; overflow: hidden; flex-grow: 1;">
- <el-tag v-if="form.tempId" type="success" style="margin: 3px;">
- {{ form.tempName }}
- </el-tag>
- <span v-else style="margin: 3px; color: #999;">请点我选择模板</span>
- </div>
- <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
- <i class="el-icon-info"></i>
- 在左边的菜单【任务模板】板块设置好每天要发送的内容
- </div>
- </el-form-item>
- <el-alert v-if="form.autoSopTime.autoSopType == 3" type="warning" :closable="false" show-icon>
- <template #title>
- <span style="font-size: 23px; line-height: 1.5;">
- 此功能用于正课区分营期,可以选择你想要开始营期的具体时间,选择后在此期间添加的用户将会自动进入对应营期。
- 例如今天1月1日,选择时间是1月1日,1月5日,1月10日。
- 用户1月1日-1月4日添加(添加上对应标签)则会进入1月5日的营期,1月5日-1月9日添加则会进入1月10日营期,1月5日自动给用户发送第一节科普
- </span>
- </template>
- </el-alert>
- <el-alert v-if="form.autoSopTime.autoSopType == 4" title="" type="warning" :closable="false" show-icon>
- <template #title>
- <span style="font-size: 23px; line-height: 1.5;">
- 此功能用于先导课区分营期,可以选择先导课开始营期的具体时间,选择后在此期间添加的用户将会自动进入对应营期。
- 例如今天1月1日,选择时间是1月1日,1月5日,1月10日。
- 用户1月1日-1月4日添加(添加上对应标签)则会进入1月1日的营期,1月5日-1月9日添加则会进入1月5日营期,自动给用户匹配上对应应该听到天数的时间节点
- </span>
- </template>
- </el-alert>
- </el-form>
- <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
- <el-button type="primary" v-if="opType != 2" @click="submitForm">确 定</el-button>
- <el-button v-if="opType != 2" @click="cancel">取 消</el-button>
- </div>
- <!-- 选择app客服角色 -->
- <el-dialog :title="customerConfig.title" :visible.sync="customerConfig.visible" width="1300px" append-to-body>
- <CusRoleList
- ref="QwUserList"
- :selected="selected"
- @confirm="customerSelectedConfirmCallForBind"
- @selectionChange="customerSelectionChangeCallForBind"
- />
- </el-dialog>
- <!-- 选择模板 -->
- <el-dialog title="选择模板" :visible.sync="tempOpen" append-to-body>
- <sop-temp ref="SopTempComments" @sopTemp="sopTemp"></sop-temp>
- </el-dialog>
- <!-- 标签 -->
- <el-dialog title="选择标签"
- :visible.sync="selectTagDialog.visible"
- width="1000px"
- append-to-body
- >
- <select-tag
- :tagSelected="selectTagDialog.selected"
- @tagSubmit="tagSubmitForBind"
- @tagCancel="tagCancelForBind"
- @tagSelection="tagSelectionChangeCallForBind"
- />
- </el-dialog>
- </div>
- </div>
- </template>
- <script>
- import {addSop, courseList, updateSop, getSop} from "@/api/app/sop/info";
- import {getList} from "@/api/app/cpsc";
- import {getSopTemp} from '@/api/app/sop/template';
- import CusRoleList from '@/views/app/user/CusRoleList.vue';
- import {listRole} from '@/api/app/user/userList';
- import ImageUpload from "@/views/app/sop/info/ImageUpload";
- import selectTag from "@/views/app/tagGroup/selectTag.vue";
- import { getTagByIds, listTagGroupForUserBindTag as searchTags, } from "@/api/app/tag/tagGroup";
- import SopTemp from "@/views/app/sop/template/sopTemp.vue";
- export default {
- name: "addSop",
- components: { SopTemp, CusRoleList, ImageUpload, selectTag },
- data() {
- return {
- miniAppList: [],
- changeDate: '2025-08-20',
- changeRange: null,
- changeBusy: [
- { startMs: new Date('2025-08-20 12:00').getTime(), endMs: new Date('2025-08-20 13:30').getTime() }
- ],
- autoSopTypeOptions: [],
- //模板遮罩
- tempOpen: false,
- // 选中数组
- ids: [],
- courseList: [],
- tags: null,
- setting: [],
- //标签
- changeTagDialog: {
- title: "",
- open: false,
- type: null,
- },
- //选择的标签
- tagsIdsChangeSelectList: null,
- queryTagParams: {
- pageNum: 1,
- pageSize: 10,
- total: 0,
- name: null,
- },
- // 总条数
- total: 0,
- // 弹出层标题
- title: "",
- // 是否显示弹出层
- open: false,
- // 状态字典
- statusOptions: [],
- //SOP发送类型
- sopSendTypeOptions: [],
- // 表单参数
- form: {
- status: 1,
- filterMode: 1,
- sendType: 2,
- type: 2,
- filterType: 2,
- expiryTime: 3,
- autoGroup: 0,
- isAutoSop: 1,
- tempId: null,
- tempName: null,
- autoSopTime: { autoSopType: 2, autoStartTime: '00:00', autoEndTime: '24:00', autoSopSend: 2, autoDateTime: [] },
- },
- selected: [],
- //选择客服对话框
- customerConfig: {
- title: "",
- visible: false
- },
- // 表单校验
- rules: {
- name: [{ required: true, message: "名称不能为空", trigger: "submit" }],
- type: [{ required: true, message: "不能为空", trigger: "submit" }],
- sendType: [{ required: true, message: "不能为空", trigger: "submit" }],
- startTime: [{ required: true, message: "开始时间不能为空", trigger: "submit" }],
- tempId: [{ required: true, message: "模板不能为空", trigger: "submit" }],
- tags: [
- {
- validator: this.validateGroupLevelOrTags,
- trigger: ["blur", "change"]
- }
- ],
- },
- opType: 0,//操作类型,0-新增(默认),1-编辑,2-查看
- formId: null,
- selectTagDialog: {
- visible: false,
- selected: [],
- },
- };
- },
- created() {
- this.getDicts("app_sop_status").then(response => {
- this.statusOptions = response.data;
- });
- this.getDicts("app_sop_type").then(response => {
- this.sopSendTypeOptions = response.data;
- });
- this.getDicts("app_sop_autoType").then(response => {
- this.autoSopTypeOptions = response.data;
- });
- //操作类型
- let opType = this.$route.params && this.$route.params.type;
- if (opType) {
- this.opType = opType;
- }
- //编辑/查看时有效
- let id = this.$route.params && this.$route.params.id;
- if (id) {
- this.formId = id;
- this.handleUpdate(id);
- }
- courseList().then(response => {
- this.courseList = response.list;
- });
- getList().then(response => {
- });
- },
- watch: {
- selected(newList) {
- this.form.appCustomerId = newList.map(item => item.id);
- }
- },
- methods: {
- validateGroupLevelOrTags(rule, value, callback) {
- // 检查是否是群聊筛选方式且自动创建群为1
- if (this.form.filterMode == 2 && this.form.autoGroup == 1) {
- // 检查评级数组和标签数组是否都为空
- const hasLevel = this.form.autoGroupLevelArray && this.form.autoGroupLevelArray.length > 0;
- const hasTags = this.tagsIdsChangeSelectList && this.tagsIdsChangeSelectList.length > 0;
- if (!hasLevel && !hasTags) {
- callback(new Error('创建群聊评级和企微标签必须至少选择一项'));
- } else {
- callback();
- }
- } else {
- // 如果不满足条件,验证通过
- callback();
- }
- },
- /** 打开子组件的选择器 */
- openPicker() {
- this.$refs.timePicker.openPicker();
- },
- fmt(ms) {
- if (!ms) return "-";
- const d = new Date(ms);
- return d.toLocaleTimeString("zh-CN", { hour12: false });
- },
- /**
- * 取消选择标签
- */
- tagCancel() {
- this.resetSearchQueryTag();
- this.changeTagDialog.open = false;
- },
- /**
- * 选择标签
- */
- hangleChangeTags() {
- this.selectTagDialog.visible = true;
- },
- /**
- * 绑定标签取消
- */
- tagCancelForBind() {
- this.selectTagDialog.visible = false;
- },
- /**
- * 绑定标签确认
- */
- tagSubmitForBind() {
- this.selectTagDialog.visible = false;
- },
- /**
- * 选中的绑定标签列表
- * @param group 标签所属组
- * @param tag 具体操作的标签
- */
- tagSelectionChangeCallForBind(group, tag) {
- if (!tag.isSelected) {
- this.selectTagDialog.selected = this.selectTagDialog.selected.filter(item => tag.id != item.id);
- } else {
- if (!this.selectTagDialog.selected.some(st => st.id == tag.id)) {
- this.selectTagDialog.selected.push(tag);
- }
- }
- },
- /**
- * 删除一些选择的标签
- * @param list
- */
- handleCloseTags(ruleItem) {
- const index = this.selectTagDialog.selected.findIndex(t => t === ruleItem);
- if (index !== -1) {
- this.selectTagDialog.selected.splice(index, 1);
- }
- },
- /**
- * 开始时间发生变化
- */
- clearAutoDatesIfNeeded() {
- if (this.form.autoSopTime.autoDateTime.length > 0 && (this.form.autoSopTime.autoSopType == 3 || this.form.autoSopTime.autoSopType == 4)) {
- // 1. 过滤掉 < startTime 的日期
- const validDates = this.form.autoSopTime.autoDateTime.filter(date => new Date(date) >= new Date(this.form.startTime));
- // 2. 如果有被过滤掉的日期,提示用户
- if (validDates.length < this.form.autoSopTime.autoDateTime.length) {
- this.$message.warning(`已自动移除小于 ${this.form.startTime} 的日期!`);
- }
- // 3. 升序排序
- validDates.sort((a, b) => new Date(a) - new Date(b));
- // 4. 更新数据
- this.form.autoSopTime.autoDateTime = validDates;
- }
- },
- /**
- * 开始时间,任务开始时间排序
- * @param dates
- */
- sortSelectedDates(dates) {
- if (!this.form.startTime) {
- this.$message.error("请先选择开始时间!不得小于任务开始时间");
- this.form.autoSopTime.autoDateTime = [];
- return;
- }
- // 1. 过滤掉 < startTime 的日期
- const validDates = dates.filter(date => new Date(date) >= new Date(this.form.startTime));
- // 2. 如果有被过滤掉的日期,提示用户
- if (validDates.length < dates.length) {
- this.$message.warning(`已自动移除小于 ${this.form.startTime} 的日期!`);
- }
- // 3. 升序排序
- validDates.sort((a, b) => new Date(a) - new Date(b));
- // 4. 更新数据
- this.form.autoSopTime.autoDateTime = validDates;
- },
- /**
- * 查询模板
- * @param type
- */
- selectListSopTemp(type) {
- this.tempOpen = true;
- setTimeout(() => {
- this.$refs.SopTempComments.getList(type);
- }, 200);
- },
- sopTemp(val) {
- this.$set(this.form, 'tempId', val.id);
- this.$set(this.form, 'tempName', val.name);
- this.tempOpen = false;
- },
- //选择app用户时
- openSelectCustomerPage(type, sendType) {
- this.customerConfig.title = "选择客服"
- this.customerConfig.visible = true;
- },
- /**
- * 切换类别时 ,清除选择的成员
- */
- clearUser() {
- this.selected = [];
- this.tags = null;
- },
- /**
- * 编辑/查看获取任务信息
- * @param sopId
- */
- handleUpdate(sopId) {
- this.reset();
- getSop({id: sopId}).then(async (response) => {
- this.form = response.data;
- this.form.autoSopTime = JSON.parse(response.data.autoSopTime)
- if (this.form.filterMode != 1) {
- this.form.sendType = 2;
- }
- if (!this.isEmpty(this.form.tags)) {
- let tagInfo = await getTagByIds(this.form.tags);
- this.selectTagDialog.selected = tagInfo.data || [];
- }
- this.form.status = response.data.status.toString();
- if (this.form.setting != null) {
- this.setting = JSON.parse(this.form.setting);
- }
- if (this.form.autoGroupLevel != null) {
- this.form.autoGroupLevelArray = this.form.autoGroupLevel.split(",").map(Number)
- .filter(item => item !== 0);
- }
- if (!this.isEmpty(this.form.appCustomerId)) {
- let userInfo = await listRole({ids: this.form.appCustomerId});
- this.selected = userInfo.rows;
- }
- let tempInfo = await getSopTemp(this.form.tempId);
- this.$set(this.form, 'tempName', tempInfo.data.name);
- });
- },
- isEmpty(obj) {
- if (null === obj || undefined === obj || 0 === obj.length) {
- return true;
- }
- return false;
- },
- customerSelectedConfirmCallForBind() {
- this.customerConfig.visible = false;
- },
- /**
- * 选中的用户列表
- * @param list
- */
- customerSelectionChangeCallForBind(config) {
- let selected = config.selected;
- //单行操作
- if (config.mode === 0) {
- let row = config.row;
- if (selected) {
- if (!this.selected.some(s => s.id == row.id)) {
- this.selected.push(row)
- }
- } else {
- this.selected = this.selected.filter(m => m.id != row.id);
- }
- }
- //操作当前页所有行
- else {
- let list = config.rows;
- if (selected) {
- list.map(l => {
- if (!this.selected.some(s => s.id == l.id)) {
- this.selected.push(l)
- }
- });
- } else {
- list.map(l => {
- for (let i = 0; i < this.selected.length; i++) {
- if (l.id == this.selected[i].id) {
- this.selected.splice(i, 1);
- }
- }
- })
- }
- }
- },
- //选择变动时的变动
-
- /**
- * 推送方式修改
- * @param val
- */
- handleSendTypeChange(val) {
- this.selected = [];
- this.form.tempId = null;
- this.form.tempName = null;
- if (val == 1) {
- // 遍历 this.setting 数组并清空每个对象的 content 属性
- this.setting.forEach(item => {
- if (item.content.length > 9) {
- item.content = item.content.slice(0, 9); // 保留前 9 个元素
- }
- });
- }
- },
- handleCloseCustomer(list) {
- const index = this.selected.findIndex(t => t === list);
- if (index !== -1) {
- this.selected.splice(index, 1);
- }
- },
- /**
- * 取消按钮
- */
- cancel() {
- //删除当前打开的菜单tab
- this.$store.dispatch("tagsView/delView", this.$route);
- //替换浏览器路由
- this.$router.replace('/app/sop')
- this.reset();
- },
- /**
- * 清空搜索标签条件
- */
- resetSearchQueryTag() {
- this.queryTagParams = {
- pageNum: 1,
- pageSize: 10,
- total: 0,
- name: null,
- };
- },
- // 表单重置
- reset() {
- this.form = {
- id: null,
- filterMode: 1,
- name: null,
- status: 1,
- sendType: 2,
- filterType: 2,
- expiryTime: 3,
- appCustomerId: null,
- setting: null,
- createBy: null,
- createTime: null,
- autoSopTime: { autoSopType: 2, autoStartTime: '00:00', autoEndTime: '24:00', autoSopSend: 2, autoDateTime: [] },
- };
- this.resetForm("form");
- this.tags = null;
- },
- /** 重置按钮操作 */
- resetQuery() {
- this.resetForm("queryForm");
- this.handleQuery();
- },
- formatDateTo24HourString(date) {
- let year = date.getFullYear();
- let month = ('0' + (date.getMonth() + 1)).slice(-2); // 月份需要加 1 并补零
- let day = ('0' + date.getDate()).slice(-2); // 日需要补零
- let hours = ('0' + date.getHours()).slice(-2); // 小时需要补零
- let minutes = ('0' + date.getMinutes()).slice(-2); // 分钟需要补零
- let seconds = ('0' + date.getSeconds()).slice(-2); // 秒需要补零
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
- },
- // 打开群聊选择器
- openGroupChatSelector() {
- this.$refs.groupChatSelector.show(this.form.chatIds);
- },
- // 处理群聊选择结果
- handleSelectGroupChats(selectedChatIds) {
- this.form.chatIds = selectedChatIds;
- // 强制更新视图
- this.$forceUpdate();
- },
- /**
- * 保存sop任务
- */
- submitForm() {
- this.$refs["form"].validate(valid => {
- if (valid) {
- if (this.selected.length <= 0) {
- return this.$message.error("请选择客服")
- }
- this.form.appCustomerId = this.selected.map(s => s.id).join(",");
- if (this.selectTagDialog.selected != null && this.selectTagDialog.selected.length > 0) {
- this.form.tags = this.selectTagDialog.selected?.map(item => item.id).join(",");
- } else {
- return this.$message.error("选择的标签不能为空!!请选择筛选的标签")
- }
- if (this.form.autoSopTime.autoSopType == 3 || this.form.autoSopTime.autoSopType == 4) {
- if (this.form.autoSopTime.autoDateTime == null || this.form.autoSopTime.autoDateTime == "") {
- return this.$message.error("选择的日期不能为空!!请选择日期")
- }
- }
- this.form.appCustomerId = this.selected.map(s => s.id).join(",");
- this.form.setting = JSON.stringify(this.setting)
- this.form.autoSopTime.createTime = this.formatDateTo24HourString(new Date());
- this.form.autoSopTime = JSON.stringify(this.form.autoSopTime)
- if (this.form.id != null) {
- updateSop(this.form).then(response => {
- this.msgSuccess("修改成功");
- this.$store.dispatch("tagsView/delView", this.$route);
- window.location.replace('/app/sop')
- this.reset();
- });
- } else {
- addSop(this.form).then(response => {
- this.msgSuccess("新增成功");
- this.$store.dispatch("tagsView/delView", this.$route);
- window.location.replace('/app/sop')
- this.reset();
- });
- }
- }
- });
- },
- }
- };
- </script>
- <style scoped lang="scss">
- .custom-input ::v-deep .el-input__inner {
- height: 20px;
- padding: 0 4px;
- text-align:center;
- display: block;
- }
- .custom-input ::v-deep .el-input__icon {
- line-height: 20px;
- }
- .user-box {
- width: 50px; /* 盒子宽度 */
- height: 30px; /* 盒子高度 */
- padding: 5px 10px; /* 内边距 */
- border: 1px solid #d5d1d1;/* 边框 */
- margin: 3px; /* 外边距 */
- background-color: #f9f9f9;/* 背景颜色 */
- color: #333; /* 文本颜色 */
- font-size: 14px; /* 字体大小 */
- text-align: center; /* 文本居中 */
- }
- .elFormItemClass{
- margin: 20px 0px
- }
- .message-stayle{
- display: flex;
- justify-content: normal;
- align-items: center;
- margin-top: 10px;
- }
- .message-stayle .el-link {
- white-space: normal; /* 允许换行 */
- word-break: break-all; /* 单词中间断行 */
- overflow-wrap: break-word; /* 允许在单词内换行 */
- }
- .message-stayle span {
- word-break: break-all;
- }
- .container {
- position: relative; /* 使 phone div 的 absolute 定位基于这个容器 */
- width: 100%;
- height: 100%;
- }
- .phone {
- position: absolute; /* 定位到容器内 */
- top: 5%;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
- max-width: 375px;
- height: 100%;
- max-height: 90%;
- border: 8px solid #ccc;
- border-radius: 36px;
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
- background-color: #fff;
- overflow: hidden;
- }
- .phone::before {
- content: '';
- position: absolute;
- top: 0;
- left: 50%;
- width: 60px;
- height: 5px;
- background-color: #ccc;
- border-radius: 10px;
- transform: translateX(-50%);
- }
- .chat-interface {
- display: flex;
- flex-direction: column;
- height: 100%;
- background-color: #fff;
- }
- .header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- height: 50px;
- padding: 0 15px;
- background-color: #fff;
- border-bottom: 1px solid #e0e0e0;
- }
- .header .back,
- .header .menu {
- height: 25px;
- width: 25px;
- }
- .header .title{
- font-size: 16px;
- margin: auto;
- }
- .message-area {
- flex: 1;
- background-color: rgb(240, 242, 245);
- padding: 10px;
- overflow-y: auto;
- }
- .footer {
- display: flex;
- align-items: center;
- padding: 10px;
- background-color: #fff;
- border-top: 1px solid #e0e0e0;
- }
- .footer .voice-button,
- .footer .emoji-button,
- .footer .add-button {
- width: 25px;
- height: 25px;
- border: none;
- cursor: pointer;
- flex-shrink: 0; /* 不允许缩小 */
- }
- .footer .emoji-button,
- .footer .add-button {
- margin: 0px 5px;
- }
- .footer .input-box {
- flex: 1;
- border: 1px solid #e0e0e0;
- margin-left: 5px;
- }
- .text-container {
- max-height: 7.5em; /* 设置最大高度为6行,根据字体大小调整 */
- overflow-y: auto; /* 内容超出时显示滚动条 */
- line-height: 1.5em; /* 行高设置,确保每行高度一致 */
- }
- .el-form-item {
- margin-bottom: 30px;
- }
- .custom-span {
- display: block; /* 确保元素是块级元素 */
- height: 110px; /* 设置固定高度 */
- overflow-y: auto; /* 超出高度时显示滚动条 */
- word-wrap: break-word; /* 自动换行 */
- word-break: break-all; /* 在必要时进行换行 */
- }
- .custom-span-description{
- display: block; /* 确保元素是块级元素 */
- height: 110px; /* 设置固定高度 */
- overflow-y: auto; /* 超出高度时显示滚动条 */
- word-wrap: break-word; /* 自动换行 */
- word-break: break-all; /* 在必要时进行换行 */
- }
- .custom-span-title {
- display: block; /* 确保元素是块级元素 */
- height: 45px; /* 设置固定高度 */
- overflow-y: auto; /* 超出高度时显示滚动条 */
- word-wrap: break-word; /* 自动换行 */
- word-break: break-all; /* 在必要时进行换行 */
- }
- /* CSS 样式 */
- .tag-container {
- display: flex;
- flex-wrap: wrap; /* 超出宽度时自动换行 */
- gap: 8px; /* 设置标签之间的间距 */
- }
- .name-background {
- display: inline-block;
- background-color: #abece6; /* 背景颜色 */
- padding: 4px 8px; /* 调整内边距,让背景包裹文字 */
- border-radius: 4px; /* 可选:设置圆角 */
- }
- .tag-box {
- padding: 8px 12px;
- border: 1px solid #989797;
- border-radius: 4px;
- cursor: pointer;
- display: inline-block;
- }
- .tag-selected {
- background-color: #00bc98;
- color: #fff;
- border-color: #00bc98;
- }
- .el-tag + .el-tag {
- margin-left: 10px;
- }
- .button-new-tag {
- margin-left: 10px;
- height: 32px;
- line-height: 30px;
- padding-top: 0;
- padding-bottom: 0;
- }
- .input-new-tag {
- width: 90px;
- margin-left: 10px;
- vertical-align: bottom;
- }
- .text-container {
- max-height: 5em; /* 设置最大高度为6行,根据字体大小调整 */
- overflow-y: auto; /* 内容超出时显示滚动条 */
- line-height: 1.5em; /* 行高设置,确保每行高度一致 */
- }
- </style>
|