zhujindu 1 рік тому
батько
коміт
b0e6e4380c

+ 17 - 0
src/api/complaintDetail.js

@@ -0,0 +1,17 @@
+import request from '@/utils/request';
+
+// 不想写
+export function getComplaintCustomerClueInfoById(query) {
+  return request({
+    url: '/mobile/customerClueInfo/getComplaintCustomerClueInfoById',
+    method: 'get',
+    params: query,
+  });
+}
+export function insertCustomerClueAnswer(data) {
+  return request({
+    url: 'mobile/customerClueInfo/insertCustomerClueAnswer',
+    method: 'post',
+    data,
+  });
+}

+ 233 - 0
src/views/clew/complaintDetail/index.vue

@@ -0,0 +1,233 @@
+<template>
+  <div class="bgcolor assignPage">
+    <div class="navBarTOP">
+      <van-nav-bar class="navBar" left-arrow :title="title" @click-left="onClickLeft" />
+    </div>
+    <div class="lineGrey"></div>
+    <div class="lineGrey"></div>
+    <div class="lineGrey"></div>
+    <div class="lineGrey"></div>
+    <div class="lineGrey"></div>
+    <!-- 客诉详情 -->
+    <infoDetail :infoData="infoData" v-if="infoData"> </infoDetail>
+    <!-- 客诉记录 -->
+    <!-- 跟进任务填写 -->
+    <div class="assign" v-if="infoData && infoData.isClose != 1">
+      <div class="followUp required">跟进结果</div>
+      <div class="taskGather" v-if="taskGather && taskGather">
+        <radioGroup :clueOptionList="taskGather"></radioGroup>
+      </div>
+      <div class="tc" style="padding: 0 16px">
+        <van-button class="submitBtn" block type="info" color="#0057ba" @click="onSubmit">
+          提交
+        </van-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getComplaintCustomerClueInfoById } from '@/api/complaintDetail';
+import infoDetail from './infoDetail.vue';
+// import { selectCustomerClueInfoById, insertFollowCustomerClueAnswer } from '@/api/assignAwait';
+import { mapState } from 'vuex';
+import radioGroup from './radioGroup';
+
+export default {
+  name: 'assignPage',
+  components: {
+    assignAwaitDetail,
+    radioGroup,
+    followUpHistory,
+  },
+  computed: {
+    ...mapState({
+      userInfo: (state) => state.user.userInfo,
+    }),
+  },
+  data() {
+    return {
+      id: '',
+      infoData: null,
+      title: '',
+      postName: '',
+      taskGather: null, //跟进任务集合
+      requiredFlag: true, //问题必填检验
+      requiredMessage: '', //必填提示信息
+    };
+  },
+  watch: {},
+  activated() {
+    this.id = this.$route.query.id;
+    this.postName = localStorage.getItem('postName');
+    this.getComplaintCustomerClueInfoByIdFun();
+  },
+  methods: {
+    getComplaintCustomerClueInfoByIdFun() {
+      this.toastLoading(0, '加载中...', true);
+      this.id = this.$route.query.id;
+      getComplaintCustomerClueInfoById({ customerClueInfoId: this.id }).then((response) => {
+        this.toastLoading().clear();
+        if (response.code == 200) {
+          this.infoData = response.data;
+          this.title = response.data.name;
+          // if (this.infoData.isClose != 1) {
+          //   this.getSelectCustomerClueInfoById();
+          // }
+        } else {
+          this.$toast(res.msg);
+        }
+      });
+    },
+    getSelectCustomerClueInfoById() {
+      selectCustomerClueInfoById({ customerClueInfoId: this.id }).then((res) => {
+        if (res.code == 200) {
+          // res.data.customerClue.searchValue.customerClueItemList
+          if (res.data.customerClue) {
+            res.data.customerClue.customerClueItemList[0].customerClueInfoId = this.id;
+            this.taskGather = res.data.customerClue.customerClueItemList;
+          }
+        } else {
+          this.$toast(res.msg);
+        }
+      });
+    },
+    onSubmit() {
+      // 没有选择跟进记录
+      if (!this.taskGather[0].searchValue) {
+        this.$toast('请选择跟进结果');
+        return;
+      }
+      this.requiredFlag = true;
+      let customerClueItemList = [];
+      // 每一个层级都是一道题的题目,子级就是题,被选中和填写的题要带上题目一块上传(题的同级也要上传)
+      // 第一级题目下的题默认都要上传
+      let params = { customerClueItemList: [] };
+      params.customerClueItemList.push(...this.deepClone(this.taskGather, 0));
+      let optionList = this.taskGather[0].customerClueOptionList;
+      this.filterOption(optionList, params);
+      // 必填验证
+      if (this.requiredFlag) {
+        this.toastLoading(0, '加载中...', true);
+        insertFollowCustomerClueAnswer(params).then((res) => {
+          this.toastLoading().clear();
+          if (res.code == 200) {
+            this.$toast(res.msg);
+            window.location.replace(window.location.origin + '/mobile/clew');
+          } else {
+            this.$toast(res.msg);
+          }
+        });
+      } else {
+        this.$toast(this.requiredMessage);
+      }
+    },
+    filterOption(optionList, params) {
+      let copy = null;
+      for (let i = 0; i < optionList.length; i++) {
+        if (optionList[i].value == 'Y') {
+          if (optionList[i].customerClueItemList) {
+            // 必填校验
+            this.isRequiredFlag(optionList[i].customerClueItemList);
+            params.customerClueItemList.push(
+              ...this.deepClone(optionList[i].customerClueItemList, 0)
+            );
+            if (
+              optionList[i].customerClueItemList[0] &&
+              optionList[i].customerClueItemList[0].customerClueOptionList.length
+            ) {
+              this.filterOption(
+                optionList[i].customerClueItemList[0].customerClueOptionList,
+                params
+              );
+            }
+          }
+        }
+      }
+    },
+    deepClone(obj, num) {
+      // 检查是否为对象或数组
+      if (obj === null || typeof obj !== 'object') {
+        return obj; // 基本类型直接返回
+      }
+      // 创建一个数组或对象
+      const copy = Array.isArray(obj) ? [] : {};
+      // 遍历对象的每个属性
+      for (const key in obj) {
+        if (obj.hasOwnProperty(key) && num < 2) {
+          // 递归调用深拷贝
+          if (key == 'customerClueOptionList' || key == 'customerClueItemList') {
+            num = num + 1;
+          }
+          copy[key] = this.deepClone(obj[key], num);
+        }
+      }
+      return copy;
+    },
+    isRequiredFlag(optionList) {
+      console.log(optionList);
+      // 必填类型
+      for (let i = 0; i < optionList.length; i++) {
+        if (optionList[i].answerType == 'wb' && optionList[i].isMust == 0) {
+          if (!optionList[i].answerValue) {
+            this.requiredFlag = false;
+            this.requiredMessage = optionList[i].remark;
+            return;
+          }
+        }
+      }
+    },
+    // 校验错误返回信息
+    onFailed(errorInfo) {
+      console.log('failed', errorInfo);
+    },
+    onClickLeft() {
+      this.$router.go(-1);
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.assignPage {
+  .assign {
+    margin: 10px;
+    background-color: #fff;
+    padding-bottom: 20px;
+    .followUp {
+      padding: 16px;
+      font-size: 14px;
+      font-weight: 600;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.assignPage {
+  .van-field__label {
+    width: 100px;
+    &::before {
+      content: '*';
+      color: red;
+    }
+  }
+  .centerBtn {
+    float: right;
+    background: #0057ba;
+    border-color: #0057ba;
+    color: #fff;
+    margin-top: -33px;
+    border-radius: 5px;
+  }
+  .dialogz {
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    height: 72vh;
+    .van-dialog__content {
+      flex: 1;
+      overflow-y: auto;
+    }
+  }
+}
+</style>

+ 89 - 0
src/views/clew/complaintDetail/infoDetail.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="cardclewContent assignAwaitDetail">
+    <div class="info">姓名:{{ infoData.name }}</div>
+    <div class="info">
+      手机号:<a
+        style="color: #0057ba; font-weight: bold; text-decoration: underline"
+        :href="'tel:' + infoData.phone"
+        >{{ infoData.phone }}<van-icon name="phone"
+      /></a>
+    </div>
+    <div class="info">区域:{{ infoData.companyName }}</div>
+    <div class="info">省:{{ infoData.provinceName }}</div>
+    <div class="info">市:{{ infoData.cityName }}</div>
+    <div class="info">区/县:{{ infoData.countryName }}</div>
+    <div class="info">
+      分类:
+      <span>{{ filterClassify(infoData.customerClassify) }}</span>
+    </div>
+    <div class="info">详细地址:{{ infoData.countryName }}</div>
+    <slot></slot>
+  </div>
+</template>
+
+<script>
+import { getDictOption } from '@/api/index';
+export default {
+  name: 'assignAwaitDetail',
+  props: {
+    infoData: {
+      type: Object,
+      default: {},
+    },
+    source: {
+      // assignPage 拥有家装分配权限
+      type: String,
+    },
+  },
+  data() {
+    return {
+      customerClassify: [],
+    };
+  },
+  watch: {
+    source: {
+      handler(val) {
+        if (val == 'JZfollowUp') {
+          this.getCustomerClassify();
+        }
+      },
+      immediate: true,
+    },
+  },
+  created() {},
+  methods: {
+    async getCustomerClassify() {
+      let option = await getDictOption({}, 'customer_classify');
+      this.customerClassify = option.data || [];
+    },
+    filterClassify(customerClassify) {
+      let item = this.customerClassify.find((val) => val.dictValue == customerClassify);
+      return item.dictLabel || '';
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.cardclewContentCell {
+  margin: 0 10px;
+}
+.cardclewContent {
+  background: #fff;
+  box-sizing: border-box;
+  padding: 10px 16px;
+  margin: 6px 10px 10px;
+}
+.cardclewContent .info {
+  font-size: 14px;
+  color: #444;
+  line-height: 28px;
+}
+.cardclewContent .title p {
+  padding: 0;
+  margin: 0;
+}
+.cardclewContent .title .textLeft {
+  display: inline-block;
+  padding-bottom: 10px;
+}
+</style>