Browse Source

feat:新增数据-订单明细功能模块

xiexaing 1 năm trước cách đây
mục cha
commit
2b0d4643f9

BIN
dist.rar


+ 2 - 0
src/api/api.js

@@ -20,6 +20,7 @@ import goodmenuCourses from '../newApi/menuCourse'//课程目录
 import paper from '../newApi/paper' //题库试卷管理
 import bankChapter from '../newApi/bankChapter'//题库大章管理
 import moduleBank from '../newApi/moduleBank'//题库模块管理
+import orderDetail from '../newApi/orderDetail' // 数据-订单详情
 
 
 import pay from '../newApi/pay'//支付
@@ -190,5 +191,6 @@ export default {
     ...mock,
     ...mockSub,
     ...systemExam,
+    ...orderDetail,
 
 }

+ 92 - 0
src/newApi/orderDetail.js

@@ -0,0 +1,92 @@
+import request from "@/utils/request"; //引入axios请求及拦截器
+export default {
+  //查询订单列表
+  orderDetailList(data) {
+    return request({
+      url: "/system/top/order/rep/list",
+      method: "get",
+      params: data,
+      isProce: true
+    });
+  },
+  //查询订单详情(子列表)
+  subOrderDetailList(data) {
+    return request({
+      url: "/system/top/order/rep/goods/detail",
+      method: "get",
+      params: data,
+    });
+  },
+  //订单明细修改
+  editOrderDetail(data) {
+    return request({
+      url: "/system/top/order/rep/edit",
+      method: "post",
+      data,
+    });
+  },
+  //订单明细详情修改(子列表修改)
+  editSubOrderDetail(data) {
+    return request({
+      url: "/system/top/order/rep/detail/edit",
+      method: "post",
+      data,
+    });
+  },
+  //订单题库开通列表
+  orderQuestionBankList(data) {
+    return request({
+      url: "/system/top/order/rep/question/list",
+      method: "get",
+      params: data,
+    });
+  },
+
+  //订单题库开通详情
+  orderQuestionBankDetail(data) {
+    return request({
+      url: "/system/top/order/rep/question/detail",
+      method: "get",
+      params: data,
+    });
+  },
+  //新增订单题库开通记录
+  addOrderQuestionBank(data) {
+    return request({
+      url: "/system/top/order/rep/save/question",
+      method: "post",
+      data,
+    });
+  },
+  //删除订单题库开通记录
+  delOrderQuestionBank(data) {
+    return request({
+      url: "/system/top/order/rep/del/question/" + data,
+      method: "get",
+    });
+  },
+  // 账单记录打印(导出)
+  billPrint(data) {
+    return request({
+      url: "/system/top/order/rep/bill/export",
+      method: "get",
+      params: data,
+    });
+  },
+  //订单题库开通记录导入
+  recordUpdateImport(data) {
+    return request({
+      url: "/system/top/order/rep/import/question",
+      method: "post",
+      data,
+    });
+  },
+  //批量新增订单题库开通记录
+  addRecordUpdate(data) {
+    return request({
+      url: "/system/top/order/rep/batch/save/question",
+      method: "post",
+      data,
+    });
+  },
+};

+ 2 - 0
src/utils/request.js

@@ -10,6 +10,8 @@ axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
 export const baseURL = process.env.VUE_APP_BASE_API
 // export const baseURL = 'https://ptapi.gdzzkj.net/'
 // export const baseURL = "http://192.168.1.7:7077/";
