Bläddra i källkod

客户信息表增加销售认领记录

cgp 1 vecka sedan
förälder
incheckning
ac98d2b8e1
2 ändrade filer med 178 tillägg och 87 borttagningar
  1. 9 0
      src/api/qw/companyCustomer.js
  2. 169 87
      src/views/qw/companyCustomer/index.vue

+ 9 - 0
src/api/qw/companyCustomer.js

@@ -104,3 +104,12 @@ export function getCollectionInfoListByIdAndPhone(data) {
     data: data
   })
 }
+
+// 获取客户认领记录列表
+export function getCustomerLogList(query) {
+  return request({
+    url: '/qw/customerLog/list',
+    method: 'get',
+    params: query
+  })
+}

+ 169 - 87
src/views/qw/companyCustomer/index.vue

@@ -24,7 +24,7 @@
           :default-time="['00:00:00', '23:59:59']"
         ></el-date-picker>
       </el-form-item>
-      <!-- 新增:信息表生成时间 -->
+      <!-- 信息表生成时间 -->
       <el-form-item label="生成时间">
         <el-date-picker
           v-model="createTimeRange"
@@ -38,9 +38,16 @@
           :default-time="['00:00:00', '23:59:59']"
         ></el-date-picker>
       </el-form-item>
-      <!-- 完善状态 -->
-      <el-form-item label="完善状态" prop="claimStatus">
+      <!-- 认领状态筛选 -->
+      <el-form-item label="认领状态" prop="claimStatus">
         <el-select v-model="queryParams.claimStatus" placeholder="请选择" clearable size="small" style="width: 120px">
+          <el-option label="未认领" :value="0" />
+          <el-option label="已认领" :value="1" />
+        </el-select>
+      </el-form-item>
+      <!-- 完善状态筛选 -->
+      <el-form-item label="完善状态" prop="completeStatus">
+        <el-select v-model="queryParams.completeStatus" placeholder="请选择" clearable size="small" style="width: 120px">
           <el-option label="未完善" :value="0" />
           <el-option label="已完善" :value="1" />
         </el-select>
@@ -92,10 +99,13 @@
       <el-table-column label="建档时间" align="center" prop="filingTime" width="180">
         <template slot-scope="scope">{{ parseTime(scope.row.filingTime) }}</template>
       </el-table-column>
-      <el-table-column label="客服姓名" align="center" prop="companyUserName" />
+      <el-table-column label="归属销售" align="center" prop="companyUserName" />
+      <!-- 修正:归属分组应使用 deptName -->
+      <el-table-column label="归属分组" align="center" prop="deptName" />
       <el-table-column label="负责医生" align="center" prop="doctorName" />
       <el-table-column label="购买次数" align="center" prop="buyCount" />
-      <el-table-column label="完善状态" align="center" prop="claimStatus" :formatter="claimStatusFormat" />
+      <el-table-column label="认领状态" align="center" prop="claimStatus" :formatter="claimStatusFormat" />
+      <el-table-column label="完善状态" align="center" prop="completeStatus" :formatter="completeStatusFormat" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="300">
         <template slot-scope="scope">
           <el-button size="mini" type="text" icon="el-icon-info" @click="handleDetail(scope.row)">详情</el-button>
@@ -105,13 +115,11 @@
           <el-button size="mini" type="text" icon="el-icon-delete" v-if="scope.row.myCustomerFlag"
                      @click="handleDelete(scope.row)">删除
           </el-button>
-          <el-button size="mini" type="text" icon="el-icon-user" v-if="!scope.row.companyUserId"
-                     @click="handleClaim(scope.row)">认领客户
-          </el-button>
-          <el-button size="mini" type="text" icon="el-icon-view" @click="handlePrescribe(scope.row)">查看处方
-          </el-button>
-          <el-button size="mini" type="text" icon="el-icon-document" @click="handleCollection(scope.row)">查看信息采集
-          </el-button>
+          <!-- 认领按钮:无条件显示 -->
+          <el-button size="mini" type="text" icon="el-icon-user" @click="handleClaim(scope.row)">认领客户</el-button>
+          <el-button size="mini" type="text" icon="el-icon-view" @click="handlePrescribe(scope.row)">查看处方</el-button>
+          <el-button size="mini" type="text" icon="el-icon-document" @click="handleCollection(scope.row)">查看信息采集</el-button>
+          <el-button size="mini" type="text" icon="el-icon-document-copy" @click="handleViewLog(scope.row)">认领记录</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -250,13 +258,35 @@
     <!-- 信息采集弹窗 -->
     <collection-info-dialog :visible.sync="collectionVisible" :id="currentId"/>
 
