瀏覽代碼

客户信息

wjj 7 小時之前
父節點
當前提交
aef508688c
共有 2 個文件被更改,包括 807 次插入0 次删除
  1. 28 0
      src/api/qw/companyCustomer.js
  2. 779 0
      src/views/qw/companyCustomer/index.vue

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

@@ -0,0 +1,28 @@
+import request from '@/utils/request'
+
+// 查询客户列表
+export function listCustomer(query) {
+  return request({
+    url: '/qw/companyCustomer/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出客户
+export function exportCustomer(query) {
+    return request({
+        url: '/qw/companyCustomer/export',
+        method: 'get',
+        params: query
+    })
+  
+}
+
+// 查询客户详情
+export function getCustomer(id) {
+  return request({
+    url: '/qw/companyCustomer/' + id,
+    method: 'get'
+  })
+}

+ 779 - 0
src/views/qw/companyCustomer/index.vue

@@ -0,0 +1,779 @@
+<template>
+  <div class="app-container">
+    <!-- 搜索栏 -->
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      :inline="true"
+      v-show="showSearch"
+      label-width="80px"
+    >
+      <el-form-item label="客户姓名" prop="customerName">
+        <el-input
+          v-model="queryParams.customerName"
+          placeholder="请输入客户姓名"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="电话" prop="phone">
+        <el-input
+          v-model="queryParams.phone"
+          placeholder="请输入电话"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="客服姓名" prop="companyUserName">
+        <el-input
+          v-model="queryParams.companyUserName"
+          placeholder="请输入客服姓名"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="建档时间">
+        <el-date-picker
+          v-model="dateRange"
+          size="small"
+          style="width: 240px"
+          value-format="yyyy-MM-dd HH:mm:ss"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :default-time="['00:00:00', '23:59:59']"
+        ></el-date-picker>
+      </el-form-item>
+      <el-form-item label="生成时间">
+        <el-date-picker
+          v-model="createTimeRange"
+          size="small"
+          style="width: 240px"
+          value-format="yyyy-MM-dd HH:mm:ss"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :default-time="['00:00:00', '23:59:59']"
+        ></el-date-picker>
+      </el-form-item>
+      <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>
+      </el-form-item>
+      <el-form-item label="流程状态" prop="processStatus">
+        <el-select
+          v-model="queryParams.processStatus"
+          placeholder="请选择"
+          clearable
+          size="small"
+          style="width: 120px"
+        >
+          <el-option
+            v-for="item in processStatusOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="加微状态" prop="kdzlAddWechatStatus">
+        <el-select
+          v-model="queryParams.kdzlAddWechatStatus"
+          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="kdzlMakeStatus">
+        <el-select
+          v-model="queryParams.kdzlMakeStatus"
+          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="kdzlCallStatus">
+        <el-input
+          v-model="queryParams.kdzlCallStatus"
+          placeholder="示例:已接听、未接听"
+          clearable
+          size="small"
+          style="width: 150px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="购买次数">
+        <el-input-number
+          v-model="queryParams.minBuyCount"
+          :min="0"
+          size="small"
+          style="width: 100px"
+          controls-position="right"
+          placeholder="最少"
+        />
+        <span style="margin: 0 5px">-</span>
+        <el-input-number
+          v-model="queryParams.maxBuyCount"
+          :min="0"
+          size="small"
+          style="width: 100px"
+          controls-position="right"
+          placeholder="最多"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+
+    <!-- 工具栏 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          :loading="exportLoading"
+          v-hasPermi="['qw:companyCustomer:export']"
+          >导出</el-button
+        >
+      </el-col>
+
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+
+    <!-- 客户列表表格 -->
+    <el-table
+      v-loading="loading"
+      :data="customerList"
+      @selection-change="handleSelectionChange"
+      @sort-change="handleSortChange"
+    >
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="客户姓名" align="center" prop="customerName" />
+      <el-table-column
+        label="性别"
+        align="center"
+        prop="sex"
+        :formatter="sexFormat"
+      />
+      <el-table-column label="年龄" align="center" prop="age" />
+      <el-table-column
+        label="地址"
+        align="center"
+        prop="address"
+        show-overflow-tooltip
+      />
+      <el-table-column label="电话" align="center" prop="phone" />
+      <el-table-column
+        label="生成时间"
+        align="center"
+        prop="createTime"
+        width="180"
+        sortable="custom"
+      >
+        <template slot-scope="scope">{{
+          parseTime(scope.row.createTime)
+        }}</template>
+      </el-table-column>
+      <el-table-column
+        label="建档时间"
+        align="center"
+        prop="filingTime"
+        width="180"
+        sortable="custom"
+      >
+        <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="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">
+        <template slot-scope="scope">
+          <el-tag :type="scope.row.claimStatus === 1 ? 'success' : 'danger'">
+            {{ scope.row.claimStatus === 1 ? "已认领" : "待认领" }}
+          </el-tag>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="完善状态" align="center" prop="completeStatus">
+        <template slot-scope="scope">
+          <el-tag
+            :type="scope.row.completeStatus === 1 ? 'success' : 'warning'"
+          >
+            {{ scope.row.completeStatus === 1 ? "已完善" : "待完善" }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <!-- 【新增】流程状态 -->
+      <el-table-column
+        label="流程状态"
+        align="center"
+        prop="processStatus"
+        width="100"
+      >
+        <template slot-scope="scope">
+          <el-tag :type="getProcessStatusType(scope.row.processStatus)">
+            {{ getProcessStatusLabel(scope.row.processStatus) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <!-- 口袋助理-加微状态 -->
+      <el-table-column
+        label="口袋助理-加微状态"
+        align="center"
+        prop="kdzlAddWechatStatus"
+      >
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.kdzlAddWechatStatus === 1" type="success"
+            >已加</el-tag
+          >
+          <el-tag v-else-if="scope.row.kdzlAddWechatStatus === 0" type="warning"
+            >未加</el-tag
+          >
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
+
+      <!-- 口袋助理-成交状态 -->
+      <el-table-column
+        label="口袋助理-成交状态"
+        align="center"
+        prop="kdzlMakeStatus"
+      >
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.kdzlMakeStatus === 1" type="success"
+            >已成交</el-tag
+          >
+          <el-tag v-else-if="scope.row.kdzlMakeStatus === 0" type="warning"
+            >未成交</el-tag
+          >
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
+
+      <!-- 口袋助理-通话状态 -->
+      <el-table-column
+        label="口袋助理-通话状态"
+        align="center"
+        prop="kdzlCallStatus"
+      />
+      <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
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- ========== 新增/编辑/详情 弹窗 ========== -->
+    <el-dialog
+      :title="title"
+      :visible.sync="open"
+      width="1100px"
+      append-to-body
+      :close-on-click-modal="false"
+    >
+      <!-- 内容不变-->
+      <el-form ref="form" :model="form" label-width="100px" size="small">
+        <!-- 第一行 -->
+        <div
+          style="display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 15px"
+        >
+          <el-form-item
+            label="客户姓名"
+            prop="customerName"
+            style="flex: 1; min-width: 140px; margin-bottom: 0"
+          >
+            <el-input
+              v-model="form.customerName"
+              placeholder="请输入客户姓名"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+          <el-form-item
+            label="性别"
+            prop="sex"
+            style="flex: 0.6; min-width: 100px; margin-bottom: 0"
+          >
+            <el-select
+              v-model="form.sex"
+              placeholder="请选择"
+              style="width: 100%"
+              :disabled="isDetail"
+            >
+              <el-option
+                v-for="dict in sexOptions"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            label="年龄"
+            prop="age"
+            style="flex: 0.7; min-width: 120px; margin-bottom: 0"
+          >
+            <el-input-number
+              v-model="form.age"
+              :min="18"
+              :max="200"
+              placeholder="年龄"
+              controls-position="right"
+              style="width: 100%"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+          <el-form-item
+            label="电话"
+            prop="phone"
+            style="flex: 1.2; min-width: 150px; margin-bottom: 0"
+          >
+            <el-input
+              v-model="form.phone"
+              placeholder="请输入电话"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+        </div>
+        <!-- 第二行 -->
+        <div
+          style="display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 15px"
+        >
+          <el-form-item
+            label="地址"
+            prop="address"
+            style="flex: 2; min-width: 200px; margin-bottom: 0"
+          >
+            <el-input
+              v-model="form.address"
+              placeholder="请输入地址"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+          <el-form-item
+            label="建档时间"
+            prop="filingTime"
+            style="flex: 1; min-width: 180px; margin-bottom: 0"
+          >
+            <el-date-picker
+              v-model="form.filingTime"
+              type="datetime"
+              placeholder="选择建档时间"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+        </div>
+        <!-- 第三行 -->
+        <div
+          style="display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 15px"
+        >
+          <el-form-item
+            label="客服姓名"
+            prop="companyUserName"
+            style="flex: 1; min-width: 130px; margin-bottom: 0"
+          >
+            <el-input
+              v-model="form.companyUserName"
+              placeholder="客服姓名"
+              :disabled="isDetail"
+            />
+            <input type="hidden" v-model="form.companyUserId" />
+          </el-form-item>
+          <el-form-item
+            label="约诊时间"
+            prop="appointmentTime"
+            style="flex: 1.2; min-width: 180px; margin-bottom: 0"
+          >
+            <el-date-picker
+              v-model="form.appointmentTime"
+              type="datetime"
+              placeholder="选择约诊时间"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+          <el-form-item
+            label="负责医生"
+            prop="doctorName"
+            style="flex: 1; min-width: 130px; margin-bottom: 0"
+          >
+            <el-input
+              v-model="form.doctorName"
+              placeholder="负责医生"
+              :disabled="isDetail"
+            />
+            <input type="hidden" v-model="form.doctorId" />
+          </el-form-item>
+        </div>
+        <!-- 文本域 -->
+        <div style="margin-bottom: 15px">
+          <el-form-item
+            label="现病史"
+            prop="presentIllness"
+            style="margin-bottom: 0"
+          >
+            <el-input
+              type="textarea"
+              v-model="form.presentIllness"
+              placeholder="请输入现病史"
+              :rows="3"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+        </div>
+        <div style="margin-bottom: 15px">
+          <el-form-item
+            label="现用药情况"
+            prop="currentMedication"
+            style="margin-bottom: 0"
+          >
+            <el-input
+              type="textarea"
+              v-model="form.currentMedication"
+              placeholder="请输入现用药情况"
+              :rows="3"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+        </div>
+        <div style="margin-bottom: 0">
+          <el-form-item
+            label="过敏史"
+            prop="allergyHistory"
+            style="margin-bottom: 0"
+          >
+            <el-input
+              type="textarea"
+              v-model="form.allergyHistory"
+              placeholder="请输入过敏史"
+              :rows="3"
+              :disabled="isDetail"
+            />
+          </el-form-item>
+        </div>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancel">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listCustomer,
+  getCustomer,
+  exportCustomer,
+} from "@/api/qw/companyCustomer";
+export default {
+  name: "Customer",
+  data() {
+    return {
+      // 导出遮罩层
+      exportLoading: false,
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      form: {},
+      isDetail: false,
+      title: "",
+      open: false,
+      // 客户列表
+      customerList: [],
+      dateRange: [],
+      createTimeRange: [],
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        customerName: null,
+        phone: null,
+        companyUserName: null,
+        claimStatus: null,
+        completeStatus: null,
+        kdzlAddWechatStatus: null,
+        kdzlMakeStatus: null,
+        kdzlCallStatus: null,
+        minBuyCount: null,
+        maxBuyCount: null,
+        sortField: null, //排序字段 (create_time / filing_time)
+        sortOrder: null, //排序方向 (asc / desc)
+      },
+      // 【新增】流程状态映射
+      processStatusOptions: [
+        { value: 0, label: "待完善", type: "info" },
+        { value: 1, label: "待开方", type: "primary" },
+        { value: 2, label: "开方中", type: "warning" },
+        { value: 3, label: "待审核", type: "warning" },
+        { value: 4, label: "已开方", type: "success" },
+        { value: 5, label: "已拒方", type: "danger" },
+        { value: 6, label: "已完成", type: "success" },
+      ],
+      sexOptions: [
+        { label: "女", value: "0" },
+        { label: "男", value: "1" },
+        { label: "未知", value: "2" },
+      ],
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      this.loading = true;
+      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];
+      }
+      // 传递排序参数(如果存在)
+      if (params.sortField && params.sortOrder) {
+        // 直接保留,后端会接收
+      }
+      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;
+          this.loading = false;
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+    },
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+
+    resetQuery() {
+      this.dateRange = [];
+      this.createTimeRange = [];
+      this.resetForm("queryForm");
+      this.queryParams.claimStatus = null;
+      this.queryParams.completeStatus = null;
+      this.queryParams.minBuyCount = null;
+      this.queryParams.maxBuyCount = null;
+      // 清空口袋助理相关查询条件
+      this.queryParams.kdzlAddWechatStatus = null;
+      this.queryParams.kdzlMakeStatus = null;
+      this.queryParams.kdzlCallStatus = null;
+      // 清空排序
+      this.queryParams.sortField = null;
+      this.queryParams.sortOrder = null;
+      this.queryParams.processStatus = null;
+      this.handleQuery();
+    },
+
+    handleDetail(row) {
+      getCustomer(row.id)
+        .then((response) => {
+          this.form = response.data;
+          if (this.form.sex !== undefined && this.form.sex !== null) {
+            this.form.sex = String(this.form.sex);
+          }
+          this.isDetail = true;
+          this.open = true;
+          this.title = "客户详情";
+        })
+        .catch(() => {
+          this.$message.error("获取客户详情失败");
+        });
+    },
+
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    reset() {
+      this.form = {
+        id: null,
+        customerName: null,
+        sex: null,
+        age: undefined,
+        address: null,
+        phone: null,
+        filingTime: null,
+        companyUserId: null,
+        companyUserName: null,
+        appointmentTime: null,
+        doctorId: null,
+        doctorName: null,
+        presentIllness: null,
+        currentMedication: null,
+        allergyHistory: null,
+      };
+      this.resetForm("form");
+      this.isDetail = false;
+    },
+
+    handleSelectionChange(selection) {
+      this.ids = selection.map((item) => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    handleSortChange({ prop, order }) {
+      // prop: 'createTime' 或 'filingTime'
+      // order: 'ascending' 或 'descending',无排序时为 null
+      if (!order) {
+        // 清除排序
+        this.queryParams.sortField = null;
+        this.queryParams.sortOrder = null;
+      } else {
+        // 映射前端字段名到数据库字段名
+        this.queryParams.sortField =
+          prop === "createTime" ? "create_time" : "filing_time";
+        this.queryParams.sortOrder = order === "ascending" ? "asc" : "desc";
+      }
+      // 重置到第一页
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    sexFormat(row) {
+      return this.sexOptions.find((o) => o.value === row.sex)?.label ?? row.sex;
+    },
+    // 【新增】获取流程状态标签类型(颜色)
+    getProcessStatusType(status) {
+      if (status === null || status === undefined || status === "")
+        return "info";
+      const option = this.processStatusOptions.find(
+        (item) => item.value === status
+      );
+      return option ? option.type : "info";
+    },
+    // 【新增】获取流程状态标签文本
+    getProcessStatusLabel(status) {
+      if (status === null || status === undefined || status === "") return "-";
+      const option = this.processStatusOptions.find(
+        (item) => item.value === status
+      );
+      return option ? option.label : "未知";
+    },
+    // 【新增】获取流程状态标签类型(颜色)
+    getProcessStatusType(status) {
+      if (status === null || status === undefined || status === "")
+        return "info";
+      const option = this.processStatusOptions.find(
+        (item) => item.value === status
+      );
+      return option ? option.type : "info";
+    },
+
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm("是否确认导出所有理疗配置数据项?", "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.exportLoading = true;
+          return exportCustomer(queryParams);
+        })
+        .then((response) => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        })
+        .catch(() => {});
+    },
+
+    addDateRange(params, dateRange) {
+      if (dateRange && dateRange.length === 2) {
+        params.beginTime = dateRange[0];
+        params.endTime = dateRange[1];
+      }
+      return params;
+    },
+  },
+};
+</script>