+// export const baseURL = "http://192.168.1.123:7077/";
+
 export const BASE_IMG_URL = process.env.VUE_APP_IMG_API;
 const service = axios.create({
   // axios中请求配置有baseURL选项,表示请求URL公共部分

+ 134 - 0
src/views/orderData/orderDetail/addQuestionBankDialog.vue

@@ -0,0 +1,134 @@
+<template>
+  <div>
+    <BaseDialog
+      width="450px"
+      :isShow.sync="isDialog"
+      title="新增"
+      :appendToBody="true"
+      @close="close"
+      @submit="submitForm"
+    >
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="100px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="姓名:" prop="userName">
+          <el-input
+            v-model="ruleForm.userName"
+            placeholder="请输入"
+            :disabled="true"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="身份证号:" prop="userCard">
+          <el-input
+            v-model="ruleForm.userCard"
+            placeholder="请输入"
+            :disabled="true"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="教育类型:" prop="eduName">
+          <el-input
+            v-model="ruleForm.eduName"
+            placeholder="请选择"
+            :disabled="true"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="业务层次:" prop="businessName">
+          <el-input
+            v-model="ruleForm.businessName"
+            placeholder="请选择"
+            :disabled="true"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="专业:" prop="majorName">
+          <el-input
+            v-model="ruleForm.majorName"
+            placeholder="请选择"
+            :disabled="true"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="开通日期:" prop="openDate">
+          <el-date-picker
+            v-model="ruleForm.openDate"
+            type="datetime"
+            placeholder="请选择日期"
+            value-format="timestamp"
+            style="width: 99%"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="" prop="sign">
+          <el-input
+            v-model="ruleForm.sign"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </BaseDialog>
+  </div>
+</template>
+    
+<script>
+export default {
+  data() {
+    return {
+      isDialog: false,
+      ruleForm: {},
+      rules: {
+        openDate: [
+          { required: true, message: "开通日期不能为空", trigger: "blur" },
+        ],
+      },
+    };
+  },
+  mounted() {},
+  methods: {
+    openBoxs(row, type) {
+      this.isDialog = true;
+      this.search(row)
+    },
+    search(row) {
+      this.$api
+        .orderQuestionBankDetail(row)
+        .then((res) => {
+          this.ruleForm = res.data;
+        })
+        .finally(() => {});
+    },
+    close() {
+      this.ruleForm = {};
+      this.$refs["ruleForm"].resetFields();
+    },
+    submitForm() {
+      this.$refs["ruleForm"].validate((valid) => {
+        if (valid) {
+          const data = {
+            openDate: this.$methodsTools.time10to13(this.ruleForm.openDate, 1),
+            orderGoodsId: this.ruleForm.orderGoodsId,
+            orderSn: this.ruleForm.orderSn,
+            sign: this.ruleForm.sign,
+          };
+          this.$api
+            .addOrderQuestionBank(data)
+            .then((res) => {
+              this.$message.success("操作成功");
+              this.$emit("refresh");
+            })
+            .finally(() => {
+              this.isDialog = false;
+            });
+        } else {
+          return false;
+        }
+      });
+    },
+  },
+};
+</script>
+    
+  <style lang="scss" scoped>
+</style>
+    

+ 93 - 0
src/views/orderData/orderDetail/earnRecordDialog.vue

@@ -0,0 +1,93 @@
+<template>
+  <div>
+    <BaseDialog
+      width="600px"
+      :isShow.sync="isDialog"
+      :title="dialogTitle"
+      :confirmName="confirmName"
+      @close="close"
+      @submit="submitForm"
+    >
+      <div class="text" v-if="dialogTitle === '收款记录'">
+        {{ ruleForm.proceedsRecord }}
+      </div>
+      <el-input
+        v-else
+        :rows="6"
+        type="textarea"
+        placeholder="请输入"
+        v-model="ruleForm.proceedsRecord"
+      ></el-input>
+    </BaseDialog>
+  </div>
+</template>
+  
+  <script>
+export default {
+  data() {
+    return {
+      isDialog: false,
+      dialogTitle: "收款记录",
+      confirmName: "确 定",
+      ruleForm: {
+        proceedsRecord: "",
+      },
+    };
+  },
+  mounted() {},
+  methods: {
+    openBoxs(row, type) {
+      if (type === "check") {
+        this.dialogTitle = "收款记录";
+        this.confirmName = "修 改";
+      } else {
+        this.dialogTitle = "收款记录修改";
+        this.confirmName = "确 定";
+      }
+      this.isDialog = true;
+      this.ruleForm = JSON.parse(JSON.stringify(row));
+    },
+    close() {
+      this.ruleForm = {};
+    },
+    submitForm() {
+      if (this.dialogTitle === "收款记录") {
+        this.dialogTitle = "收款记录修改";
+        this.confirmName = "确 定";
+        return;
+      }
+      // 日期时间进行提交时需要(/1000)操作
+      this.ruleForm["proceedsDate"] = this.$methodsTools.time10to13(
+        this.ruleForm["proceedsDate"],
+        1
+      );
+      this.ruleForm["proceedsCheckDate"] = this.$methodsTools.time10to13(
+        this.ruleForm["proceedsCheckDate"],
+        1
+      );
+      delete this.ruleForm.isEdit;
+      delete this.ruleForm.subTableList;
+      this.$api
+        .editOrderDetail(this.ruleForm)
+        .then((res) => {
+          this.$message.success("操作成功");
+          this.$emit("refresh");
+        })
+        .finally(() => {
+          this.isDialog = false;
+        });
+    },
+  },
+};
+</script>
+  
+<style lang="scss" scoped>
+.text {
+  white-space: pre-line;
+  line-height: 35px;
+  color: #333;
+  max-height: 260px;
+  overflow-y: auto;
+}
+</style>
+  

+ 1423 - 0
src/views/orderData/orderDetail/index.vue

@@ -0,0 +1,1423 @@
+<template>
+  <div id="businessLevel">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    >
+      <template slot="slotSearch">
+        <el-input
+          placeholder="输入订单编号/业务员/业务号/所属客户"
+          v-model="formData['keyword']"
+          clearable
+          style="width: 360px"
+        >
+        </el-input>
+      </template>
+    </search-box-new>
+    <div id="tableList">
+      <div class="headerNavTool">
+        <div class="leftIndexText">
+          {{ navText.title }}
+          <strong>{{ navText.index }}</strong>
+          {{ navText.ch }}
+          <span style="color: #999; font-size: 14px; margin-left: 10px"
+            ><i class="el-icon-warning-outline"></i>
+            点击数据,左右键盘可滑动数据表。</span
+          >
+        </div>
+        <div class="rightBtnBox">
+          <slot name="customize"></slot>
+          <el-button
+            type="primary"
+            :loading="billPrintLoading"
+            @click="handleBillPrint"
+            >账单打印</el-button
+          >
+          <el-button type="primary" @click="openRecordUpdateDialog"
+            >记录更新</el-button
+          >
+          <el-popover
+            popper-class="slotPopper"
+            placement="bottom-end"
+            trigger="click"
+          >
+            <div class="popoverDis">
+              <div class="checkboxHeader">
+                <el-checkbox
+                  :indeterminate="isIndeterminate"
+                  v-model="checkAll"
+                  @change="handleCheckAllChange"
+                  >列展示</el-checkbox
+                >
+                <div class="initbtns" @click="initVue">重置</div>
+              </div>
+
+              <div
+                style="height: 1px; width: 100%; background-color: #eaeefb"
+              ></div>
+              <el-checkbox-group
+                class="checkboxGroup"
+                v-model="checkedCities"
+                @change="handleCheckedCitiesChange"
+              >
+                <div
+                  class="checkboxchild"
+                  v-for="(item, index) in cities"
+                  :key="index"
+                >
+                  <el-checkbox
+                    :label="item"
+                    @change="checkboxChange(item, $event)"
+                    >{{ item }}</el-checkbox
+                  >
+                  <div class="icon-right">
+                    <i class="el-icon-upload2" @click="upMove(item, index)"></i>
+                    <i
+                      class="el-icon-download"
+                      @click="downMove(item, index)"
+                    ></i>
+                  </div>
+                </div>
+              </el-checkbox-group>
+            </div>
+            <el-button
+              v-if="navText.custom !== false"
+              style="margin-left: 10px"
+              slot="reference"
+              >自定义列</el-button
+            >
+          </el-popover>
+        </div>
+      </div>
+      <el-table
+        ref="tableRef"
+        :row-key="(row) => row.orderSn"
+        :data="tableData"
+        show-summary
+        :summary-method="getSummaries"
+        style="width: 100%"
+        :cell-style="timeStyle"
+        v-loading="loading"
+        :header-cell-style="{
+          'background-color': '#eee',
+          color: '#333',
+          fontSize: '14px',
+        }"
+        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+        @expand-change="openContentShow"
+      >
+        <el-table-column type="expand">
+          <template slot="header">
+            <div
+              class="headShow"
+              :class="[headShow ? 'el-icon-minus' : 'el-icon-plus']"
+              @click="openHeadShow"
+            ></div>
+          </template>
+          <template slot-scope="scope">
+            <div style="display: flex">
+              <div style="width: 50px; background: #eeeeee"></div>
+              <!-- 子列表 -->
+              <el-table
+                v-loading="scope.row.subLoading"
+                :data="scope.row.subTableList"
+                :header-cell-style="{
+                  'background-color': '#eee',
+                  color: '#333',
+                  fontSize: '14px',
+                }"
+              >
+                <af-table-column
+                  v-for="(subItem, subIndex) in subTableSet"
+                  :width="subItem.width"
+                  :label="subItem.label"
+                  :align="subItem.dontCenter ? 'left' : 'center'"
+                  header-align="center"
+                  :prop="subItem.prop"
+                  :key="subIndex"
+                >
+                  <template slot-scope="subScope">
+                    <div v-if="subItem.edit">
+                      <div v-if="subScope.row.isEdit[subIndex]">
+                        <el-date-picker
+                          v-model="subScope.row[subItem.prop]"
+                          type="date"
+                          placeholder="请选择日期"
+                          value-format="timestamp"
+                          style="width: 99%"
+                        >
+                        </el-date-picker>
+                      </div>
+                      <div v-else style="padding: 8px">
+                        {{
+                          subScope.row[subItem.prop]
+                            ? $methodsTools.onlyForma(
+                                subScope.row[subItem.prop] / 1000,
+                                false
+                              )
+                            : "-"
+                        }}
+                      </div>
+                      <div style="margin-top: 2px">
+                        <div v-if="subScope.row.isEdit[subIndex]">
+                          <sapn
+                            class="inputBtn"
+                            @click="
+                              editNumber(
+                                subIndex,
+                                subScope.row,
+                                'confirm',
+                                scope.row
+                              )
+                            "
+                            >确定</sapn
+                          >
+                          <sapn
+                            class="inputBtn"
+                            @click="
+                              editNumber(subIndex, subScope.row, 'cancel')
+                            "
+                            >取消</sapn
+                          >
+                        </div>
+                        <sapn
+                          v-else
+                          class="inputBtn editInputBtn"
+                          @click="editNumber(subIndex, subScope.row, 'edit')"
+                        >
+                          修改
+                        </sapn>
+                      </div>
+                    </div>
+                    <div v-else-if="subItem.label === '性别'">
+                      {{
+                        subScope.row[subItem.prop] == 1
+                          ? "男"
+                          : subScope.row[subItem.prop] == 2
+                          ? "女"
+                          : "未知"
+                      }}
+                    </div>
+                    <div v-else-if="subItem.label === '状态'">
+                      <div>
+                        {{
+                          subScope.row[subItem.prop] == 2 ? "已退款" : "正常"
+                        }}
+                      </div>
+                      <!-- 状态为已退款显示 -->
+                      <div
+                        style="white-space: nowrap"
+                        v-if="
+                          subScope.row.refundStatus == 2 &&
+                          subScope.row.refundTime
+                        "
+                      >
+                        ({{
+                          $methodsTools.onlyForma(subScope.row.refundTime)
+                        }})
+                      </div>
+                    </div>
+                    <div v-else-if="subItem.label === '成交单价'">
+                      ¥{{ subScope.row[subItem.prop] }}
+                    </div>
+                    <div v-else>
+                      <div>
+                        {{
+                          subScope.row[subItem.prop] == undefined ||
+                          subScope.row[subItem.prop] == null
+                            ? "-"
+                            : subScope.row[subItem.prop]
+                        }}
+                      </div>
+                      <span
+                        v-if="subItem.label === '题库记录'"
+                        class="inputBtn editInputBtn"
+                        @click="openQuestionBankDialog(subScope.row)"
+                      >
+                        更新
+                      </span>
+                    </div>
+                  </template>
+                </af-table-column>
+                <el-table-column style="width: 100%"> </el-table-column>
+              </el-table>
+            </div>
+            <div style="margin: 0 0 15px 0">
+              <pagination
+                :total="scope.row.subTotal"
+                :pageSize="scope.row.subPageSize"
+                :currentPage="scope.row.subPageNum"
+                @handleSizeChange="subHandleSizeChange($event, scope.row)"
+                @handleCurrentChange="subHandleCurrentChange($event, scope.row)"
+              />
+            </div>
+          </template>
+        </el-table-column>
+
+        <!-- 主列表 -->
+        <el-table-column
+          type="index"
+          label="序号"
+          width="70"
+          align="center"
+          header-align="center"
+        >
+        </el-table-column>
+
+        <af-table-column
+          v-for="(item, columnIndex) in compTableSet(tableSet)"
+          :label="item.label"
+          :align="item.dontCenter ? 'left' : 'center'"
+          :prop="item.prop"
+          :key="columnIndex"
+          :width="item.inputType ? '160' : ''"
+          style="white-space: nowrap"
+        >
+          <template slot-scope="scope">
+            <div v-if="item.edit">
+              <div v-if="scope.row.isEdit[columnIndex]">
+                <!-- 月份编辑 -->
+                <el-input
+                  v-if="
+                    item.inputType === 'number' && item.label.includes('月')
+                  "
+                  :type="item.inputType"
+                  placeholder="请输入"
+                  v-model="scope.row.proceedsJson[item.prop]"
+                  style="width: 99%"
+                >
+                  <div slot="prefix" style="margin-top: 6px">¥</div>
+                </el-input>
+                <!-- 日期编辑 -->
+                <el-date-picker
+                  v-else-if="item.inputType === 'date'"
+                  v-model="scope.row[item.prop]"
+                  :type="item.inputType"
+                  placeholder="请选择日期"
+                  value-format="timestamp"
+                  style="width: 99%"
+                >
+                </el-date-picker>
+                <!-- 其他编辑 -->
+                <el-input
+                  v-else
+                  :type="item.inputType"
+                  placeholder="请输入"
+                  v-model="scope.row[item.prop]"
+                  style="width: 99%"
+                >
+                  <div
+                    v-if="item.label == '成本支付'"
+                    slot="prefix"
+                    style="margin-top: 6px"
+                  >
+                    ¥
+                  </div>
+                </el-input>
+              </div>
+              <div v-else style="padding: 8px">
+                {{ getEditValueName(item, scope) }}
+              </div>
+              <div style="margin-top: 2px; white-space: nowrap">
+                <div v-if="scope.row.isEdit[columnIndex]">
+                  <sapn
+                    class="inputBtn"
+                    @click="editNumber(columnIndex, scope.row, 'confirm', null)"
+                    >确定</sapn
+                  >
+                  <sapn
+                    class="inputBtn"
+                    @click="editNumber(columnIndex, scope.row, 'cancel')"
+                    >取消</sapn
+                  >
+                </div>
+                <sapn
+                  v-else
+                  class="inputBtn editInputBtn"
+                  @click="editNumber(columnIndex, scope.row, 'edit')"
+                >
+                  修改
+                </sapn>
+              </div>
+            </div>
+            <div v-else-if="item.label === '收款记录'">
+              <sapn
+                class="inputBtn"
+                @click="openEarnRecordDialog(scope.row, 'check')"
+              >
+                查看
+              </sapn>
+              <div>
+                <sapn
+                  class="inputBtn editInputBtn"
+                  @click="openEarnRecordDialog(scope.row, 'edit')"
+                >
+                  修改
+                </sapn>
+              </div>
+            </div>
+            <div v-else>
+              <template v-if="item.list">
+                <div v-for="(content, i) in item.list" :key="i">
+                  <div>
+                    {{ content.name }} :
+                    {{
+                      item.label == "订单时间"
+                        ? $methodsTools.onlyForma(scope.row[content.key])
+                        : scope.row[content.key]
+                    }}
+                  </div>
+                </div>
+              </template>
+              <div v-else>
+                {{ getEditValueName(item, scope) }}
+              </div>
+            </div>
+          </template>
+        </af-table-column>
+      </el-table>
+    </div>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <!-- 收款记录弹窗 -->
+    <earnRecordDialog ref="earnRecordDialog" @refresh="search()" />
+    <!-- 题库记录弹窗 -->
+    <questionBankDialog ref="questionBankDialog" />
+    <!-- 记录更新弹窗 -->
+    <recordUpdateDialog ref="recordUpdateDialog" />
+  </div>
+</template>
+  
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import pagination from "@/components/pagination";
+import earnRecordDialog from "./earnRecordDialog.vue";
+import questionBankDialog from "./questionBankDialog.vue";
+import recordUpdateDialog from "./recordUpdateDialog.vue";
+import * as baseUrls from "@/utils/request.js";
+import { exportFn } from "@/utils/index.js";
+export default {
+  components: {
+    searchBoxNew,
+    pagination,
+    earnRecordDialog,
+    questionBankDialog,
+    recordUpdateDialog,
+  },
+  data() {
+    return {
+      disabledBtn: false,
+      headShow: false, // 展开全部行
+      loading: false, //当前表单加载是否加载动画
+      billPrintLoading: false, // 账单打印加载动画
+      navText: {
+        title: "2024年祥粤订单销售、收款、回证登记明细表",
+        index: 0,
+        ch: "条",
+        custom: true,
+      },
+      //搜索
+      formList: [
+        {
+          prop: "orderOrg",
+          placeholder: "订单来源",
+          scope: "select",
+          noClear: false,
+          options: [
+            {
+              label: "旧云学堂",
+              value: "旧云学堂",
+            },
+            {
+              label: "业务系统",
+              value: "业务系统",
+            },
+            {
+              label: "C端云学堂线下",
+              value: "C端云学堂线下",
+            },
+            {
+              label: "C端云学堂线上",
+              value: "C端云学堂线上",
+            },
+          ],
+        },
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "creditStatus",
+          placeholder: "账款状态",
+          scope: "select",
+          noClear: false,
+          options: [
+            {
+              label: "已结清",
+              value: 1,
+            },
+            {
+              label: "未结清",
+              value: 0,
+            },
+          ],
+        },
+        {
+          prop1: "startTime",
+          prop2: "endTime",
+          placeholder1: "申请时间开始",
+          placeholder2: "申请时间结束",
+          scope: "moreDataPicker",
+        },
+        {
+          prop1: "checkStartTime",
+          prop2: "checkEndTime",
+          placeholder1: "通过时间开始",
+          placeholder2: "通过时间结束",
+          scope: "moreDataPicker",
+        },
+        {
+          prop: "userName",
+          placeholder: "输入学员姓名",
+        },
+        {
+          prop: "userCard",
+          placeholder: "输入身份证号",
+        },
+        {
+          scope: "solt",
+          soltName: "slotSearch",
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "来源/编号",
+          prop: "orderOrgAndorderSn",
+          hidden: true,
+          dontCenter: "left",
+          list: [
+            {
+              name: "订单来源",
+              key: "orderOrg",
+            },
+            {
+              name: "订单编号",
+              key: "orderSn",
+            },
+          ],
+        },
+        {
+          label: "订单时间",
+          prop: "orderTimeAndcheckTime",
+          hidden: true,
+          dontCenter: "left",
+          list: [
+            {
+              name: "申请时间",
+              key: "orderTime",
+            },
+            {
+              name: "通过时间",
+              key: "checkTime",
+            },
+          ],
+        },
+        {
+          label: "业务信息",
+          prop: "createUsernameAndcreateNo",
+          hidden: true,
+          dontCenter: "left",
+          list: [
+            {
+              name: "业务员",
+              key: "createUsername",
+            },
+            {
+              name: "业务号",
+              key: "createNo",
+            },
+          ],
+        },
+        {
+          label: "订单所属",
+          prop: "tenantNameAndpurchaseOrg",
+          hidden: true,
+          dontCenter: "left",
+          list: [
+            {
+              name: "所属机构",
+              key: "tenantName",
+            },
+            {
+              name: "所属客户",
+              key: "purchaseOrg",
+            },
+          ],
+        },
+        {
+          label: "业务类型",
+          prop: "businessAndType",
+          hidden: true,
+          dontCenter: "left",
+          list: [
+            {
+              name: "业务简称",
+              key: "businessAbbreviation",
+            },
+            {
+              name: "教育类型",
+              key: "eduName",
+            },
+            {
+              name: "业务层次",
+              key: "businessName",
+            },
+          ],
+        },
+        // {
+        //   label: "成交单价",
+        //   prop: "educationName",
+        //   hidden: true,
+        // },
+        {
+          label: "成交数量",
+          prop: "concludeNum",
+          hidden: true,
+        },
+        {
+          label: "成交总价",
+          prop: "priceTotal",
+          hidden: true,
+        },
+        {
+          label: "1月",
+          prop: "one",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "2月",
+          prop: "two",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "3月",
+          prop: "three",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "4月",
+          prop: "four",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "5月",
+          prop: "five",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "6月",
+          prop: "six",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "7月",
+          prop: "seven",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "8月",
+          prop: "eight",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "9月",
+          prop: "nine",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "10月",
+          prop: "ten",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "11月",
+          prop: "eleven",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "12月",
+          prop: "twelve",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "12月以后",
+          prop: "other",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "已退金额",
+          prop: "refunded",
+          hidden: true,
+        },
+        {
+          label: "实际账款",
+          prop: "practical",
+          hidden: true,
+        },
+        {
+          label: "已收金额",
+          prop: "received",
+          hidden: true,
+        },
+        {
+          label: "未收金额",
+          prop: "uncollected",
+          hidden: true,
+        },
+        {
+          label: "收款记录",
+          prop: "proceedsRecord",
+          hidden: true,
+        },
+        {
+          label: "发票申请日期",
+          prop: "invoiceApplyTime",
+          hidden: true,
+        },
+        {
+          label: "发票类型",
+          prop: "invoiceType",
+          hidden: true,
+        },
+        {
+          label: "积分",
+          prop: "integral",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+        {
+          label: "日期",
+          prop: "proceedsDate",
+          hidden: true,
+          edit: true,
+          inputType: "date",
+        },
+        {
+          label: "收入核对日期",
+          prop: "proceedsCheckDate",
+          hidden: true,
+          edit: true,
+          inputType: "date",
+        },
+        {
+          label: "变化",
+          prop: "proceedsChange",
+          hidden: true,
+          edit: true,
+          inputType: "text",
+        },
+        {
+          label: "成本支付",
+          prop: "cost",
+          hidden: true,
+          edit: true,
+          inputType: "number",
+        },
+      ],
+      // 子列表
+      subTableSet: [
+        {
+          label: "姓名",
+          prop: "userName",
+          width: "100",
+        },
+        {
+          label: "性别",
+          prop: "sex",
+          width: "100",
+        },
+        {
+          label: "身份证号",
+          prop: "userCard",
+          width: "230",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+          width: "360",
+        },
+        {
+          label: "年份",
+          prop: "goodsYear",
+          width: "100",
+        },
+        {
+          label: "专业",
+          prop: "majorName",
+          width: "200",
+        },
+        {
+          label: "成交单价",
+          prop: "goodsPrice",
+          width: "200",
+        },
+        {
+          label: "完单日期",
+          prop: "finishTime",
+          edit: true,
+          inputType: "date",
+          width: "160",
+        },
+        {
+          label: "回证/公示日期",
+          prop: "publicityTime",
+          edit: true,
+          inputType: "date",
+          width: "160",
+        },
+        {
+          label: "领证日期",
+          prop: "acquireTime",
+          edit: true,
+          inputType: "date",
+          width: "160",
+        },
+        {
+          label: "补考次数",
+          prop: "applyNum",
+          width: "100",
+        },
+        {
+          label: "题库记录",
+          prop: "questionRecord",
+          width: "100",
+        },
+        {
+          label: "状态",
+          prop: "refundStatus",
+          width: "200",
+        },
+      ],
+      checkedCities: [], //自定义列 选中数组
+      cities: [], //自定义列 总数组
+      isIndeterminate: false, // 用于全选操作
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  computed: {
+    // 用于自定义列
+    compTableSet: function () {
+      return function (options) {
+        var arrays = options.filter((item) => {
+          return item.hidden;
+        });
+        return arrays;
+      };
+    },
+    //可编辑区域的 显示的value值
+    getEditValueName: function () {
+      return function (item, scope) {
+        let value = scope.row[item.prop];
+        if (item.inputType === "date") {
+          return this.$methodsTools.onlyForma(value / 1000, false) || "-";
+        }
+        if (
+          (scope.row.proceedsJson &&
+            scope.row.proceedsJson[item.prop] != undefined) ||
+          scope.row.proceedsJson[item.prop] != null
+        ) {
+          return "¥" + scope.row.proceedsJson[item.prop] || "-";
+        }
+        if (["成交数量", "变化", "积分", "发票类型"].includes(item.label)) {
+          return value == undefined || value == null ? "-" : value;
+        }
+        if (item.label == "发票申请日期" && value) {
+          return this.$methodsTools.onlyForma(value, false) || "-";
+        }
+        return value == undefined || value == null ? "-" : "¥" + value;
+      };
+    },
+  },
+  created() {},
+  mounted() {
+    this.inittableSet = JSON.stringify(this.tableSet);
+    this.initTR();
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    editNumber(columnIndex, row, type, saveRow) {
+      console.log(row);
+      switch (type) {
+        case "edit":
+          this.$set(row.isEdit, columnIndex, true);
+          break;
+        case "cancel":
+          this.$set(row.isEdit, columnIndex, false);
+          break;
+        case "confirm":
+          this.$set(row.isEdit, columnIndex, false);
+          this.handleListEdit(columnIndex, row, saveRow);
+          break;
+        default:
+          break;
+      }
+    },
+    //列表修改操作
+    handleListEdit(columnIndex, row, saveRow) {
+      const data = JSON.parse(JSON.stringify(row));
+      let propName;
+      //saveRow有值为子列表修改
+      if (saveRow) {
+        propName = this.subTableSet[columnIndex].prop;
+      } else {
+        propName = this.tableSet[columnIndex].prop;
+        // // 月份提交
+        // data.proceedsJson = row.proceedsJsonMap;
+      }
+      data[propName] = row[propName];
+      // 日期时间进行提交时需要(/1000)操作
+      [
+        "proceedsDate",
+        "proceedsCheckDate",
+        "finishTime",
+        "publicityTime",
+        "acquireTime",
+      ].forEach((timeKey) => {
+        data[timeKey] = this.$methodsTools.time10to13(row[timeKey], 1);
+      });
+      delete data.isEdit;
+      delete data.subTableList;
+
+      console.log(data, "------data-----");
+      const _request = saveRow ? "editSubOrderDetail" : "editOrderDetail";
+      this.$api[_request](data)
+        .then((res) => {
+          if (saveRow) {
+            this.getSubTableList(saveRow);
+          } else {
+            this.search();
+          }
+          this.$message.success("操作成功");
+        })
+        .catch(() => {
+          this.$message.error("操作失败");
+        });
+    },
+    // 打开收款记录弹窗
+    openEarnRecordDialog(row, type) {
+      this.$refs.earnRecordDialog.openBoxs(row, type);
+    },
+    // 打开题库记录弹窗
+    openQuestionBankDialog(row) {
+      this.$refs.questionBankDialog.openBoxs(row);
+    },
+    // 打开更新记录弹窗
+    openRecordUpdateDialog() {
+      this.$refs.recordUpdateDialog.openBoxs();
+    },
+    // 账单打印
+    handleBillPrint() {
+      const data = JSON.parse(JSON.stringify(this.formData));
+      ["startTime", "endTime", "checkStartTime", "checkEndTime"].forEach(
+        (key) => {
+          data[key] = data[key] ? data[key] / 1000 : "";
+        }
+      );
+      delete data.pageNum;
+      delete data.pageSize;
+      this.billPrintLoading = true;
+      this.$api
+        .billPrint(data)
+        .then((res) => {
+          exportFn(res.msg, "账单明细");
+          // this.$download.name(res.msg);
+          this.$message.success("操作成功");
+        })
+        .finally(() => {
+          this.billPrintLoading = false;
+        });
+    },
+    // 头部全部展开/收起
+    openHeadShow() {
+      this.headShow = !this.headShow;
+      this.tableData.forEach((item) => {
+        this.$refs.tableRef.toggleRowExpansion(item, this.headShow);
+      });
+    },
+    // 点击展开
+    openContentShow(row, expandedRows) {
+      console.log(row.orderSn, "---点击展开row.id----");
+      console.log(expandedRows, "---expandedRows----");
+      const matchingItem = expandedRows.find(
+        (item) => item.orderSn === row.orderSn
+      );
+      if (matchingItem) {
+        this.getSubTableList(matchingItem);
+      }
+    },
+    // 获取子表格数据
+    getSubTableList(row) {
+      this.$set(row, "subLoading", true);
+      var data = {
+        pageSize: row.subPageSize,
+        pageNum: row.subPageNum,
+        orderSn: row.orderSn,
+        orderBase: row.orderBase,
+        orderFrom: row.orderFrom,
+      };
+      this.$api
+        .subOrderDetailList(data)
+        .then((res) => {
+          row.subTableList = res.rows;
+          row.subTableList.forEach((i) => {
+            i.finishTime = this.$methodsTools.time10to13(i.finishTime, 2);
+            i.publicityTime = this.$methodsTools.time10to13(i.publicityTime, 2);
+            i.acquireTime = this.$methodsTools.time10to13(i.acquireTime, 2);
+
+            this.$set(i, "isEdit", Array(this.subTableSet.length).fill(false));
+          });
+          row.subTotal = res.total;
+        })
+        .finally(() => {
+          this.$set(row, "subLoading", false);
+        });
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .orderDetailList(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.tableData.forEach((item) => {
+            // 子列表分页参数
+            item.subTotal = 0;
+            item.subPageNum = 1;
+            item.subPageSize = 10;
+            item.proceedsDate = this.$methodsTools.time10to13(
+              item.proceedsDate,
+              2
+            );
+            item.proceedsCheckDate = this.$methodsTools.time10to13(
+              item.proceedsCheckDate,
+              2
+            );
+            this.$set(item, "isEdit", Array(this.tableSet.length).fill(false));
+            this.$set(item, "subTableList", []);
+            this.$set(item, "proceedsJson", item.proceedsJsonMap || {});
+            this.$nextTick(() => {
+              this.$refs.tableRef.toggleRowExpansion(item, false);
+            });
+          });
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+      this.headShow = false;
+    },
+    // 合计
+    getSummaries(param) {
+      const { columns, data } = param;
+      const sums = [];
+      columns.forEach((column, index) => {
+        if (index === 1) {
+          sums[index] = "合计";
+          return;
+        }
+        // 以下不进行合计
+        const noSummariesList = [
+          "发票申请日期",
+          "日期",
+          "收入核对日期",
+          "变化",
+          "收款记录",
+          "发票类型",
+        ];
+        const values = data
+          .filter((item) => !noSummariesList.includes(column.label)) //过滤不进行合计的列
+          .map((item) => {
+            if (
+              !isNaN(Number(item[column.property])) ||
+              (column.label &&
+                column.label.includes("月") &&
+                item.proceedsJson[column.property])
+            ) {
+              return Number(
+                column.label.includes("月")
+                  ? item.proceedsJson[column.property]
+                  : item[column.property]
+              );
+            }
+            return NaN; // 如果不是数字,返回NaN以便在reduce中排除
+          });
+        // console.log(values, "---values-----");
+        if (!values.every((value) => isNaN(value))) {
+          sums[index] = values.reduce((prev, curr) => {
+            const value = Number(curr);
+            if (!isNaN(value)) {
+              return prev + curr;
+            } else {
+              return prev;
+            }
+          }, 0);
+          sums[index] =
+            column.property === "integral" || column.property === "concludeNum"
+              ? sums[index].toFixed(0)
+              : "¥" + sums[index].toFixed(2);
+        } else {
+          sums[index] = " ";
+        }
+      });
+
+      return sums;
+    },
+    //初始化
+    initTR() {
+      this.cities = [];
+      this.checkedCities = [];
+      this.checkAll = true;
+      this.isIndeterminate = false;
+      this.tableSet.forEach((item, index) => {
+        this.cities.push(item.label);
+        if (item.hidden) {
+          this.checkedCities.push(item.label);
+        }
+      });
+      this.tableSet = [];
+      this.$nextTick(() => {
+        this.tableSet = JSON.parse(this.inittableSet);
+      });
+      if (this.checkedCities.length === 0) {
+        this.isIndeterminate = false;
+      } else if (this.checkedCities.length === this.cities.length) {
+        this.isIndeterminate = false;
+        this.checkAll = true;
+      } else {
+        this.isIndeterminate = true;
+        this.checkAll = false;
+      }
+    },
+    //自定义列全选按钮触发
+    handleCheckAllChange(val) {
+      this.checkedCities = val ? this.cities : [];
+      this.isIndeterminate = false;
+      if (val) {
+        this.tableSet = [];
+        this.$nextTick(() => {
+          this.tableSet = JSON.parse(this.inittableSet);
+        });
+      } else {
+        this.tableSet.forEach((item, index) => {
+          item.hidden = false;
+        });
+      }
+    },
+    // 勾选自定义列子选项
+    handleCheckedCitiesChange(value) {
+      var copyTable = JSON.parse(JSON.stringify(this.tableSet));
+      let checkedCount = value.length;
+      this.checkAll = checkedCount === this.cities.length;
+      this.isIndeterminate =
+        checkedCount > 0 && checkedCount < this.cities.length;
+      this.tableSet = [];
+      this.$nextTick(() => {
+        this.tableSet = copyTable;
+      });
+    },
+    checkboxChange(v, e) {
+      var copyTable = JSON.parse(JSON.stringify(this.tableSet));
+      copyTable.forEach((item) => {
+        if (item.label === v) {
+          item.hidden = e;
+        }
+      });
+
+      this.tableSet = [];
+      this.$nextTick(() => {
+        this.tableSet = copyTable;
+      });
+    },
+    //自定义列重置
+    initVue() {
+      // this.$emit("initTableset");
+      this.tableSet = JSON.parse(this.inittableSet);
+      this.initTR();
+    },
+    // 下移
+    downMove(option, index) {
+      if (index !== this.tableSet.length - 1) {
+        this.tableSet[index] = this.tableSet.splice(
+          index + 1,
+          1,
+          this.tableSet[index]
+        )[0];
+        this.cities[index] = this.cities.splice(
+          index + 1,
+          1,
+          this.cities[index]
+        )[0];
+      } else {
+        this.tableSet.unshift(this.tableSet.splice(index, 1)[0]);
+        this.cities.unshift(this.cities.splice(index, 1)[0]);
+      }
+      var copyTable = JSON.parse(JSON.stringify(this.tableSet));
+      this.tableSet = [];
+      this.$nextTick(() => {
+        this.tableSet = copyTable;
+      });
+    },
+    // 上移
+    upMove(option, index) {
+      if (index != 0) {
+        this.tableSet[index] = this.tableSet.splice(
+          index - 1,
+          1,
+          this.tableSet[index]
+        )[0];
+        this.cities[index] = this.cities.splice(
+          index - 1,
+          1,
+          this.cities[index]
+        )[0];
+      } else {
+        this.tableSet.push(this.tableSet.shift());
+        this.cities.push(this.cities.shift());
+      }
+      var copyTable = JSON.parse(JSON.stringify(this.tableSet));
+      this.tableSet = [];
+      this.$nextTick(() => {
+        this.tableSet = copyTable;
+      });
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    subHandleSizeChange(e, row) {
+      row.subPageSize = e;
+      row.subPageNum = 1;
+      this.getSubTableList(row);
+    },
+    subHandleCurrentChange(e, row) {
+      row.subPageNum = e;
+      this.getSubTableList(row);
+    },
+  },
+};
+</script>
+  
+<style lang="less" scoped>
+.slotPopper {
+  padding: 0px !important;
+}
+#tableList {
+  padding: 16px 16px 16px;
+  border-radius: 8px;
+  box-shadow: 0 0 9px 1px rgba(28, 41, 90, 0.1);
+  background: #ffffff;
+  .headerNavTool {
+    height: 72px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: -16px;
+    .rightBtnBox {
+      display: flex;
+      align-items: center;
+    }
+  }
+  // 去除input增减箭头
+  /deep/ input::-webkit-inner-spin-button {
+    -webkit-appearance: none !important;
+  }
+  /deep/ input.el-input__inner {
+    text-align: center;
+  }
+  /deep/ .el-table {
+    display: flex;
+    flex-direction: column;
+  }
+  //  order默认值为0,只需将表体order置为1即可移到最后,这样合计行就上移到表体上方
+  /deep/ .el-table__body-wrapper {
+    order: 1;
+  }
+  .inputBtn {
+    margin: 5px 0;
+    border: 1px solid #1890ff;
+    // background: #f1eff8;
+    color: #1890ff;
+    border-radius: 10px;
+    padding: 0 5px;
+    cursor: pointer;
+    margin: 5px 5px 0;
+    font-size: 12px !important;
+    white-space: nowrap;
+    &:hover {
+      background: #1890ff;
+      color: white;
+      border: 1px solid #1890ff;
+    }
+  }
+  .editInputBtn {
+    background: white;
+    border: 1px solid #aaaaaa;
+    color: #aaaaaa;
+  }
+  /deep/ .el-table__expand-icon {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  /deep/ .el-table__expand-icon .el-icon-arrow-right:before {
+    content: "\e6d9";
+    border: 1px solid #8b8a8a;
+    border-radius: 15px;
+  }
+  /deep/.el-table__expand-icon--expanded .el-icon-arrow-right:before {
+    content: "\e6d8";
+  }
+  .headShow {
+    border: 1px solid #8b8a8a;
+    border-radius: 15px;
+    cursor: pointer;
+    color: #8b8a8a;
+  }
+}
+/deep/ td.el-table__cell.el-table__expanded-cell {
+  padding: 0;
+}
+
+/deep/.el-button {
+  border-radius: 8px;
+}
+.popoverDis {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  font-size: 14px;
+  padding: 10px 0;
+  overflow-y: auto;
+  height: 450px;
+  width: 180px;
+  .checkboxHeader {
+    height: 40px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding-left: 13px;
+    padding-right: 15px;
+    width: 100%;
+    .initbtns {
+      color: #47a6ff;
+      cursor: pointer;
+    }
+  }
+  .checkboxGroup {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+    .checkboxchild {
+      width: 100%;
+      justify-content: space-between;
+      height: 40px;
+      display: flex;
+      align-items: center;
+      padding: 0px 15px 0px 13px;
+      transition: all 0.4s;
+      &:hover {
+        background-color: #ecf5ff;
+      }
+      &:hover .icon-right {
+        display: flex;
+      }
+      .icon-right {
+        display: flex;
+        align-items: center;
+        width: 30px;
+        height: 30px;
+        color: #666;
+        font-size: 14px;
+        display: none;
+        i {
+          cursor: pointer;
+          margin: 0px 3px;
+          &:hover {
+            color: #47a6ff;
+          }
+        }
+      }
+    }
+  }
+}
+</style>
+  
+  

+ 157 - 0
src/views/orderData/orderDetail/questionBankDialog.vue

@@ -0,0 +1,157 @@
+<template>
+  <div>
+    <BaseDialog
+      width="990px"
+      :isShow.sync="isDialog"
+      title="题库记录"
+      :isShowFooter="false"
+      @close="close"
+    >
+      <div style="max-height: 600px; overflow-y: auto;padding: 3px;">
+        <table-list
+          rowKey="id"
+          ref="tableList"
+          :tableSets="tableSet"
+          :tableData="tableData"
+          :navText="navText"
+          :loading="loading"
+        >
+          <template slot="customize">
+            <el-button type="warning" @click="openAddDialog"> 新增 </el-button>
+          </template>
+          <template slot="btn" slot-scope="props">
+            <el-button type="text" @click="del(props.scope.row)"
+              >删除</el-button
+            >
+          </template>
+        </table-list>
+      </div>
+      <!-- 新增弹窗 -->
+      <addQuestionBankDialog ref="addQuestionBankDialog" @refresh="refresh()" />
+    </BaseDialog>
+  </div>
+</template>
+  
+<script>
+import tableList from "@/components/tableList";
+import addQuestionBankDialog from "./addQuestionBankDialog.vue";
+export default {
+  components: { tableList, addQuestionBankDialog },
+  data() {
+    return {
+      isDialog: false,
+      loading: false,
+      navText: {
+        title: "开通记录",
+        index: 0,
+        ch: "条",
+        addHide: true,
+        custom: false,
+      },
+      tableSet: [
+        {
+          label: "",
+          prop: "sign",
+          hidden: true,
+        },
+        {
+          label: "姓名",
+          prop: "userName",
+          hidden: true,
+        },
+        {
+          label: "身份证号",
+          prop: "userCard",
+          hidden: true,
+          width: "180"
+        },
+        {
+          label: "教育类型",
+          prop: "eduName",
+          hidden: true,
+        },
+        {
+          label: "业务层次",
+          prop: "businessName",
+          hidden: true,
+          width: "300"
+        },
+        {
+          label: "专业",
+          prop: "majorName",
+          hidden: true,
+        },
+        {
+          label: "开通日期",
+          prop: "openDate",
+          scope: "aTimeList",
+          hidden: true,
+          isDiszing: true,
+          width: "180"
+        },
+      ],
+      tableData: [],
+      total: 0,
+    };
+  },
+  mounted() {},
+  methods: {
+    openBoxs(row, type) {
+      this.isDialog = true;
+      this.ruleForm = {
+        orderGoodsId: row.orderGoodsId,
+        orderSn: row.orderSn,
+        userCard: row.userCard,
+        userName: row.userName,
+      }
+      this.search()
+    },
+    close() {
+      this.ruleForm = {};
+    },
+    openAddDialog() {
+      this.$refs.addQuestionBankDialog.openBoxs(this.ruleForm)
+    },
+    search(v) {
+      this.loading = true;
+      this.$api
+        .orderQuestionBankList(this.ruleForm)
+        .then((res) => {
+          this.tableData = res.data;
+          this.navText.index = res.data?.length;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    refresh() {
+      this.$emit("refresh");
+      this.search();
+    },
+    del(v) {
+      this.$confirm("确定删除此内容?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$api
+            .delOrderQuestionBank(v.id)
+            .then((res) => {
+              this.$message.success("删除成功");
+              this.search();
+            });
+        })
+        .catch(() => {});
+    },
+  },
+};
+</script>
+  
+<style lang="scss" scoped>
+.text {
+  white-space: pre-wrap;
+  overflow-wrap: break-word;
+}
+</style>
+  

+ 412 - 0
src/views/orderData/orderDetail/recordUpdateDialog.vue

@@ -0,0 +1,412 @@
+<template>
+  <div>
+    <BaseDialog
+      :width="dialogWidth"
+      :isShow.sync="isImportDialog"
+      title="批量更新"
+      @submit="confirmImport"
+      @close="close"
+    >
+      <div class="content" v-loading="loading">
+        <input
+          id="importData"
+          type="file"
+          ref="importData"
+          style="display: none"
+          accept=".xlsx, .xls"
+          @change="handleImport"
+        />
+        <div v-if="!isTableData">
+          <el-button type="primary" size="medium" @click="clickHandleImport"
+            >导入数据</el-button
+          >
+          <div class="down" @click="downloadTemplate">下载导入模板</div>
+        </div>
+        <div v-else id="tableList">
+          <div class="headerNavTool">
+            <div class="leftIndexText">
+              全部
+              <span style="color: #1890ff">{{
+                ruleForm.tableData.length
+              }}</span>
+              人; 正确
+              <span style="color: #1890ff">{{ correctNum }}</span>
+              人; 错误
+              <span style="color: #dd201b">{{ errorNum }}</span>
+              人;
+              <span style="color: #999; font-size: 14px; margin-left: 10px">
+                <i class="el-icon-warning-outline"></i>
+                点击数据,左右键盘可滑动数据表。
+              </span>
+            </div>
+            <div class="rightBtnBox">
+              <el-button size="medium" @click="clickHandleImport" type="primary"
+                >继续导入</el-button
+              >
+              <el-button
+                size="medium"
+                @click="handleDelete(null)"
+                type="primary"
+                >批量删除</el-button
+              >
+            </div>
+          </div>
+          <el-form
+            ref="ruleForm"
+            :model="ruleForm"
+            :rules="rules"
+            auto-complete="on"
+          >
+            <el-table
+              ref="tableList"
+              :loading="loading"
+              :data="ruleForm.tableData"
+              style="width: 100%"
+              max-height="500"
+              fit
+              border
+              :header-cell-style="{
+                'text-align': 'center',
+                'background-color': '#eee',
+                color: '#333',
+                fontSize: '14px',
+              }"
+              :cell-style="{
+                'text-align': 'center',
+              }"
+              @selection-change="handleSelectionChange"
+              :row-class-name="tableRowClassName"
+            >
+              <el-table-column
+                type="selection"
+                width="55"
+                fixed="left"
+              ></el-table-column>
+              <el-table-column
+                type="index"
+                label="序号"
+                width="50 "
+              ></el-table-column>
+              <el-table-column prop="sign" label="" width="150">
+                <!-- <template slot-scope="scope">
+                  <el-input
+                    v-model="scope.row.sign"
+                    placeholder="请输入"
+                  ></el-input>
+                </template> -->
+              </el-table-column>
+              <el-table-column prop="userName" label="姓名" width="150">
+                <!-- <template slot-scope="scope">
+                  <el-form-item
+                    :prop="'tableData.' + scope.$index + '.userName'"
+                    :rules="rules.userName"
+                  >
+                    <el-input
+                      v-model="scope.row.userName"
+                      placeholder="请输入"
+                    ></el-input>
+                  </el-form-item>
+                </template> -->
+              </el-table-column>
+              <el-table-column prop="userCard" label="身份证号" width="200">
+                <!-- <template slot-scope="scope">
+                  <el-form-item
+                    :prop="'tableData.' + scope.$index + '.userCard'"
+                    :rules="rules.userCard"
+                  >
+                    <el-input
+                      v-model="scope.row.userCard"
+                      placeholder="请输入"
+                    ></el-input>
+                  </el-form-item>
+                </template> -->
+              </el-table-column>
+              <el-table-column prop="eduName" label="教育类型" width="150">
+              </el-table-column>
+              <el-table-column prop="businessName" label="业务层次" width="150">
+              </el-table-column>
+              <el-table-column prop="majorName" label="专业" width="150">
+              </el-table-column>
+              <el-table-column prop="remark" label="备注" width="150">
+              </el-table-column>
+              <el-table-column prop="openDate" label="开通日期" width="180">
+                <template slot-scope="scope">
+                  {{
+                    $methodsTools.onlyForma(scope.row.openDate, false) || "-"
+                  }}
+                </template>
+              </el-table-column>
+              <el-table-column prop="date" label="操作" fixed="right">
+                <template slot-scope="scope">
+                  <el-button type="text" @click="handleDelete(scope.row)"
+                    >删除</el-button
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form>
+        </div>
+      </div>
+    </BaseDialog>
+  </div>
+</template>
+      
+<script>
+import { downFn } from "@/utils/index.js";
+export default {
+  data() {
+    return {
+      ruleForm: {},
+      isImportDialog: false,
+      dialogWidth: "400px",
+      loading: false, //当前表单加载是否加载动画
+      multipleSelection: [],
+      correctNum: 0,
+      errorNum: 0,
+      total: 0,
+      rules: {
+        userName: [
+          {
+            validator: (rule, value, callback) => {
+              if (!isNaN(parseFloat(value))) {
+                callback(new Error(" "));
+              } else {
+                callback();
+              }
+            },
+            trigger: "blur",
+          },
+        ],
+        userCard: [
+          {
+            validator: (rule, value, callback) => {
+              var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
+              if (value && !reg.test(value)) {
+                callback(new Error(" "));
+              } else {
+                callback();
+              }
+            },
+            trigger: "blur",
+          },
+        ],
+      },
+    };
+  },
+  computed: {
+    // tableData是否有数据
+    isTableData: function () {
+      if (this.ruleForm.tableData && this.ruleForm.tableData?.length > 0) {
+        this.dialogWidth = "900px";
+        return true;
+      } else {
+        this.dialogWidth = "400px";
+        return false;
+      }
+    },
+  },
+  mounted() {},
+
+  methods: {
+    openBoxs(row) {
+      this.isImportDialog = true;
+      this.ruleForm = {
+        tableData: [],
+      };
+    },
+    clickHandleImport() {
+      this.$refs.importData.click();
+    },
+    tableRowClassName({ row, rowIndex }) {
+      if (row.check === 2) {
+        return "error-row";
+      }
+      return "";
+    },
+    // 确认导入操作(保存)
+    confirmImport() {
+      console.log("确认导入操作");
+      if (!this.ruleForm.tableData?.length) {
+        this.$message.warning("请导入数据");
+        return;
+      }
+      const data = JSON.parse(
+        JSON.stringify(
+          this.ruleForm.tableData.filter((item) => item.check == 1)
+        )
+      );
+      if (!data.length) {
+        this.$message.warning("无正确数据,请检查文件内容");
+        return;
+      }
+      this.loading = true;
+      this.$api
+        .addRecordUpdate(data)
+        .then((res) => {
+          this.$message.success("操作成功!");
+        })
+        .finally(() => {
+          this.isImportDialog = false;
+          this.loading = false;
+        });
+      // this.$refs.ruleForm.validate((valid) => {
+      //   if (valid) {
+      //   } else {
+      //     this.$message.warning(
+      //       `列表有${this.getDataErrorNumber(
+      //         "error"
+      //       )}条数据错误,请修改再确定。`
+      //     );
+      //   }
+      // });
+    },
+    // 获取错误数据条数
+    getDataErrorNumber(type) {
+      let errorNumber = 0;
+      var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
+      this.ruleForm.tableData.forEach((item) => {
+        if (
+          !isNaN(parseFloat(item.userName)) ||
+          (!reg.test(item.userCard) && item.userCard)
+        ) {
+          errorNumber++;
+        }
+      });
+      return type === "error"
+        ? errorNumber
+        : this.ruleForm.tableData.length - errorNumber;
+    },
+    // 下载导入模版
+    downloadTemplate() {
+      downFn(
+        "oss/images/file/20240605/1717576699880.xlsx",
+        "更新记录模版.xlsx"
+      );
+    },
+    // 导入操作
+    handleImport(e) {
+      this.loading = true;
+      var file = e.target.files[0];
+      if (file === undefined) {
+        return;
+      }
+      const type = file.name.toLowerCase().split(".").splice(-1);
+      const fileType = ["xlsx", "xls"].some((item) => item == type);
+      if (!fileType) {
+        this.$message.error("上传格式需为:.xlsx/.xls");
+        e.target.value = "";
+        return;
+      }
+      let formData = new FormData();
+      formData.append("file", file);
+      this.$api
+        .recordUpdateImport(formData)
+        .then((res) => {
+          if (!res.data.dataList.length) {
+            this.$message.warning("未检测到导入数据,请检查导入文件");
+            return;
+          }
+          const data = res.data.dataList;
+          if (this.ruleForm.tableData && this.ruleForm.tableData.length > 0) {
+            this.ruleForm.tableData = this.ruleForm.tableData.concat(data);
+            this.correctNum += res.data.correctNum;
+            this.errorNum += res.data.errorNum;
+          } else {
+            this.ruleForm.tableData = data;
+            this.correctNum = res.data.correctNum;
+            this.errorNum = res.data.errorNum;
+            this.total = res.data.total;
+          }
+          this.ruleForm.tableData.forEach((item) => {
+            // 生成唯一key值
+            item.keyId = Number(
+              Math.random().toString().substr(2, 5) + Date.now()
+            ).toString(36);
+          });
+          this.$message.success("导入成功!");
+        })
+        .finally(() => {
+          e.target.value = "";
+          this.loading = false;
+        });
+    },
+    handleDelete(row) {
+      if (!this.multipleSelection.length && !row) {
+        this.$message.warning("请勾选需要删除的选项");
+        return;
+      }
+      this.$confirm(
+        row
+          ? `确定删除此内容?内容删除后将无法恢复!`
+          : `此操作将永久删除所勾选的${this.multipleSelection.length}条数据, 是否继续?`,
+        "提示",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        }
+      )
+        .then(() => {
+          const ids = row
+            ? [row.keyId]
+            : this.multipleSelection.map((item) => item.keyId);
+          console.log(ids, "ids");
+          this.ruleForm.tableData = this.ruleForm.tableData.filter(
+            (item) => !ids.includes(item.keyId)
+          );
+          this.$message.success("删除成功");
+        })
+        .catch(() => {});
+    },
+    //多选操作回调
+    handleSelectionChange(val) {
+      console.log(val);
+      this.multipleSelection = val;
+    },
+    close() {},
+  },
+};
+</script>
+      
+<style lang="scss" scoped>
+#tableList {
+  padding: 16px 16px 16px;
+  border-radius: 8px;
+  box-shadow: 0px 0px 9px 1px rgba(28, 41, 90, 0.1);
+  background: #ffffff;
+  .headerNavTool {
+    height: 72px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: -16px;
+    .rightBtnBox {
+      display: flex;
+      align-items: center;
+    }
+  }
+  /deep/ .el-form-item {
+    margin-bottom: 0;
+  }
+  /deep/ .el-table .error-row {
+    background: #ff5a4f;
+    color: #333;
+  }
+}
+.content {
+  font-size: 14px !important;
+  text-align: center;
+
+  .down {
+    margin: 10px;
+    color: dodgerblue;
+    text-decoration: underline;
+    &:hover {
+      text-decoration: underline;
+      // border-bottom: 1px solid #3498db;
+    }
+    cursor: pointer;
+  }
+}
+</style>
+