-    <!-- ========== 独立的认领确认弹窗 ========== -->
-    <el-dialog title="认领客户" :visible.sync="claimDialogVisible" width="400px" append-to-body
+    <!-- 认领记录弹窗 -->
+    <el-dialog title="认领记录" :visible.sync="claimLogDialogVisible" width="900px" append-to-body :close-on-click-modal="false">
+      <el-table v-loading="claimLogLoading" :data="claimLogList" border>
+        <el-table-column label="归属销售" align="center" prop="companyUserName" />
+        <el-table-column label="归属部门" align="center" prop="deptName" />
+        <el-table-column label="认领时间" align="center" prop="claimTime" width="180">
+          <template slot-scope="scope">{{ parseTime(scope.row.claimTime) }}</template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="claimLogTotal > 0"
+        :total="claimLogTotal"
+        :page.sync="claimLogQueryParams.pageNum"
+        :limit.sync="claimLogQueryParams.pageSize"
+        @pagination="getClaimLogList"
+      />
+    </el-dialog>
+    <!-- ========== 独立的认领确认弹窗(带认领号码输入) ========== -->
+    <el-dialog title="认领客户" :visible.sync="claimDialogVisible" width="450px" append-to-body
                :close-on-click-modal="false">
-      <div>
-        <p>确认认领客户【{{ currentClaimRow && currentClaimRow.customerName }}】吗?</p>
-        <p>认领后,该客户将归属到您的客服账号和负责医生名下。</p>
-      </div>
+      <el-form :model="claimForm" ref="claimForm" :rules="claimRules" label-width="100px" size="small">
+        <el-form-item label="客户名称">
+          <span>{{ currentClaimRow && currentClaimRow.customerName }}</span>
+        </el-form-item>
+        <el-form-item label="认领号码" prop="claimNumber" required>
+          <el-input v-model="claimForm.claimNumber" placeholder="请输入认领号码(手机号)" clearable />
+        </el-form-item>
+        <p style="color: #909399; font-size: 12px; margin-top: 10px;">认领后,该客户将归属到您的账号下。</p>
+      </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button @click="claimDialogVisible = false">取 消</el-button>
         <el-button type="primary" :loading="claimSubmitLoading" @click="submitClaim">确 认</el-button>
@@ -268,7 +298,7 @@
 <script>
 import {
   listCustomer, getCustomer, addCustomer, updateCustomer, delCustomer, exportCustomer,
-  getCompanyUserAndDoctor, getPrescribeListByIdAndPhone, claimCustomer
+  getCompanyUserAndDoctor, getPrescribeListByIdAndPhone, claimCustomer,getCustomerLogList
 } from '@/api/qw/companyCustomer'
 import {parseTime} from '@/utils/common'
 
@@ -299,6 +329,19 @@ export default {
         callback();
       }
     };
+    // 认领号码校验(必填,11位手机号格式)
+    const validateClaimNumber = (rule, value, callback) => {
+      if (!value) {
+        callback(new Error('请输入认领号码'));
+        return;
+      }
+      const phone = String(value).trim();
+      if (phone.length !== 11 || !/^1[3-9]\d{9}$/.test(phone)) {
+        callback(new Error('请输入有效的11位手机号码'));
+        return;
+      }
+      callback();
+    };
     return {
       loading: true,
       ids: [],
@@ -317,7 +360,8 @@ export default {
         customerName: null,
         phone: null,
         companyUserName: null,
-        claimStatus: 0,
+        claimStatus: null,    // 认领状态筛选
+        completeStatus: null, // 完善状态筛选
         purchased: false,
         minBuyCount: null,
         maxBuyCount: null
@@ -335,12 +379,8 @@ export default {
           {validator: validatePhone, trigger: "blur"}
         ],
         address: [{required: true, message: "地址不能为空", trigger: "blur"}],
-        // filingTime: [{ required: true, message: "建档时间不能为空", trigger: "blur" }],
         companyUserName: [{required: true, message: "客服姓名不能为空", trigger: "blur"}],
         doctorName: [{required: true, message: "负责医生不能为空", trigger: "blur"}],
-        // presentIllness: [{ required: true, message: "现病史不能为空", trigger: "blur" }],
-        // currentMedication: [{ required: true, message: "现用药情况不能为空", trigger: "blur" }],
-        // allergyHistory: [{ required: true, message: "过敏史不能为空", trigger: "blur" }]
       },
       sexOptions: [
         {label: '女', value: '0'},
@@ -375,14 +415,38 @@ export default {
       claimDialogVisible: false,
       claimSubmitLoading: false,
       currentClaimRow: null,
+      claimForm: {
+        claimNumber: ''
+      },
+      claimRules: {
+        claimNumber: [
+          { required: true, message: '请输入认领号码', trigger: 'blur' },
+          { validator: validateClaimNumber, trigger: 'blur' }
+        ]
+      },
+      // 认领记录弹窗相关
+      claimLogDialogVisible: false,
+      claimLogLoading: false,
+      claimLogList: [],
+      claimLogTotal: 0,
+      claimLogQueryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        companyCustomerId: null   // 当前查看的客户ID
+      }
     }
   },
   created() {
     this.getList()
   },
   methods: {
+    // 认领状态格式化
     claimStatusFormat(row) {
-      return row.claimStatus === 1 ? '已完善' : '未完善';
+      return row.claimStatus === 1 ? '已认领' : '未认领';
+    },
+    // 完善状态格式化
+    completeStatusFormat(row) {
+      return row.completeStatus === 1 ? '已完善' : '未完善';
     },
     parseTime,
     getCurrentDateTime() {
@@ -397,14 +461,22 @@ export default {
     },
     getList() {
       this.loading = true;
+      // 构建参数,过滤掉 null/undefined/空字符串
       const params = this.addDateRange(this.queryParams, this.dateRange);
       if (this.createTimeRange && this.createTimeRange.length === 2) {
         params.beginCreateTime = this.createTimeRange[0];
         params.endCreateTime = this.createTimeRange[1];
       }
+      // 处理 purchased:false 时不传
       if (!params.purchased) {
         delete params.purchased;
       }
+      // 删除值为 null、undefined 或空字符串的属性
+      Object.keys(params).forEach(key => {
+        if (params[key] === null || params[key] === undefined || params[key] === '') {
+          delete params[key];
+        }
+      });
       listCustomer(params).then(response => {
         this.customerList = response.rows;
         this.total = response.total;
@@ -417,88 +489,70 @@ export default {
       this.dateRange = [];
       this.createTimeRange = [];
       this.resetForm("queryForm");
-      this.queryParams.claimStatus = 0;
+      this.queryParams.claimStatus = null;
+      this.queryParams.completeStatus = null;
       this.queryParams.purchased = false;
       this.queryParams.minBuyCount = null;
       this.queryParams.maxBuyCount = null;
       this.handleQuery();
     },
     /**
-     * 认领客户:打开独立确认弹窗
+     * 认领客户:打开独立弹窗,要求输入认领号码
      */
     handleClaim(row) {
-      if (row.companyUserId) {
-        this.$message.warning('该客户已被认领,无法重复认领');
-        return;
-      }
-      getCompanyUserAndDoctor().then(res => {
-        const userData = res.data;
-        if (!userData || !userData.doctorId) {
-          this.$modal.msgError("未找到绑定医生!请先绑定医生后再操作!");
-          return;
+      this.currentClaimRow = row;
+      this.claimForm.claimNumber = '';
+      this.claimDialogVisible = true;
+      // 清除表单校验
+      this.$nextTick(() => {
+        if (this.$refs.claimForm) {
+          this.$refs.claimForm.clearValidate();
         }
-        this.currentClaimRow = row;
-        this.claimDialogVisible = true;
-      }).catch(err => {
-        console.error("获取客服/医生信息失败", err);
-        this.$message.error("获取用户信息失败,无法认领");
       });
     },
     /**
-     * 执行认领提交:成功后自动打开编辑弹窗(修改模式)
+     * 执行认领提交
+     * 先获取当前登录用户的客服和医生信息,再调用认领接口
      */
     submitClaim() {
-      if (!this.currentClaimRow || !this.currentClaimRow.id) {
-        this.$message.error("客户信息异常,请刷新后重试");
-        this.claimDialogVisible = false;
-        return;
-      }
-      this.claimSubmitLoading = true;
-      // 获取最新的客服和医生信息
-      getCompanyUserAndDoctor().then(res => {
-        const userData = res.data;
-        if (!userData || !userData.doctorId) {
-          this.$message.error("未找到绑定医生,无法认领");
-          this.claimSubmitLoading = false;
+      this.$refs.claimForm.validate(valid => {
+        if (!valid) return;
+        if (!this.currentClaimRow || !this.currentClaimRow.id) {
+          this.$message.error("客户信息异常,请刷新后重试");
           this.claimDialogVisible = false;
           return;
         }
-        const claimParams = {
-          id: this.currentClaimRow.id,
-          companyUserId: userData.companyUserId,
-          companyUserName: userData.companyUserName,
-          doctorId: userData.doctorId,
-          doctorName: userData.doctorName
-        };
-        claimCustomer(claimParams).then(() => {
+        this.claimSubmitLoading = true;
+        // 获取当前登录用户的客服及医生信息
+        getCompanyUserAndDoctor().then(res => {
+          const userData = res.data;
+          if (!userData || !userData.doctorId) {
+            this.$message.error("未找到绑定医生,无法认领");
+            this.claimSubmitLoading = false;
+            this.claimDialogVisible = false;
+            return;
+          }
+          const claimParams = {
+            id: this.currentClaimRow.id,
+            companyUserId: userData.companyUserId,
+            companyUserName: userData.companyUserName,
+            doctorId: userData.doctorId,
+            doctorName: userData.doctorName,
+            claimPhone: this.claimForm.claimNumber   // 认领号码
+          };
+          return claimCustomer(claimParams);
+        }).then(() => {
           this.$message.success("认领成功");
           this.claimDialogVisible = false;
-          // 刷新列表(让表格显示最新状态)
           this.getList();
-          // 打开编辑弹窗,让用户继续完善信息
-          return getCustomer(this.currentClaimRow.id);
-        }).then(response => {
-          // 重置表单状态(确保不是只读模式)
-          this.reset();
-          this.form = response.data;
-          if (this.form.sex !== undefined && this.form.sex !== null) {
-            this.form.sex = String(this.form.sex);
-          }
-          this.open = true;
-          this.title = "修改客户信息";
-          this.isDetail = false;
-        }).catch(error => {
-          // 如果打开编辑弹窗失败(例如获取详情接口报错),仅提示,不影响认领成功的消息
-          console.error("获取客户详情失败", error);
-          this.$message.error("获取客户详情失败,请手动刷新后编辑");
+        }).catch(err => {
+          // 直接从 err 中取出后端返回的错误信息
+          const errorMsg = err?.message || err?.msg || "认领失败,请稍后重试";
+          this.$message.error(errorMsg);
+          // 不再输出 console.error,避免重复显示
         }).finally(() => {
           this.claimSubmitLoading = false;
         });
-      }).catch(err => {
-        console.error("获取客服/医生信息失败", err);
-        this.$message.error("获取用户信息失败,无法认领");
-        this.claimSubmitLoading = false;
-        this.claimDialogVisible = false;
       });
     },
     sexFormat(row) {
@@ -527,8 +581,8 @@ export default {
       this.form = {
         id: null,
         customerName: null,
-        sex: '0',
-        age: 18,
+        sex: null,
+        age: undefined,
         address: null,
         phone: null,
         filingTime: null,
@@ -559,7 +613,7 @@ export default {
       getCompanyUserAndDoctor().then(response => {
         const data = response.data;
         if (!data || !data.doctorId) {
-          this.$modal.msgError("未找到绑定医生!请绑定医生后再操作!");
+          this.$modal.msgError("未找到绑定医生!请绑定医生后再操作!");
           return;
         }
         this.form.companyUserId = data.companyUserId;
@@ -676,6 +730,34 @@ export default {
       this.currentId = row.id
       this.collectionVisible = true
     },
+    // 查看认领记录
+    handleViewLog(row) {
+      // 重置分页
+      this.claimLogQueryParams.pageNum = 1
+      this.claimLogQueryParams.companyCustomerId = row.id
+      this.claimLogDialogVisible = true
+      this.getClaimLogList()
+    },
+    // 获取认领记录列表
+    getClaimLogList() {
+      this.claimLogLoading = true
+      // 构建参数,删除空值
+      const params = { ...this.claimLogQueryParams }
+      Object.keys(params).forEach(key => {
+        if (params[key] === null || params[key] === undefined || params[key] === '') {
+          delete params[key]
+        }
+      })
+      getCustomerLogList(params).then(response => {
+        this.claimLogList = response.rows || []
+        this.claimLogTotal = response.total || 0
+        this.claimLogLoading = false
+      }).catch(() => {
+        this.claimLogLoading = false
+        this.claimLogList = []
+        this.claimLogTotal = 0
+      })
+    }
   },
 }
 </script>