Преглед изворни кода

feat:基础版升级标准版代码

ly пре 1 година
родитељ
комит
a88e01c104

+ 167 - 0
src/api/upgrade/contract.js

@@ -0,0 +1,167 @@
+import request from '@/utils/request'
+import { download } from '@/utils/request'
+
+// request.defaults.baseURL = '/ezhizao-yzbh-crm'
+// 查询档案入库列表
+export function listOrder(query) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/upgrade/archiveinput/list',
+        method: 'get',
+        params: query
+    })
+}
+export function listOrder2(query) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/upgrade/archiveinput/list2',
+        method: 'get',
+        params: query
+    })
+}
+// 查询档案入库详细
+export function getOrder(id) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/upgrade/archiveinput/' + id,
+        method: 'get'
+    })
+}
+
+// 新增档案入库
+export function addOrder(data) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/archive/order',
+        method: 'post',
+        data: data
+    })
+}
+
+// 修改档案入库
+export function updateOrder(data) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/archive/order',
+        method: 'put',
+        data: data
+    })
+}
+
+// 删除档案入库
+export function delBinOrder(id) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/bin/order/' + id,
+        method: 'post'
+    })
+}
+
+// 删除档案入库
+export function delOrder(id) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/upgrade/archiveinput/delete?id=' + id,
+        method: 'post'
+    })
+}
+
+export function initTaskTypes(id) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/archive/order/initTaskTypes',
+        method: 'get'
+    })
+}
+
+export function exportOrder(query) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    download(
+        "business/archive/order/export",
+        {
+            ...query,
+        },
+        `合同导出_${new Date().getTime()}.xlsx`
+    )
+}
+
+export function exportLoopTemplate() {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    download(
+        "business/archive/order/exportLoopTemplate",
+        {
+        },
+        `循环合同模板_${new Date().getTime()}.xlsx`
+    )
+}
+
+export function exportOnceTemplate() {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    download(
+        "business/archive/order/exportOnceTemplate",
+        {
+        },
+        `单次合同模板_${new Date().getTime()}.xlsx`
+    )
+}
+
+// 文件上传
+export function importLoop(file) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: `/business/archive/order/importLoop`,
+        method: 'post',
+        data: file,
+        headers: {
+            'Content-Type': 'multipart/form-data'
+        }
+    })
+}
+// 文件上传
+export function importOnce(file) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: `/business/archive/order/importOnce`,
+        method: 'post',
+        data: file,
+        headers: {
+            'Content-Type': 'multipart/form-data'
+        }
+    })
+}
+export function verifyOrder(data) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/archive/order/verify',
+        method: 'post',
+        data: data
+    })
+}
+
+export function dissolutionOrder(data) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/archive/order/dissolution',
+        method: 'post',
+        data: data
+    })
+}
+
+export function alterOrder(data) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/archive/order/alter',
+        method: 'post',
+        data: data
+    })
+
+}
+
+export function verifyCheckOrder(data) {
+    request.defaults.baseURL = '/ezhizao-yzbh-crm'
+    return request({
+        url: '/business/archive/order/verifyCheck',
+        method: 'post',
+        data: data
+    })
+}

+ 114 - 0
src/api/upgrade/workOrder.js

@@ -0,0 +1,114 @@
+import request from '@/utils/request'
+import { download } from '@/utils/request'
+
+// 查询工单管理列表
+export function listWorkOrder(query) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/business/upgrade/workorder/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询工单管理列表
+export function indexList(query) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/business/upgrade/workorder/indexList',
+    method: 'get',
+    params: query
+  })
+}
+export function completeUpgrade() {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/upgrade/crm/order/completeUpgrade',
+    method: 'post'
+  })
+}
+export function checkWorkOrder() {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/upgrade/crm/order/checkWorkOrder',
+    method: 'post'
+  })
+}
+// 查询工单管理详细
+export function getWorkOrder(id) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/business/upgrade/workorder/' + id,
+    method: 'get'
+  })
+}
+
+// 修改是否延续
+export function setContract(ids, state) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/business/upgrade/workorder' + ids + "/" + state,
+    method: 'post'
+  })
+}
+
+// 新增工单管理
+export function addWorkOrder(data) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/business/workOrder',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改工单管理
+export function updateWorkOrder(data) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/business/upgrade/workorder/updatestartmonth',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除工单管理
+export function delWorkOrder(id) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/business/workOrder/' + id,
+    method: 'delete'
+  })
+}
+
+export function exportWorkOrder(query) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  download(
+    "/business/upgrade/workorder/export",
+    {
+      ...query,
+    },
+    `合同工单导出_${new Date().getTime()}.xlsx`
+  )
+}
+
+export function exportNoContract(query) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  download(
+    "/business/upgrade/workorder/export",
+    {
+      ...query,
+    },
+    `非合同工单导出_${new Date().getTime()}.xlsx`
+  )
+}
+
+
+export function setWorkOrderService(data) {
+  request.defaults.baseURL = '/ezhizao-yzbh-crm'
+  return request({
+    url: '/business/workOrder/setService',
+    method: 'post',
+    data: data
+  })
+}

+ 356 - 0
src/views/business/upgrade/AddCompanyDialog.vue

@@ -0,0 +1,356 @@
+<template>
+  <!-- 添加或修改菜单对话框 -->
+  <el-dialog
+    title="客户添加"
+    v-model="visible"
+    width="680px"
+    append-to-body
+    draggable
+    :close-on-click-modal = "false"
+  >
+    <el-form
+      ref="companyRef"
+      :model="form"
+      size="small"
+      :rules="rules"
+      label-width="100px"
+    >
+      <el-row>
+        <el-col :span="24">
+          <el-radio-group v-model="addType">
+            <el-radio-button :label="1">表单添加</el-radio-button>
+            <el-radio-button :label="2">导入添加</el-radio-button>
+          </el-radio-group>
+        </el-col>
+        <el-col v-if="addType === 1" :span="24">
+          <el-form-item label="客户名称" prop="name">
+            <el-input v-model="form.name" placeholder="请输入客户名称" />
+          </el-form-item>
+        </el-col>
+        <el-col v-if="addType === 1" :span="24">
+          <el-form-item label="客户来源" prop="sourceCategoryName" required>
+            <CustomerFormCom
+              ref="addComRef"
+              :edit-status="true"
+              :form-data="form"
+              :source-categories="sourceCategories"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col v-if="addType === 2" :span="24">
+          <el-form-item label="上传">
+            <el-upload
+              ref="uploadRef"
+              :limit="1"
+              accept=".xlsx, .xls"
+              :headers="upload.headers"
+              :action="upload.url + '?updateSupport=' + upload.updateSupport"
+              :disabled="upload.isUploading"
+              :on-progress="handleFileUploadProgress"
+              :on-success="handleFileSuccess"
+              :auto-upload="false"
+              drag
+            >
+              <el-icon class="el-icon--upload">
+                <upload-filled />
+              </el-icon>
+              <div class="el-upload__text">
+                将文件拖到此处,或<em>点击上传</em>
+              </div>
+              <template #tip>
+                <div class="el-upload__tip text-center">
+                  <div class="el-upload__tip">
+                    <!-- <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据 -->
+                  </div>
+                  <span>仅允许导入xls、xlsx格式文件。</span>
+                  <el-link
+                    type="primary"
+                    :underline="false"
+                    style="font-size: 12px; vertical-align: baseline"
+                    @click="importTemplate"
+                    >下载模板</el-link
+                  >
+                </div>
+              </template>
+            </el-upload>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button
+          type="primary"
+          icon="Finished"
+          size="small"
+          @click="submitForm"
+          >确 定</el-button
+        >
+        <el-button icon="close" size="small" @click="cancel">取 消</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+
+<script setup>
+import { getToken, getTenant } from "@/utils/auth";
+import { addCompany } from "@/api/business/crm/company";
+import CustomerFormCom from "@/components/CustomerFormCom";
+import useUserStore from "@/store/modules/user";
+import { listSource } from "@/api/settings/source";
+import { deepClone } from "@/utils";
+// import { incomeDefault, taxTypes, confirmDefault } from "@/utils/default"
+const { proxy } = getCurrentInstance();
+/** 父组件传参 */
+const props = defineProps({
+  getList: {
+    type: Function,
+    default: () => {},
+  },
+});
+const { getList } = toRefs(props);
+/** 字典数组区 */
+const { develop_type } = proxy.useDict("develop_type");
+/** 表单抽屉 页变量 */
+const title = ref("");
+const loading = ref(false);
+const multiple = ref(true);
+const visible = ref(false);
+const editStatus = ref(false);
+const isFullscreen = ref(false);
+const addDetailNum = ref(1);
+const currentMember = {};
+const provinces = ref(proxy.region.getProvinces());
+provinces.value.unshift({ code: "", name: "全部" });
+const cities = ref([]);
+const districts = ref([]);
+
+const sourceCategories = ref([]);
+
+const addType = ref(1);
+
+watch(addType, (value) => {
+  switch (value) {
+    case "1":
+      break;
+    case "2":
+      break;
+    default:
+      break;
+  }
+});
+
+const webHost = import.meta.env.VITE_APP_BASE_API;
+
+const setHeaders = {
+  Authorization: getToken(),
+};
+const data = reactive({
+  form: {},
+  followData: {},
+  rules: {
+    name: [{ required: true, message: "客户名称不能为空", trigger: "blur" }],
+    sourceCategoryName: [
+      { validator: sourceValidator, trigger: "blur" },
+      { required: true, message: "客户来源不能为空", trigger: "blur" },
+    ],
+  },
+});
+const addComRef = ref(null);
+
+/*** 客户导入参数 */
+const upload = reactive({
+  // 是否禁用上传
+  isUploading: false,
+  // 设置上传的请求头部
+  headers: { Authorization: "Bearer " + getToken(), tenantId: getTenant() },
+  // 上传的地址
+  url: "/ezhizao-yzbh-crm/business/company/importData",
+});
+
+function sourceValidator(rule, value, callback) {
+  console.log(form.value.reffererDataSource, form.value.sourceName);
+  if (form.value.sourceCategoryName === "") {
+    callback(new Error("来源类型不能为空"));
+    return;
+  }
+  if (
+    form.value.referrerDataSource !== "" &&
+    form.value.referrerDataSource != null &&
+    form.value.sourceName === ""
+  ) {
+    callback(new Error("来源不能为空"));
+    return;
+  }
+  return callback();
+}
+
+const contactorEmptyData = {
+  id: null,
+  name: "",
+  position: "",
+  gender: "男",
+  phone: "",
+  email: "",
+  isMain: "是",
+  remark: "",
+};
+
+const companyEmptyData = {
+  id: null,
+  code: "",
+  name: "",
+  oldName: "",
+  shortName: "",
+  ownerId: "",
+  ownerName: "",
+  sourceCategoryId: "",
+  sourceCategoryName: "",
+  sourceId: "",
+  sourceName: "",
+  stageId: "",
+  stageName: "",
+  phone: "",
+  email: "",
+  contactAddress: "",
+  remark: "",
+  socialCreditCode: "",
+  mainBusinessId: "",
+  mainBusinessName: "",
+  typeId: "",
+  typeName: "",
+  legalRepresentative: "",
+  foundationDate: "",
+  licenceDate: "",
+  businessStartDate: "",
+  collectionMethod: "",
+  businessEndDate: "",
+  isPermanentlyEffective: "",
+  registerMoney: "",
+  registerMoneyUnitId: "",
+  registerMoneyUnitName: "",
+  provinceCode: "",
+  province: "",
+  cityCode: "",
+  city: "",
+  districtCode: "",
+  district: "",
+  address: "",
+  businessField: "",
+  taxTypeId: "",
+  taxTypeName: "",
+  taxDeclarationCategoryId: "",
+  taxDeclarationCategoryName: "",
+  isZero: "",
+  taxDishId: "",
+  taxDishName: "",
+  competentTaxAuthority: "",
+  annualIncome: "",
+  taxType: "",
+  taxCollectorName: "",
+  taxCollectorPhone: "",
+  taxMonth: "",
+  openingBank: "",
+  bankAccount: "",
+  companyTags: [],
+  companyTagIds: [],
+  contactors: [],
+  serviceTeams: [],
+  companyFiles: [],
+  stores: [],
+  creatorId: useUserStore().user.id,
+};
+
+const followQuery = ref({});
+const { form, rules, followData } = toRefs(data);
+
+/***********************  表单页方法 ****************************/
+
+/** 抽屉打开 */
+function open() {
+  reset();
+  visible.value = true;
+}
+
+function init() {
+  listSource()
+    .then((res) => {
+      // console.log(res)
+      sourceCategories.value = res.rows;
+      // console.log(sourceCategories.value)
+    })
+    .catch((err) => {
+      console.log(err);
+    });
+}
+
+function reset() {
+  form.value = deepClone(companyEmptyData);
+  // console.log(addComRef.value)
+  if (addComRef.value != null) addComRef.value.reset();
+}
+
+function cancel() {
+  visible.value = false;
+}
+
+function submitForm() {
+  if (addType.value === 1) {
+    proxy.$refs["companyRef"].validate((valid) => {
+      if (valid) {
+        addCompany(form.value)
+          .then((res) => {
+            console.log(res);
+            visible.value = false;
+            getList.value();
+            // emit('success')
+          })
+          .catch((err) => {
+            console.log(err);
+          });
+      }
+    });
+  } else {
+    submitFileForm();
+  }
+}
+
+const importTemplate = () => {
+  proxy.download(
+    "/business/company/importTemplate",
+    {},
+    `company_template${new Date().getTime()}.xlsx`
+  );
+};
+/**文件上传中处理 */
+const handleFileUploadProgress = (event, file, fileList) => {
+  upload.isUploading = true;
+};
+/** 文件上传成功处理 */
+const handleFileSuccess = (response, file, fileList) => {
+  upload.open = false;
+  upload.isUploading = false;
+  proxy.$refs["uploadRef"].handleRemove(file);
+  proxy.$alert(
+    "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+      response.msg +
+      "</div>",
+    "导入结果",
+    { dangerouslyUseHTMLString: true }
+  );
+  getList.value();
+};
+/** 提交上传文件 */
+function submitFileForm() {
+  proxy.$refs["uploadRef"].submit();
+}
+
+// 暴露给父组件的方法
+defineExpose({
+  open,
+});
+init();
+</script>
+
+<style></style>

+ 119 - 0
src/views/business/upgrade/WorkOrderDialog.vue

@@ -0,0 +1,119 @@
+<template>
+  <el-dialog id="workdialog" v-model="outerVisible" title="Outer Dialog" width="800">
+    <el-table
+        ref="singleTableRef"
+        :data="gridData"
+        highlight-current-row
+        style="width: 100%"
+        @current-change="handleCurrentChange"
+    >
+      <el-table-column type="index" width="50" />
+      <el-table-column property="date" label="Date" width="120" />
+      <el-table-column property="name" label="Name" width="120" />
+      <el-table-column property="address" label="Address" />
+    </el-table>
+    <div style="margin-top: 20px">
+      <el-button @click="setCurrent(gridData[1])">Select second row</el-button>
+      <el-button @click="setCurrent()">Clear selection</el-button>
+    </div>
+    <el-dialog
+        v-model="innerVisible"
+        title="Inner Dialog"
+        width="400px"
+        append-to-body
+    >
+      <span>确定要更换这条工单详细吗?</span>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="innerVisible = false">取消</el-button>
+          <el-button type="primary" @click="sumbit">
+           提交
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="outerVisible = false">取消</el-button>
+        <el-button type="primary" @click="innerVisible = true">
+          确认
+        </el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+<script lang="ts" setup>
+import { reactive, ref } from 'vue'
+import {ElTable} from "element-plus";
+
+const dialogTableVisible = ref(false)
+const dialogFormVisible = ref(false)
+const formLabelWidth = '140px'
+const outerVisible = ref(false);
+const innerVisible = ref(false);
+const currentRow = ref();
+const form = reactive({
+  name: '',
+  region: '',
+  date1: '',
+  date2: '',
+  delivery: false,
+  type: [],
+  resource: '',
+  desc: '',
+})
+interface workOrder {
+
+}
+const gridData = [
+  {
+    date: '2016-05-02',
+    name: 'John Smith',
+    address: 'No.1518,  Jinshajiang Road, Putuo District',
+  },
+  {
+    date: '2016-05-04',
+    name: 'John Smith',
+    address: 'No.1518,  Jinshajiang Road, Putuo District',
+  },
+  {
+    date: '2016-05-01',
+    name: 'John Smith',
+    address: 'No.1518,  Jinshajiang Road, Putuo District',
+  },
+  {
+    date: '2016-05-03',
+    name: 'John Smith',
+    address: 'No.1518,  Jinshajiang Road, Putuo District',
+  },
+]
+
+function open() {
+  outerVisible.value = true;
+
+}
+
+
+function sumbit() {
+  outerVisible.value = false;
+  innerVisible.value = false;
+}
+
+
+const singleTableRef = ref<InstanceType<typeof ElTable>>()
+
+const setCurrent = (row?: any) => {
+  singleTableRef.value!.setCurrentRow(row)
+}
+const handleCurrentChange = (val: any | undefined) => {
+  currentRow.value = val
+}
+defineExpose({
+  open,
+});
+</script>
+<style scoped>
+  #workdialog{
+    margin-top: auto;
+  }
+</style>

+ 173 - 0
src/views/business/upgrade/ZeroChangeDialog.vue

@@ -0,0 +1,173 @@
+<template>
+  <el-dialog
+    title="客户信息编辑"
+    v-model="visible"
+    :width="width"
+    append-to-body
+    draggable
+    @close="close"
+    :close-on-click-modal = "false"
+  >
+    <!-- 功能按钮 -->
+    <div style="padding: 8px 24px 16px 24px">
+      <el-form size="small" label-width="100px" v-model="form">
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="客户名称">
+              <div>{{ form.name }}</div>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="是否零申报">
+              <el-select
+                v-model="form.isZero"
+                placeholder="请选择"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in yesOrNo"
+                  :key="item.label"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="form-btns-container" style="height: 40px">
+      <el-button size="small" style="float: right" @click="close" icon="close">
+        取消</el-button
+      >
+      <el-button
+        type="primary"
+        icon="Finished"
+        size="small"
+        style="float: right; margin-left: 12px; margin-right: 12px"
+        @click="handleSave"
+        >保存</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+<script setup>
+import {
+  getCompany,
+  addCompany,
+  updateCompany,
+} from "@/api/business/crm/company";
+import { yesOrNo } from "@/utils/default";
+import { ref } from "vue";
+const { proxy } = getCurrentInstance();
+const visible = ref(false);
+const width = ref(800);
+const editStatus = ref(false);
+const baseUrl = ref(import.meta.env.VITE_APP_BASE_API);
+const defaultIsZero = ref(null);
+const props = defineProps({
+  saveCallBack: {
+    type: Function,
+    default: () => {},
+  },
+});
+const { saveCallBack } = toRefs(props);
+const total = ref(0);
+
+const form = ref({});
+const saveValue = ref(null);
+
+const emptyForm = {
+  details: [],
+};
+
+function open(companyId, row) {
+  saveValue.value = row;
+  reset();
+  visible.value = true;
+  if (companyId) {
+    getCompany(companyId).then((response) => {
+      form.value = response.data;
+      defaultIsZero.value = response.data.isZero;
+    });
+  }
+}
+
+function close() {
+  visible.value = false;
+  reset();
+}
+
+function reset() {
+  form.value = proxy.deepClone(emptyForm);
+}
+
+function handleSave() {
+  if (checkZero()) {
+    proxy.$modal.confirm("确定修改么?").then((_) => {
+      if (form.value.id) {
+        updateCompany(form.value).then((response) => {
+          proxy.$modal.msgSuccess("保存成功!");
+          form.value = response.data;
+          defaultIsZero.value = Number(response.data.isZero);
+          saveCallBack.value(saveValue.value);
+          close();
+        });
+      } else {
+        addCompany(form.value).then((res) => {
+          proxy.$modal.msgSuccess("保存成功!");
+          form.value = response.data;
+          defaultIsZero.value = Number(response.data.isZero);
+          saveCallBack.value(saveValue.value);
+          close();
+        });
+      }
+    });
+  }
+}
+
+function checkZero() {
+  if (form.value.isZero == null) {
+    proxy.$modal.msgError("请选择是否零申报");
+    return false;
+  }
+  if (defaultIsZero.value === 1 || defaultIsZero.value == null) {
+    return true;
+  } else if (
+    defaultIsZero.value != form.value.isZero &&
+    form.value.isZero === 1
+  ) {
+    proxy.$modal.msgError("不可将非零申报客户改为零申报");
+    return false;
+  } else {
+    return true;
+  }
+}
+
+// 暴露给父组件的方法
+defineExpose({
+  open,
+});
+</script>
+<style scoped>
+.img {
+  width: 23px;
+  height: 23px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+::v-deep(.el-upload) {
+  display: flex;
+  text-align: center;
+  justify-content: center;
+  cursor: pointer;
+  outline: 0;
+}
+
+.required::after {
+  content: "*";
+  color: red;
+}
+</style>

+ 433 - 0
src/views/business/upgrade/noContractWorkOrder/index.vue

@@ -0,0 +1,433 @@
+<template>
+  <div class="page-container list-container">
+    <!-- 功能按钮区 -->
+    <div class="list-btns-container">
+
+    <div id="listbutton">
+        <el-button type="primary" size="small"
+                   icon="Download" @click="handleExport"
+                   v-hasPermi="['business:upgrade:workOrder:export']">导出
+        </el-button>
+        <el-button type="primary" size="small"
+                   v-loading.fullscreen.lock="fullscreenLoading"
+                   icon="Plus" @click="Upgrade"
+                   v-hasPermi="['business:upgrade:workOrder:edit']">完成升级
+        </el-button>
+      </div>
+
+    </div>
+    <!-- 搜索区 -->
+    <el-form class="list-search-container" size="small" :model="queryParams" ref="queryRef" :inline="true"
+      label-width="68px">
+      <el-form-item label="客户名称:" prop="companyName">
+        <el-input v-model="queryParams.companyName" placeholder="请输入客户名称" style="width: 150px" clearable
+          @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 列表区 -->
+    <el-table v-loading="loading" :data="orderList" size="small" border height="100%"
+              @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="工单编号" align="center" prop="id" min-width="250" />
+      <el-table-column label="客户名称" align="center" min-width="250" prop="companyName" :resizable="false" />
+      <el-table-column label="税号" align="center" min-width="200" prop="socialCreditCode" :resizable="false" />
+      <el-table-column label="工单类型" align="center" prop="amount" min-width="80" :resizable="false">
+        <template #default="scope">
+          {{ scope.row.type === 1 ? "循环工单" : "代办工单" }}
+        </template>
+      </el-table-column>
+      <el-table-column label="项目" align="center" prop="taskTypeName" :resizable="false" min-width="110">
+        <template #default="scope">
+          {{ scope.row.taskTypeName }}
+          {{
+            scope.row.taskTypeDetailName
+                ? `-${scope.row.taskTypeDetailName}`
+                : ""
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="是否延续" align="center" prop="isContinue" :resizable="false">
+        <template #default="scope">
+          {{ scope.row.isContinue === 0 ? "否" : "是" }}
+        </template>
+      </el-table-column>
+      <el-table-column label="合同状态" align="center" width="150" prop="socialCreditCode" :resizable="false">
+        <template #default="scope">
+          <span v-if="scope.row.type === 1">{{ scope.row.closingMonth }}</span>
+          <span v-else>{{ scope.row.onceContractStatus }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="起始月" align="center" min-width="120" prop="startMonth" :resizable="false">
+        <template #default="scope">
+          <div v-if="scope.row.type === 1">
+            <div v-if="scope.row.editStatus.startMonth" style="
+                display: flex;
+                flex-direction: row;
+                justify-content: center;
+              ">
+              <el-date-picker v-model="scope.row.startMonth" size="small" placeholder="起始月" :clearable="true"
+                              value-format="YYYY-MM-DD" format="YYYY年MM月" type="month"
+                              @change="(arg) => startDateChangeHandler(scope.row, arg)" />
+              <el-button link type="primary" icon="Check" size="small" style="padding: 0"
+                         @click="saveHandler(scope.row, 'startMonth')" />
+            </div>
+            <div v-else style="
+                display: flex;
+                flex-direction: row;
+                justify-content: center;
+              ">
+              <div style="width: auto">
+                {{
+                  scope.row.startMonth
+                      ? moment(scope.row.startMonth).format("YYYY年MM月")
+                      : ""
+                }}
+              </div>
+              <el-button v-show="
+                  scope.row.isStop === 0 && scope.row.records.length === 0  && scope.row.isNew === 1
+                " link type="primary" icon="Edit" size="small" style="padding: 0"
+                         v-hasPermi="['business:upgrade:workOrder:edit']" @click="
+                  () => {
+                    scope.row.editStatus.startMonth =
+                      !scope.row.editStatus.startMonth;
+                  }
+                " />
+            </div>
+          </div>
+          <div v-else>-</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="结束月" align="center" min-width="90" :resizable="false">
+        <template #default="scope">
+          <div v-if="scope.row.monthNum > 0">
+            {{
+              scope.row.type === 1
+                  ? scope.row.endMonth
+                      ? moment(scope.row.endMonth).format("YYYY年MM月")
+                      : ""
+                  : "-"
+            }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="工单月数" align="center" :resizable="false" width="80" prop="monthNum">
+        <template #default="scope">
+          {{ scope.row.type === 1 ? scope.row.monthNum : "-" }}
+        </template>
+      </el-table-column>
+      <el-table-column label="工单执行人" align="center" :resizable="false" min-width="100">
+        <template #default="scope">{{ getTransactor(scope.row) }}</template>
+      </el-table-column>
+    </el-table>
+    <el-dialog title="新增工单" v-model="formOpen" width="500px" append-to-body draggable>
+      <el-form ref="dictRef" :model="form" label-width="100" size="small">
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="客户名称:" prop="companyName">
+              <el-autocomplete style="width: 100%" fit-input-width="300px" size="small"
+                :fetch-suggestions="querySearchCompanyAsync" :trigger-on-focus="true" v-model="form.companyName"
+                placeholder="请输入客户名称" @select="handleSelectCompany">
+                <template #append>
+                  <el-button icon="Plus" @click="showAddCompanyDialog">
+                  </el-button>
+                </template>
+                <template #default="{ item }">
+                  <div style="
+                      display: flex;
+                      flex-direction: row;
+                      justify-content: space-between;
+                    ">
+                    <div class="name" style="font-size: 12px">
+                      {{ item.name }}
+                    </div>
+                    <!-- <span class="code" style="font-size: 10px; color: darkgrey;">{{ item.code }}</span> -->
+                  </div>
+                </template>
+              </el-autocomplete>
+            </el-form-item>
+            <el-form-item label="服务内容:">
+              <el-input v-model.trim="form.remark" type="textarea" size="small" :rows="4" maxlength="200"
+                show-word-limit placeholder="服务内容" :clearable="true" />
+            </el-form-item>
+          </el-col>
+
+          <el-col :span="24"> </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" icon="Finished" size="small" @click="saveHandler">确 定</el-button>
+          <el-button @click="formCancel" icon="close" size="small">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <!-- 分页 -->
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize" @pagination="getList" />
+    <AddCompanyDialog ref="addCompanyDialogRef" />
+  </div>
+</template>
+
+<script setup name="WorkOrder">
+  // import contractForm from "./form";
+  import {
+    listWorkOrder,
+    delWorkOrder,
+    exportWorkOrder,
+    addWorkOrder,
+    exportNoContract,
+    completeUpgrade,
+    checkWorkOrder
+  } from "@/api/upgrade/workOrder";
+  import { listCompany } from "@/api/business/crm/company";
+  import AddCompanyDialog from "../AddCompanyDialog.vue";
+  import { ref } from "vue";
+  import {ElMessageBox} from "element-plus";
+  // import workorderForm from "./form"
+  const { proxy } = getCurrentInstance();
+  /** 字典数组区 */
+  /** 查询 对象 */
+
+  const orderList = ref([]);
+  const loading = ref(true);
+  const ids = ref([]);
+  const single = ref(true);
+  const multiple = ref(true);
+  const total = ref(0);
+  const prev = ref([]);
+  const addCompanyDialogRef = ref(null);
+  const fullscreenLoading = ref(false);
+  const formOpen = ref(false);
+
+  const form = ref({
+    id: null,
+    companyName: "",
+    companyId: null,
+    remark: "",
+    type: 2,
+    noContract: 1,
+  });
+
+  const emptyForm = {
+    id: null,
+    companyName: "",
+    companyId: null,
+    type: 2,
+    remark: "",
+    noContract: 1,
+  };
+
+  const { contract_verify_status } = proxy.useDict("contract_verify_status");
+  const { contract_status } = proxy.useDict("contract_status");
+  /** 查询对象 */
+  const queryParams = ref({
+    pageNum: 1,
+    pageSize: 20,
+    orderByColumn: "create_time",
+    companyName: "",
+    noContract: 1,
+  });
+
+  const editStatus = {
+    startMonth: false,
+  };
+
+  /***********************  方法区  ****************************/
+  onActivated(() => {
+    // 你的逻辑
+    getList();
+  });
+  /** 查询company列表 */
+  function getList() {
+    loading.value = true;
+    listWorkOrder(queryParams.value).then((response) => {
+      orderList.value = response.rows.map((l) => ({
+        ...l,
+        editStatus: proxy.deepClone(editStatus),
+      }));
+      prev.value = proxy.deepClone(response.rows);
+      total.value = response.total;
+      loading.value = false;
+    });
+  }
+
+  /** 搜索按钮操作 */
+  function handleQuery() {
+    queryParams.value.pageNum = 1;
+    getList();
+  }
+
+  /** 重置按钮操作 */
+  function resetQuery() {
+    proxy.resetForm("queryRef");
+    handleQuery();
+  }
+
+  // 多选框选中数据
+  function handleSelectionChange(selection) {
+    ids.value = selection.map((item) => item.id);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
+  }
+
+  /** 新增按钮操作 */
+  function handleAdd() {
+    // proxy.$refs.workOrderRef.open();
+    formOpen.value = true;
+  }
+
+  function formCancel() {
+    formOpen.value = false;
+    reset();
+  }
+
+  function reset() {
+    form.value = proxy.deepClone(emptyForm);
+  }
+
+  /** 修改按钮操作 */
+  function handleUpdate(row) {
+    // const id = row.id || ids.value;
+    // proxy.$refs.workOrderRef.open(id);
+  }
+
+  /** 删除按钮操作 */
+  function handleDelete(row) {
+    const _ids = row.id || ids.value;
+    proxy.$modal
+      .confirm("是否确认删除选中的数据项?")
+      .then(function () {
+        return delWorkOrder(_ids);
+      })
+      .then(() => {
+        getList();
+        proxy.$modal.msgSuccess("删除成功!");
+      })
+      .catch(() => { });
+  }
+
+  /** 导出按钮操作 */
+  function handleExport() {
+    exportNoContract(queryParams.value);
+  }
+
+  function startDateChangeHandler(row, startDate) {
+    if (startDate) {
+      // console.log(startDate)
+      row.endMonth = proxy
+        .moment(startDate)
+        .add(row.monthNum- 1, "M")
+        .format("YYYY-MM-DD");
+    } else row.endMonth = null;
+  }
+
+  function querySearchCompanyAsync(queryString, cb) {
+    const query =
+      queryString.length > 0
+        ? {
+          keyword: queryString,
+          pageSize: 20,
+          pageNum: 1,
+          orderByColumn: "create_time",
+        }
+        : { pageSize: 20, pageNum: 1, orderByColumn: "create_time" };
+    listCompany(query).then((res) => {
+      cb(res.rows);
+    });
+  }
+
+  function handleSelectCompany(item) {
+    form.value.companyName = item.name;
+    form.value.companyId = item.id;
+  }
+
+  function saveHandler() {
+    if (form.value.companyId == null) {
+      proxy.$modal.msgError("请选择公司");
+      return;
+    }
+    if (form.value.remark == null || form.value.remark === "") {
+      proxy.$modal.msgError("请输入备注");
+      return;
+    }
+    if (form.value.id == null) {
+      addWorkOrder(form.value).then((res) => {
+        formCancel();
+        getList();
+      });
+    }
+  }
+
+  function getTransactor(row) {
+    if (row.entrusts != null && row.entrusts.length > 0) {
+      const names = Array.from(new Set(row.entrusts.map((v) => v.toAccountName)));
+      return names.join(",");
+    } else {
+      return row.serviceName;
+    }
+  }
+
+  function showAddCompanyDialog() {
+    addCompanyDialogRef.value.open();
+  }
+
+  function Upgrade() {
+
+
+    //这个是检查是否有未匹配工单
+    checkMatchWorkOrder();
+    //这个是完成升级调用的
+    // const promise = Promise.resolve(completeUpgrade());
+    // promise
+  }
+
+  function checkMatchWorkOrder() {
+    const promise = checkWorkOrder();
+    promise.then((res)=>{
+      if(res.msg === "true"){
+        return Promise.reject("您尚未完成工单匹配,还有工单缺少合同,请先去补全合同");
+      }else{
+      return ElMessageBox.confirm("升级后,您的账套将会切换成为标准版,您确定完成吗").then(()=>{
+          fullscreenLoading.value = true;
+          return completeUpgrade()
+        }).catch((e)=>{
+        return Promise.reject("取消升级");
+      });
+      }
+    })
+      .then((res) => {
+      fullscreenLoading.value = false;
+      proxy.$alert(
+          "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+          res.msg +
+          "</div>"
+          ,
+          {dangerouslyUseHTMLString: true}
+      );
+    })
+      .catch((e) => {
+        fullscreenLoading.value = false;
+          if(e !== "取消升级"){
+            proxy.$alert(
+                "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+                e +
+                "</div>"
+                ,
+                {dangerouslyUseHTMLString: true}
+            );
+          }
+      });
+  }
+  getList();
+</script>
+<style>
+  #listbutton{
+    display: flex;
+    justify-content: space-between;
+  }
+</style>

+ 1728 - 0
src/views/business/upgrade/order/form.vue

@@ -0,0 +1,1728 @@
+<template>
+  <!-- 添加或修改项目信息对话框 -->
+  <div class="el-drawer__wrapper">
+    <el-drawer :title="title" v-model="visible" direction="rtl" size="100%">
+      <div class="page-container form-container">
+        <div class="form-btns-container">
+          <span class="title-label"><el-icon>
+              <Document />
+            </el-icon>
+            合同信息</span>
+
+          <el-button v-if="form.verifyStatus == 0 && !editStatus" type="warning" size="small" icon="Edit"
+            @click="editStatus = true">修改</el-button>
+          <el-button v-if="form.id && editStatus" type="info" size="small" icon="Close" @click="
+              () => {
+                editStatus = false;
+                getForm();
+              }
+            ">取消修改</el-button>
+          <el-button v-if="form.id" type="success" size="small" icon="refresh" @click="getForm">
+            刷新
+          </el-button>
+          <el-button v-show="form.id && !editStatus && form.verifyStatus == 0"
+            v-hasPermi="['business:upgrade:order:verify']" type="primary" size="small" icon="check"
+            @click="verifyHandler">审核通过</el-button>
+          <el-button v-show="form.id && !editStatus && form.verifyStatus == 0"
+            v-hasPermi="['business:upgrade:order:verify']" type="danger" size="small" icon="back"
+            @click="rejectHandler">驳回</el-button>
+          <el-button v-show="form.alterNumber > 0 && !editStatus" v-hasPermi="['business:upgrade:order:history']"
+            type="info" size="small" icon="Notebook" @click="showHistoryList">历史记录</el-button>
+
+          <div class="screen-btn" @click="handleScreen">
+            <template v-if="!isFullscreen">
+              <i class="fa fa-window-maximize" aria-hidden="true" />
+              <!-- <span>全屏</span> -->
+            </template>
+            <template v-else>
+              <i class="fa fa-window-restore" aria-hidden="true" />
+              <!-- <span>还原</span> -->
+            </template>
+          </div>
+          <div class="close-btn" @click="cancel">
+            <i class="fa fa-times" aria-hidden="true" />
+            <!-- <span>关闭</span> -->
+          </div>
+        </div>
+        <div class="Y-scrollbar" style="
+            position: absolute;
+            top: 32px;
+            bottom: 0;
+            width: 100%;
+            overflow: auto;
+          "></div>
+        <el-form ref="orderRef" class="master-container" size="small" :model="form" :rules="rules" label-width="100px">
+          <el-row :gutter="30">
+            <el-col :span="6">
+              <el-form-item label="合同编号" prop="contractNo">
+                <el-input v-if="editStatus && type !== 'alterOrder'" v-model="form.contractNo" placeholder="请输入合同编号"
+                  width="100px" />
+                <span v-else>{{ form.contractNo }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="合同类型" prop="contractType">
+                <el-radio-group v-if="editStatus || type == 'alterOrder'" v-model="form.contractType"
+                  @change="contractTypeChangeHandler">
+                  <el-radio :label="0">新签</el-radio>
+                  <el-radio :label="1">续签</el-radio>
+                </el-radio-group>
+                <span v-else>{{
+                  form.contractType === 0 ? "新签" : "续签"
+                  }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="客户名称" prop="companyId">
+                <template v-if="editStatus && type !== 'alterOrder'">
+                  <el-autocomplete :fetch-suggestions="querySearchCompanyAsync" :trigger-on-focus="true"
+                    v-model="form.companyName" placeholder="请输入客户名称" popper-class="my-autocomplete" clearable
+                    @clear="handleClearCompany" @select="handleSelectCompany" style="width: 100%">
+                    <template #append>
+                      <el-button icon="Plus" @click="showAddCompanyDialog">
+                      </el-button>
+                    </template>
+                    <template #default="{ item }">
+                      <div style="
+                          display: flex;
+                          flex-direction: row;
+                          justify-content: space-between;
+                        ">
+                        <div class="name" style="font-size: 12px">
+                          {{ item.name }}
+                        </div>
+                      </div>
+                    </template>
+                  </el-autocomplete>
+                  <!-- <el-button @click="showAddCompanyDialog">
+                    <el-icon class="el-input__icon">
+                      <plus />
+                    </el-icon>
+                  </el-button> -->
+                </template>
+                <el-link :underline="false" type="primary" @click="handleInfo(form)" v-else>{{ form.companyName
+                  }}</el-link>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="签约日期" prop="formDate">
+                <el-date-picker v-if="editStatus && type !== 'alterOrder'" clearable v-model="form.formDate" type="date"
+                  value-format="YYYY-MM-DD" placeholder="请选择签约日期">
+                </el-date-picker>
+                <span v-else>{{ form.formDate }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="签单人" prop="signerName">
+                <el-autocomplete v-if="editStatus && type !== 'alterOrder'" :fetch-suggestions="querySearchAsync"
+                  :trigger-on-focus="true" style="width: 100%" v-model="form.signerName" placeholder="请输入签单人"
+                  popper-class="my-autocomplete" @select="handleSelectEmployee">
+                  <template #default="{ item }">
+                    <div style="
+                        display: flex;
+                        flex-direction: row;
+                        justify-content: space-between;
+                      ">
+                      <div class="name" style="font-size: 12px">
+                        {{ item.nickName }}
+                      </div>
+                      <span class="code" style="font-size: 10px; color: darkgrey">{{ item.userName }}</span>
+                    </div>
+                  </template>
+                </el-autocomplete>
+                <span v-else>{{ form.signerName }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col v-if="form.verifyStatus === 4" :span="6">
+              <el-form-item label="驳回原因" prop="verifyRemark">
+                <span>{{ form.verifyRemark }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8" style="width: 100%">
+              <el-form-item label="来源" prop="sourceCategoryName" style="width: 100%">
+                <CustomerFormCom ref="CustomerFormComRef" :edit-status="editStatus && type !== 'alterOrder'"
+                  :form-data="form" :source-categories="sourceCategories" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="4">
+              <el-form-item label="客户标签" prop="customerLabelId">
+                <span>{{ selectedOptionLabel }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="甲方" prop="boss">
+                <el-input v-if="editStatus" v-model="form.boss" style="width: 100%; margin: 0; padding: 0"
+                  placeholder="请输入甲方名称" />
+                <span v-else>{{ form.boss }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="乙方" prop="party">
+                <el-input v-if="editStatus" v-model="form.party" style="width: 100%; margin: 0; padding: 0"
+                  placeholder="请输入乙方名称" />
+                <span v-else>{{ form.party }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="14">
+              <el-form-item label="备注" prop="remark">
+                <el-input v-if="editStatus" v-model="form.remark" show-word-limit maxlength="200"
+                  style="width: 100%; margin: 0; padding: 0" placeholder="请输入备注" type="textarea" :rows="2" />
+                <span v-else>{{ form.remark }}</span>
+              </el-form-item>
+            </el-col>
+            <br />
+            <el-col :span="24">
+              <el-tabs v-model="form.serviceType" size="small" class="demo-tabs" @tab-change="handleServiceTypeClick">
+                <el-tab-pane :disabled="!editStatus" label="循环服务" :name="1">
+                  <el-row>
+                    <el-col :span="24">
+                      <el-checkbox-group v-model="loops" @change="(arg) => changeDetails('loop', arg)">
+                        <el-checkbox v-for="(item, index) in loopTasks" :key="index" :label="item.id"
+                          :disabled="item.isDisabled || !editStatus">{{ item.name }}</el-checkbox>
+                      </el-checkbox-group>
+                    </el-col>
+                    <el-col :span="24">
+                      <el-row v-for="(item, index) in loopDetails" :key="index" style="
+                          border-radius: 5px;
+                          border-color: rgba(0, 0, 0, 20%);
+                          border-style: solid;
+                          border-width: 1px;
+                          margin-bottom: 10px;
+                        ">
+                        <el-col :span="4" style="padding-top: 18px">
+                          <el-form-item label="服务项目">
+                            {{ item.taskTypeName }}
+                          </el-form-item>
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px">
+                          <el-form-item label="月单价">
+                            <el-input-number v-if="editStatus" v-model="item.price" :precision="2" :step="0.1" :min="0"
+                              :controls="false" @change="
+                                (arg) =>
+                                  inputChangeHandler('loop', 'price', item, arg)
+                              " />
+                            <div v-else>{{ rowNum(item.price) }}</div>
+                          </el-form-item>
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px">
+                          <el-form-item label="服务月数">
+                            <el-input-number v-if="editStatus" v-model="item.serviceNum" :step="1" step-strictly
+                              :min="0" :controls="false" @change="
+                                (arg) =>
+                                  inputChangeHandler(
+                                    'loop',
+                                    'serviceNum',
+                                    item,
+                                    arg
+                                  )
+                              " />
+                            <div v-else>{{ item.serviceNum }}</div>
+                          </el-form-item>
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px">
+                          <el-form-item label="赠送月数">
+                            <el-input-number v-if="editStatus" v-model="item.freeNum" :step="1" step-strictly :min="0"
+                              :controls="false" @change="
+                                (arg) =>
+                                  inputChangeHandler(
+                                    'loop',
+                                    'freeNum',
+                                    item,
+                                    arg
+                                  )
+                              " />
+                            <div v-else>{{ item.freeNum }}</div>
+                          </el-form-item>
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px">
+                          <el-form-item label="优惠金额">
+                            <el-input-number v-if="editStatus" v-model="item.discountAmount" :precision="2" :step="0.1"
+                              :min="0" :controls="false" @change="
+                                (arg) =>
+                                  inputChangeHandler('loop', 'discountAmount', item, arg)
+                              " />
+                            <div v-else>{{ rowNum(item.discountAmount) }}</div>
+                          </el-form-item>
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px">
+                          <el-form-item label="合计金额">
+                            <div>{{ rowNum(item.amount) }}</div>
+                          </el-form-item>
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px">
+                          <el-form-item label="服务区间"
+                            v-if="item.timeVo != null && item.timeVo != undefined &&  type !== 'alterOrder'">
+                            <div>{{ item.timeVo.startTime.substr(0,item.timeVo.startTime.length - 3) }} ~ {{
+                              item.timeVo.endTime.substr(0,item.timeVo.endTime.length - 3) }}</div>
+                          </el-form-item>
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px">
+                          <el-form-item label="工单编号" >
+                            <div>{{item.id}}</div>
+                            <div><el-button link type="primary" size="small" @click="workOrderIdUpdate(item.id)"
+                                            v-hasPermi="['business:upgrade:order:edit']">更换</el-button></div>
+                          </el-form-item>
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px" v-if="item.taskTypeId ==4">
+
+                        </el-col>
+                        <el-col :span="4" style="padding-top: 18px" v-if="item.taskTypeId ==4">
+                          <el-form-item label="所属区">
+                            <el-select v-if="editStatus" v-model="item.belongRegion" style="margin-right: 5px">
+                              <el-option v-for="region in belong_region" :key="region.value" :label="region.label"
+                                :value="region.id"></el-option>
+                            </el-select>
+                            <span v-else>{{item.regionName}}</span>
+                          </el-form-item>
+                        </el-col>
+                      </el-row>
+                    </el-col>
+
+                    <el-divider />
+                  </el-row>
+                </el-tab-pane>
+                <el-tab-pane :disabled="!editStatus " label="代办服务" :name="2">
+                  <el-checkbox-group :disabled="!editStatus" v-model="onces"
+                    @change="(arg) => changeDetails('once', arg)">
+                    <el-checkbox v-for="(item, index) in onceTasks" :key="index" :label="item.id">{{ item.name
+                      }}</el-checkbox>
+                  </el-checkbox-group>
+                  <el-col :span="24">
+                    <el-row v-for="(item, index) in onceDetails" :key="index" style="
+                        border-radius: 5px;
+                        border-color: rgba(0, 0, 0, 20%);
+                        border-style: solid;
+                        border-width: 1px;
+                        margin-bottom: 10px;
+                      ">
+                      <el-col :span="4" style="padding-top: 18px">
+                        <el-form-item label="服务项目">
+                          {{ item.taskTypeName }}
+                        </el-form-item>
+                      </el-col>
+                      <el-col v-if="item.payAddress === 1" :span="9" style="
+                          padding-top: 18px;
+                          padding-left: 35px;
+                          display: flex;
+                          flex-direction: column;
+                          margin-bottom: 18px;
+                        ">
+                        <el-radio-group v-if="editStatus" v-model="item.addressStyle" @change="changeProcesses(item)">
+                          <el-radio :label="1" style="margin-bottom: 5px">
+                            <template #default>
+                              <div style="
+                                  display: flex;
+                                  flex-direction: row;
+                                  width: 300px;
+                                  justify-content: space-between;
+                                ">
+                                <div style="
+                                    display: inline-block;
+                                    height: 24px;
+                                    line-height: 24px;
+                                    margin-right: 10px;
+                                  ">
+                                  自有地址
+                                </div>
+                                <div>
+                                  <el-select :disabled="item.addressStyle === 2" v-model="item.provinceCode"
+                                    placeholder="省份" style="width: 36%" @change="handleSelectProvince(item, index)">
+                                    <el-option v-for="item in provincesArr[index]" :key="item.code" :label="item.name"
+                                      :value="item.code" />
+                                  </el-select>
+
+                                  <el-select :disabled="item.addressStyle === 2" v-model="item.cityCode"
+                                    placeholder="城市" style="width: 37%" @change="handleSelectCity(item, index)">
+                                    <el-option v-for="item in citiesArr[index]" :key="item.code" :label="item.name"
+                                      :value="item.code" />
+                                  </el-select>
+                                  <el-select :disabled="item.addressStyle === 2" v-model="item.districtCode"
+                                    placeholder="行政区" style="width: 37%" @change="handleSelectDistrict(item, index)">
+                                    <el-option v-for="item in districtsArr[index]" :key="item.code" :label="item.name"
+                                      :value="item.code" />
+                                  </el-select>
+                                </div>
+                              </div>
+                            </template>
+                          </el-radio>
+                          <el-radio :label="2" style="margin-bottom: 5px">
+                            <template #default>
+                              <div style="
+                                  display: flex;
+                                  flex-direction: row;
+                                  width: 325px;
+                                  justify-content: space-between;
+                                ">
+                                <div style="
+                                    display: inline-block;
+                                    height: 24px;
+                                    line-height: 24px;
+                                    margin-right: 10px;
+                                  ">
+                                  虚拟地址
+                                </div>
+                                <el-select :disabled="item.addressStyle !== 2" v-model="item.fictionAddressId"
+                                  style="margin-right: 5px">
+                                  <el-option v-for="item in virtual_address" :key="item.value" :label="item.label"
+                                    :value="item.id"></el-option>
+                                </el-select>
+                                <div style="
+                                    display: inline-block;
+                                    height: 24px;
+                                    line-height: 24px;
+                                  ">
+                                  金额:
+                                </div>
+                                <el-input-number :disabled="item.addressStyle !== 2" v-if="editStatus"
+                                  v-model="item.addressAmount" :precision="2" :step="0.01" step-strictly
+                                  :controls="false" @change="
+                                    (arg) =>
+                                      inputChangeHandler(
+                                        'once',
+                                        'addressAmount',
+                                        item,
+                                        arg
+                                      )
+                                  " />
+                              </div>
+                            </template>
+                          </el-radio>
+                        </el-radio-group>
+                        <div v-else style="
+                            display: flex;
+                            flex-direction: row;
+                            width: 300px;
+                            justify-content: space-between;
+                            font-size: 12px;
+                          ">
+                          <div>
+                            {{
+                            item.addressStyle === 1
+                            ? "自有地址"
+                            : item.addressStyle === 2
+                            ? "虚拟地址"
+                            : ""
+                            }}
+                          </div>
+                          <div v-if="item.addressStyle === 1">
+                            注册地区:{{ item.province }} - {{ item.city }} -
+                            {{ item.district }}
+                          </div>
+                          <div v-if="item.addressStyle === 2">
+                            {{ (item.fictionAddress) }}
+                          </div>
+                          <div v-if="item.addressStyle === 2">
+                            金额:{{ rowNum(item.addressAmount) }}
+                          </div>
+                        </div>
+                      </el-col>
+                      <el-col v-if="item.payAddress === 0" :span="9" style="
+                          padding-top: 18px;
+                          display: flex;
+                          flex-direction: column;
+                          margin-bottom: 18px;
+                        ">
+                        <el-form-item v-if="item.taskTypeId === '6'" label="变更类型">
+                          <el-select v-if="editStatus" v-model="item.alterType" style="width: 280px">
+                            <el-option v-for="alter in alterTypes" :label="alter.label" :key="alter.value"
+                              :value="alter.value">
+                            </el-option>
+                          </el-select>
+                          <div v-else>{{ item.alterType }}</div>
+                        </el-form-item>
+                        <div v-if="item.alterType === '跨区变更'" style="margin-left: 60px">
+                          <el-radio-group v-if="editStatus" v-model="item.addressStyle" @change="changeProcesses(item)">
+                            <el-radio :label="1" style="margin-bottom: 5px">
+                              <template #default>
+                                <div style="
+                                    display: flex;
+                                    flex-direction: row;
+                                    width: 300px;
+                                    justify-content: space-between;
+                                  ">
+                                  <div style="
+                                      display: inline-block;
+                                      height: 24px;
+                                      line-height: 24px;
+                                      margin-right: 10px;
+                                    ">
+                                    自有地址
+                                  </div>
+                                  <div>
+                                    <el-select :disabled="item.addressStyle === 2" v-model="item.provinceCode"
+                                      placeholder="省份" style="width: 33.33%" @change="
+                                        handleSelectProvince(item, index)
+                                      ">
+                                      <el-option v-for="item in provincesArr[index]" :key="item.code" :label="item.name"
+                                        :value="item.code" />
+                                    </el-select>
+                                    <el-select :disabled="item.addressStyle === 2" v-model="item.cityCode"
+                                      placeholder="城市" style="width: 33.33%" @change="handleSelectCity(item, index)">
+                                      <el-option v-for="item in citiesArr[index]" :key="item.code" :label="item.name"
+                                        :value="item.code" />
+                                    </el-select>
+                                    <el-select :disabled="item.addressStyle === 2" v-model="item.districtCode"
+                                      placeholder="行政区" style="width: 33.33%" @change="
+                                        handleSelectDistrict(item, index)
+                                      ">
+                                      <el-option v-for="item in districtsArr[index]" :key="item.code" :label="item.name"
+                                        :value="item.code" />
+                                    </el-select>
+                                  </div>
+                                </div>
+                              </template>
+                            </el-radio>
+                            <el-radio :label="2" style="margin-bottom: 5px">
+                              <template #default>
+                                <div style="
+                                    display: flex;
+                                    flex-direction: row;
+                                    width: 300px;
+                                    justify-content: space-between;
+                                  ">
+                                  <div style="
+                                      display: inline-block;
+                                      height: 24px;
+                                      line-height: 24px;
+                                      margin-right: 10px;
+                                    ">
+                                    虚拟地址
+                                  </div>
+                                  <el-select :disabled="item.addressStyle !== 2" v-model="item.fictionAddressId"
+                                    style="margin-right: 5px">
+                                    <el-option v-for="item in virtual_address" :key="item.value" :label="item.label"
+                                      :value="item.id"></el-option>
+                                  </el-select>
+                                  <div style="
+                                      display: inline-block;
+                                      height: 24px;
+                                      line-height: 24px;
+                                    ">
+                                    金额:
+                                  </div>
+                                  <el-input-number :disabled="item.addressStyle !== 2" v-if="editStatus"
+                                    v-model="item.addressAmount" :precision="2" :step="0.01" step-strictly
+                                    :controls="false" @change="
+                                      (arg) =>
+                                        inputChangeHandler(
+                                          'once',
+                                          'addressAmount',
+                                          item,
+                                          arg
+                                        )
+                                    " />
+                                </div>
+                              </template>
+                            </el-radio>
+                          </el-radio-group>
+                          <div v-else style="
+                              display: flex;
+                              flex-direction: row;
+                              width: 300px;
+                              justify-content: space-between;
+                              font-size: 12px;
+                            ">
+                            <div>
+                              {{
+                              item.addressStyle === 1
+                              ? "自有地址"
+                              : item.addressStyle === 2
+                              ? "虚拟地址"
+                              : ""
+                              }}
+                            </div>
+                            <div v-if="item.addressStyle === 1">
+                              注册地区:{{ item.province }} - {{ item.city }} -
+                              {{ item.district }}
+                            </div>
+                            <div v-if="item.addressStyle === 2">
+                              {{ item.fictionAddress }}
+                            </div>
+                            <div v-if="item.addressStyle === 2">
+                              金额:{{ rowNum(item.addressAmount) }}
+                            </div>
+                          </div>
+                        </div>
+                        <el-form-item v-else label="办理地区">
+                          <div v-if="editStatus" style="
+                              display: flex;
+                              flex-direction: row;
+                              width: 280px;
+                              justify-content: space-between;
+                            ">
+                            <el-select v-model="item.provinceCode" placeholder="省份" style="width: 33.33%"
+                              @click.stop="null" @change="handleSelectProvince(item, index)">
+                              <el-option v-for="item in provincesArr[index]" :key="item.code" :label="item.name"
+                                :value="item.code" />
+                            </el-select>
+                            <el-select v-model="item.cityCode" placeholder="城市" style="width: 33.33%"
+                              @change="handleSelectCity(item, index)" @click.stop="null">
+                              <el-option v-for="item in citiesArr[index]" :key="item.code" :label="item.name"
+                                :value="item.code" />
+                            </el-select>
+                            <el-select v-model="item.districtCode" placeholder="行政区" style="width: 33.33%"
+                              @change="handleSelectDistrict(item, index)" @click.stop="null">
+                              <el-option v-for="item in districtsArr[index]" :key="item.code" :label="item.name"
+                                :value="item.code" />
+                            </el-select>
+                          </div>
+
+                          <div v-else style="
+                              display: flex;
+                              flex-direction: row;
+                              width: 300px;
+                              justify-content: space-between;
+                            ">
+                            {{ item.province }} - {{ item.city }} -
+                            {{ item.district }}
+                          </div>
+                        </el-form-item>
+                      </el-col>
+                      <el-col :span="7" style="padding-top: 18px; margin-bottom: 18px">
+                        <el-checkbox-group :disabled="!editStatus" v-model="item.processes"
+                          @change="(arg) => changeProcesses(item, arg)" style="display: flex; flex-direction: column">
+                          <el-checkbox v-for="(process, index) in item.defaultProcesses" :key="index" :label="process">
+                            <template #default>
+                              <div style="
+                                  display: flex;
+                                  flex-direction: row;
+                                  width: 300px;
+                                  justify-content: space-between;
+                                ">
+                                <div style="
+                                    display: inline-block;
+                                    height: 24px;
+                                    line-height: 24px;
+                                    margin-right: 10px;
+                                    width: 80px;
+                                  ">
+                                  {{ process.taskTypeDetailName }}
+                                </div>
+                                <div style="
+                                    display: inline-block;
+                                    height: 24px;
+                                    line-height: 24px;
+                                  ">
+                                  金额:
+                                </div>
+                                <el-input-number :disabled="
+                                    checkedProcess(
+                                      process.taskTypeDetailId,
+                                      item
+                                    )
+                                  " size="small" v-if="editStatus" v-model="process.amount" :precision="2" :step="0.01"
+                                  step-strictly :controls="false" style="width: 100px" @click.stop="null" @change="
+                                    (arg) =>
+                                      inputChangeHandler(
+                                        'process',
+                                        'amount',
+                                        process,
+                                        arg,
+                                        item
+                                      )
+                                  " />
+                                <div v-else style="
+                                    display: inline-block;
+                                    height: 24px;
+                                    line-height: 24px;
+                                    width: 40px;
+                                    text-align: right;
+                                  ">
+                                  {{ rowNum(process.amount) }}
+                                </div>
+                              </div>
+                            </template>
+                            <!-- {{ process.name }} -->
+                          </el-checkbox>
+                        </el-checkbox-group>
+                      </el-col>
+                      <el-col :span="3" style="
+                          padding-top: 18px;
+                          display: flex;
+                          flex-direction: column;
+                          margin-bottom: 18px;
+                        ">
+                        <div style="
+                            display: flex;
+                            flex-direction: row;
+                            font-size: 12px;
+                          ">
+                          <div style="
+                              display: inline-block;
+                              height: 24px;
+                              line-height: 24px;
+                              margin-left: 10px;
+                            ">
+                            总金额:
+                          </div>
+                          <div style="
+                              display: inline-block;
+                              height: 24px;
+                              line-height: 24px;
+                            ">
+                            {{ rowNum(item.amount) }}
+                          </div>
+                        </div>
+                      </el-col>
+                      <el-col :span="4" style="padding-top: 18px">
+
+                      </el-col>
+                      <el-col v-if="item.taskTypeId == 9 || item.taskTypeId == 8" :span="9" style="
+                          padding-top: 18px;
+                          display: flex;
+                          flex-direction: column;
+                          margin-bottom: 18px;
+                        ">
+                        <el-form-item label="备注" prop="remark">
+                          <el-input v-model="item.remark" v-if="editStatus" />
+                          <div v-else>{{ item.remark }}</div>
+                        </el-form-item>
+                      </el-col>
+                    </el-row>
+                  </el-col>
+                  <el-divider />
+                </el-tab-pane>
+              </el-tabs>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="合计:" prop="remark">
+                <span>{{ rowNum(form.amount) }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="优惠金额:">
+                <span>{{ rowNum(form.discountAmount) }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="实收:">
+                <div>{{ rowNum(form.trueAmount) }}</div>
+              </el-form-item>
+            </el-col>
+            <br />
+            <el-col :span="24">
+              <div class="details-head" style="font-size: 12px">
+                <div class="title">
+                  <i class="fa fa-th-list" aria-hidden="true" /> 合同附件
+                </div>
+                <div class="details-btns-container" style="display: flex">
+                  <el-upload v-if="editStatus && type != 'alterOrder'" action="#" :http-request="upload"
+                    :with-credentials="true" :show-file-list="false" multiple>
+                    <el-button style="margin-top: 10px; margin-bottom:10px;" size="small" type="primary"
+                      icon="Upload">点击上传</el-button>
+                  </el-upload>
+                </div>
+              </div>
+              <div class="details-body" style="height: 200px">
+                <el-table ref="filesTable" :data="form.files" size="small" height="100%" border
+                  header-row-class-name="list-header-row">
+                  <el-table-column type="index" label="序号" width="47" align="center" />
+                  <el-table-column label="文件名" prop="originalFileName" align="center">
+                    <template #default="scope">
+                      <el-link :href="`${baseUrl}${scope.row.fileUrl}`" :underline="false" target="_blank"
+                        type="primary">
+                        {{ scope.row.originalFileName }}
+                      </el-link>
+                    </template>
+                  </el-table-column>
+                  <el-table-column v-if="editStatus && type !== 'alterOrder'" label="操作" width="70" align="center">
+                    <template #default="scope">
+                      <el-button link size="small" type="danger" @click="handleDelFile(scope.$index)">删除</el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </div>
+              <br />
+            </el-col>
+
+            <el-col v-if="editStatus" :span="24" style="
+                text-align: center;
+                display: flex;
+                flex-direction: row;
+                justify-content: center;
+              ">
+              <el-button size="small" type="primary" icon="Finished" style="width: 160px"
+                @click="submitForm">保存</el-button>
+            </el-col>
+          </el-row>
+
+          <br />
+        </el-form>
+      </div>
+    </el-drawer>
+    <el-dialog title="驳回详情" v-model="rejectOpen" width="500px" append-to-body draggable :close-on-click-modal="false">
+      <el-form ref="dictRef" :model="form" label-width="100">
+        <el-form-item label="驳回原因" :prop="verifyRemark">
+          <el-input v-model.trim="form.verifyRemark" type="textarea" :rows="3" placeholder="请输入驳回原因" maxlength="200"
+            show-word-limit />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" icon="Finished" size="small" @click="verifyUpload(4)">确 定</el-button>
+          <el-button icon="close" size="small" @click="rejectCancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <el-dialog title="是否续签" v-model="verifyOpen" width="600px" append-to-body draggable>
+      <el-form ref="dictRef" :model="verifyForm" label-width="380" size="small">
+        <el-form-item v-for="item in redirectDetails" :key="item.id"
+          :label="`${item.taskTypeName}上个任务结束月:${item.endMonth}是否重新开始`">
+          <el-checkbox v-model="item.redirect" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" icon="Finished" size="small" @click="redirectVerify()">确 定</el-button>
+          <el-button icon="close" size="small" @click="verifyFormClose">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <AddCompanyDialog ref="addCompanyDialogRef" />
+    <WorkOrderDialog ref="workOrderDialogRef" />
+    <company-form ref="companyRef" :get-list="getList"></company-form>
+    <dialog-history-choice ref="historyChoiceRef" @choice="historyChoiceHandle" />
+  </div>
+</template>
+<script setup>
+  import { uploadFile } from "@/api/tool/file";
+  import { listLableNoPage } from "@/api/business/lable";
+  import AddCompanyDialog from "../AddCompanyDialog";
+  import WorkOrderDialog from "@/views/business/upgrade/WorkOrderDialog.vue";
+  import match from "@/utils/match";
+  import {
+    getOrder,
+    initTaskTypes,
+    addOrder,
+    updateOrder,
+    verifyOrder,
+    alterOrder,
+    dissolutionOrder,
+    verifyCheckOrder,
+  } from "@/api/upgrade/contract";
+  import { listSource } from "@/api/settings/source";
+  import { listCompany } from "@/api/business/crm/company";
+  import { listUser } from "@/api/system/user";
+  import CustomerFormCom from "@/components/CustomerFormCom";
+  import DialogHistoryChoice from "@/views/dialog/DialogHistoryChoice.vue";
+  import { formatDate, rowNum } from "@/utils/index";
+  import { ref } from "vue";
+  import companyForm from "@/views/business/crm/company/formView.vue";
+  import useUserStore from "@/store/modules/user";
+  // import { it } from "element-plus/es/locale";
+  const { proxy } = getCurrentInstance();
+  const verifyOpen = ref(false);
+  const verifyForm = ref({});
+  const redirectDetails = ref([]);
+  const baseUrl = import.meta.env.VITE_APP_BASE_API;
+  const historyChoiceRef = ref(null);
+  const alterTypes = ref([
+    {
+      value: "普通变更",
+      label: "普通变更",
+    },
+    {
+      value: "股权变更",
+      label: "股权变更",
+    },
+    {
+      value: "减资",
+      label: "减资",
+    },
+    {
+      value: "跨区变更",
+      label: "跨区变更",
+    },
+  ]);
+
+  /** 父组件传参 */
+  const props = defineProps({
+    getList: {
+      type: Function,
+      default: () => { },
+    },
+  });
+  const { getList } = toRefs(props);
+  /** 字典数组区 */
+  const { virtual_address } = proxy.useDict("virtual_address");
+  const { belong_region } = proxy.useDict("belong_region");
+
+  /** 表单抽屉 页变量 */
+  const title = ref("");
+  const loading = ref(false);
+  const multiple = ref(true);
+  const visible = ref(false);
+  const editStatus = ref(false);
+  const loopTasks = ref([]);
+  const onceTasks = ref([]);
+  const sourceCategories = ref([]);
+  const loops = ref([]);
+  const onces = ref([]);
+  const type = ref("");
+  const addCompanyDialogRef = ref(null);
+  const workOrderDialogRef = ref(null);
+  const rejectOpen = ref(false);
+
+  // 循环任务明细
+  const loopDetails = ref([]);
+  // 单次任务明细
+  const onceDetails = ref([]);
+  const detailEmpty = {
+    id: null,
+    taskTypeName: "",
+    taskTypeId: null,
+    serviceNum: undefined,
+    freeNum: undefined,
+    price: undefined,
+    amount: undefined,
+    addressStyle: undefined,
+    address: undefined,
+    fictionAddressId: undefined,
+    tenantId: undefined,
+    province: "",
+    city: "",
+    district: "",
+    addressStyle: 1,
+    provinceId: undefined,
+    processes: [],
+    defaultProcesses: [],
+  };
+
+  //地址数组
+  const provincesArr = ref([]);
+  const citiesArr = ref([]);
+  const districtsArr = ref([]);
+
+  const provinces = ref(proxy.region.getProvinces());
+  provinces.value.unshift({ code: "", name: "全部" });
+  const cities = ref([]);
+  const districts = ref([]);
+  const options = ref([]);
+  const contractEmpty = {
+    serviceType: 1,
+    contractType: 0,
+    formDate: formatDate(new Date(), "yyyy-MM-dd"),
+    signerId: useUserStore().user.userId,
+    signerName: useUserStore().user.nickName,
+    files: [],
+  };
+  const isFullscreen = ref(false);
+  const webHost = import.meta.env.VITE_APP_BASE_API;
+  const data = reactive({
+    form: {},
+    // rules: {
+    //   contractNo: [
+    //     { required: true, message: "合同编号不能为空", trigger: "blur" },
+    //   ],
+    //   companyId: [{ required: true, message: "请选择有效客户", trigger: "blur" }],
+    //   formDate: [
+    //      { required: editStatus.value ? false : true, message: "签约日期不能为空", trigger: "blur" },
+    //   ],
+    //   amount: [{ required: true, message: "签约金额不能为空", trigger: "blur" }],
+    //   // signerName: [
+    //   //   { required: true, message: "签单人不能为空", trigger: "change" },
+    //   // ],
+    //   contractType: [
+    //     { required: true, message: "合同类型不能为空", trigger: "change" },
+    //   ],
+    //   serviceType: [
+    //     { required: true, message: "任务类型不能为空", trigger: "change" },
+    //   ],
+    // },
+  });
+
+  const rules = computed(() => ({
+    contractNo: [
+      { required: true, message: "合同编号不能为空", trigger: "blur" },
+    ],
+    companyId: [
+      { required: type.value == "alterOrder" ? false : true, message: "请选择有效客户", trigger: "blur" },
+    ],
+    formDate: [
+      { required: type.value == "alterOrder" ? false : true, message: "签约日期不能为空", trigger: "blur" },
+    ],
+    amount: [
+      { required: true, message: "签约金额不能为空", trigger: "blur" },
+    ],
+    contractType: [
+      { required: true, message: "合同类型不能为空", trigger: "change" },
+    ],
+    serviceType: [
+      { required: true, message: "任务类型不能为空", trigger: "change" },
+    ],
+    party: [
+      { required: true, message: "乙方不能为空", trigger: "blur" },
+    ],
+  }));
+  const { form, } = toRefs(data);
+  /***********************  方法区  ****************************/
+  /** 打开抽屉 */
+  function open(id) {
+    reset();
+
+    visible.value = true;
+
+    if (id) {
+      Promise.all([initTaskTypes(), listSource(), getOrder(id)]).then((res) => {
+        loopTasks.value = res[0].data.loopTasks;
+        onceTasks.value = res[0].data.onceTasks;
+        sourceCategories.value = res[1].rows;
+        form.value = res[2].data;
+        type.value =
+          type.value == "" && form.value.status === 8 ? "alterOrder" : type.value;
+        parseDetail(form.value.details, form.value);
+        // console.log(onceDetails.value)
+        editStatus.value = false;
+        title.value = "修改订单信息";
+        initRegion();
+      });
+      // getOrder(id).then(response => {
+      // })
+    } else {
+      Promise.all([initTaskTypes(), listSource()]).then((res) => {
+        loopTasks.value = res[0].data.loopTasks;
+        onceTasks.value = res[0].data.onceTasks;
+        sourceCategories.value = res[1].rows;
+      });
+      editStatus.value = true;
+      title.value = "添加订单信息";
+    }
+    getOption()
+
+
+
+  }
+  function getOption() {
+    listLableNoPage().then(res => {
+      options.value = res.data
+    })
+  }
+  const selectedOptionLabel = computed(() => {
+    const selectedOption = options.value.find(option => option.id === form.value.customerLabelId);
+    return selectedOption ? selectedOption.lable : '';
+  });
+
+  function openSimple(id, optionType) {
+    reset();
+    visible.value = true;
+    type.value = optionType || "";
+
+    if (id) {
+      Promise.all([initTaskTypes(), listSource(), getOrder(id)]).then((res) => {
+        loopTasks.value = res[0].data.loopTasks;
+        onceTasks.value = res[0].data.onceTasks;
+        sourceCategories.value = res[1].rows;
+        form.value = res[2].data;
+        console.log("loopTasks.value", loopTasks.value);
+        loopTasks.value.forEach(item => {
+          form.value.details.forEach(item2 => {
+            if (item2.taskTypeId == item.id) {
+              item.isDisabled = item2.disabled
+            }
+          })
+        })
+
+
+        parseDetail(form.value.details, form.value);
+
+        title.value = "合同变更信息";
+        if (type.value != "") {
+          editStatus.value = true;
+        } else {
+          editStatus.value = false;
+        }
+      });
+    } else {
+      Promise.all([initTaskTypes(), listSource()]).then((res) => {
+        loopTasks.value = res[0].data.loopTasks;
+        onceTasks.value = res[0].data.onceTasks;
+        sourceCategories.value = res[1].rows;
+      });
+      editStatus.value = true;
+      title.value = "添加订单信息";
+    }
+  }
+  watch(editStatus, (newValue) => {
+    console.log('editStatus changed:', newValue);
+  });
+  /** 取消按钮 */
+  function cancel() {
+    visible.value = false;
+    reset();
+  }
+  function handleInfo(row) {
+    proxy.$refs.companyRef.open(row.companyId);
+  }
+  /** 表单重置 */
+  function reset() {
+    form.value = JSON.parse(JSON.stringify(contractEmpty));
+    loops.value = [];
+    onces.value = [];
+    loopDetails.value = [];
+    onceDetails.value = [];
+    type.value = "";
+    proxy.resetForm("orderRef");
+    // belong_region.value.forEach(item => {
+    //   item.id = Number(item.id)
+    // })
+  }
+  /** 全屏缩放 */
+  function handleScreen() {
+    const dom = document.querySelector(
+      ".list-container > .el-drawer__wrapper > .el-overlay"
+    );
+    isFullscreen.value = !isFullscreen.value;
+    dom.style.position = isFullscreen.value ? "fixed" : "absolute";
+  }
+
+  function sourceValidator(rule, value, callback) {
+    if (form.value.sourceCategoryName === "") {
+      callback(new Error("来源类型不能为空"));
+      return;
+    }
+    if (
+      form.value.referrerDataSource !== "" &&
+      form.value.referrerDataSource != null &&
+      form.value.sourceName === ""
+    ) {
+      callback(new Error("来源不能为空"));
+      return;
+    }
+    return callback();
+  }
+
+  /** 提交按钮 */
+  function submitForm() {
+    const query = { userId: form.value.signerId };
+    const users = [];
+    listUser(query).then((res) => {
+      users.value = res.rows;
+      console.log(form.value.signerId);
+      // if (users.value.length == 1) {
+      //   if (
+      //     form.value.signerId == users.value[0].userId &&
+      //     form.value.signerName == users.value[0].nickName
+      //   ) {
+      //   } else {
+      //     proxy.$modal.msgError("请选择有效签单人");
+      //     return;
+      //   }
+      // } else {
+      //   proxy.$modal.msgError("请选择有效签单人");
+      //   return;
+      // }
+      const companyQuery = { id: form.value.companyId };
+      const companys = [];
+      listCompany(companyQuery).then((res) => {
+        companys.value = res.rows;
+        if (companys.value.length == 1) {
+          if (
+            form.value.companyId == companys.value[0].id &&
+            form.value.companyName == companys.value[0].name
+          ) {
+          } else {
+            proxy.$modal.msgError("请选择有效客户");
+            return;
+          }
+        } else {
+          proxy.$modal.msgError("请选择有效客户");
+          return;
+        }
+
+        proxy.$refs["orderRef"].validate((valid) => {
+          if (valid && detailValid() && amountValid()) {
+            const formValue = form.value;
+            // formValue.details.forEach(item => {
+            //   item.timeVo = null
+            // })
+
+
+
+            formValue.details =
+              form.value.serviceType === 1
+                ? loopDetails.value
+                : onceDetails.value;
+            if (formValue.id != null) {
+              if (formValue.companyId !== null) {
+                if (type.value == "") {
+                  updateOrder(formValue).then((response) => {
+                    proxy.$modal.msgSuccess("修改成功");
+                    visible.value = false;
+                    getList.value();
+                  });
+                } else if (type.value == "alterOrder") {
+                  alterOrder(formValue).then((response) => {
+                    proxy.$modal.msgSuccess("修改成功");
+                    visible.value = false;
+                    getList.value();
+                  });
+                } else if (type.value == "dissolutionOrder") {
+                  dissolutionOrder(formValue).then((response) => {
+                    proxy.$modal.msgSuccess("修改成功");
+                    visible.value = false;
+                    getList.value();
+                  });
+                } else {
+                  proxy.$modal.msgError("请选择有效客户");
+                }
+              }
+            } else {
+              addOrder(formValue).then((response) => {
+                proxy.$modal.msgSuccess("新增成功");
+                visible.value = false;
+                getList.value();
+              });
+            }
+          }
+        });
+      });
+    });
+  }
+
+  function detailValid() {
+    if (form.value.serviceType === 1) {
+      // 循环服务
+      if (loopDetails.value.length === 0) {
+        proxy.$modal.msgError("请选择至少一条任务");
+        return false;
+      }
+      // loopDetails.forEach((item, index) => {
+      for (let i = 0; i < loopDetails.value.length; i++) {
+        let item = loopDetails.value[i];
+        if (
+          (item.freeNum ? Number(item.freeNum) : 0) +
+          (item.serviceNum ? Number(item.serviceNum) : 0) <=
+          0
+        ) {
+          proxy.$modal.msgError(`${item.taskTypeName}服务月数不能为0`);
+          return false;
+        }
+        if (item.price == null || item.price === "") {
+          proxy.$modal.msgError(`${item.taskTypeName}请填写服务单价`);
+          return false;
+        }
+      }
+    } else if (form.value.serviceType === 2) {
+      // 代账服务
+      if (onceDetails.value.length === 0) {
+        proxy.$modal.msgError("请选择至少一条任务");
+        return false;
+      }
+      for (let i = 0; i < onceDetails.value.length; i++) {
+        let item = onceDetails.value[i];
+        if (item.payAddress === 1) {
+          if (item.addressStyle == null) {
+            proxy.$modal.msgError("请选择注册地址类型");
+            return false;
+          }
+          if (
+            item.addressStyle === 1 &&
+            (item.province == null || item.city == null || item.district == null)
+          ) {
+            proxy.$modal.msgError("请选择注册区域");
+            return false;
+          }
+          console.log(item);
+          if (item.addressStyle === 2 && item.fictionAddressId == null) {
+            proxy.$modal.msgError("请选择虚拟地址");
+            return false;
+          }
+          if (item.addressStyle === 2 && item.addressAmount == undefined) {
+            proxy.$modal.msgError("请填写虚拟地址金额");
+            return false;
+          }
+        }
+        if (
+          item.payAddress === 0 &&
+          (item.province == null || item.city == null || item.district == null)
+        ) {
+          proxy.$modal.msgError("请选择办理地区");
+          return false;
+        }
+        for (let j = 0; j < item.processes.length; j++) {
+          let process = item.processes[j];
+          if (process.amount == undefined) {
+            proxy.$modal.msgError(`${process.taskTypeDetailName}请填写金额`);
+            return false;
+          }
+        }
+      }
+    }
+    return true;
+  }
+
+  function amountValid() {
+    if (form.value.trueAmount < 0) {
+      proxy.$modal.msgError("实收金额不可小于0");
+      return false;
+    }
+    return true;
+  }
+
+  /** 查询表单信息  */
+  function getForm() {
+    proxy.$refs.orderRef.resetFields();
+    loading.value = true;
+    getOrder(form.value.id).then((response) => {
+      loading.value = false;
+      form.value = response.data;
+      type.value =
+        type.value == "" && form.value.status === 8 ? "alterOrder" : type.value;
+    });
+  }
+  function handleServiceTypeClick(tab) {
+    computedService();
+  }
+
+  function changeDetails(type, arg) {
+    switch (type) {
+      case "loop":
+        arg.forEach((e) => {
+          const taskType = loopTasks.value.find((v) => v.id == e);
+          if (loopDetails.value.findIndex((v) => v.taskTypeId == e) < 0) {
+            const newDetail = JSON.parse(JSON.stringify(detailEmpty));
+            newDetail.taskTypeId = e;
+            newDetail.taskTypeName = taskType.name;
+            loopDetails.value.push(newDetail);
+          }
+        });
+        loopDetails.value = loopDetails.value.filter(
+          (v) => arg.findIndex((e) => e == v.taskTypeId) > -1
+        );
+
+        computedService()
+        break;
+      case "once":
+        arg.forEach((e) => {
+          const taskType = onceTasks.value.find((v) => v.id == e);
+          if (onceDetails.value.findIndex((v) => v.taskTypeId == e) < 0) {
+            const newDetail = JSON.parse(JSON.stringify(detailEmpty));
+            newDetail.taskTypeId = e;
+            newDetail.taskTypeName = taskType.name;
+            newDetail.payAddress = taskType.payAddress;
+            (newDetail.alterType = e === "6" ? "普通变更" : ""),
+              (newDetail.defaultProcesses = taskType.processes.map((v) => ({
+                taskTypeId: e,
+                taskTypeDetailId: v.id,
+                taskTypeDetailName: v.name,
+                fictionAddressId: null,
+                fictionAddress: "",
+                addressStyle: 0,
+                checked: false,
+                amount: undefined,
+              })));
+            newDetail.processes = [];
+            onceDetails.value.push(newDetail);
+          }
+        });
+        onceDetails.value = onceDetails.value.filter(
+          (v) => arg.findIndex((e) => e == v.taskTypeId) > -1
+        );
+
+        let provincesLength = provincesArr.value.length;
+
+        if (onceDetails.value.length > provincesLength) {
+          for (let i = 0; i < onceDetails.value.length - provincesLength; i++) {
+            provincesArr.value.push(provinces.value);
+            citiesArr.value.push(cities.value);
+            districtsArr.value.push(districts.value);
+          }
+        } else if (onceDetails.value.length < provincesLength) {
+          for (let i = 0; i < provincesLength - onceDetails.value.length; i++) {
+            provincesArr.value.length--;
+            citiesArr.value.length--;
+            districtsArr.value.length--;
+          }
+        }
+        break;
+      default:
+        break;
+    }
+  }
+
+  function inputChangeHandler(type, field, item, value, parent) {
+    console.log(111, type, field, item, value, parent);
+    let amount = 0;
+    switch (type) {
+      case "loop":
+        switch (field) {
+          case "price":
+            amount =
+              (item.serviceNum ? Number(item.serviceNum) : 0) *
+              (value ? Number(value) : 0) - (item.discountAmount ? Number(item.discountAmount) : 0);
+            item.amount = amount;
+            break;
+          case "serviceNum":
+            amount =
+              (item.price ? Number(item.price) : 0) * (value ? Number(value) : 0) - (item.discountAmount ? Number(item.discountAmount) : 0);
+            item.amount = amount;
+
+            break;
+          case "freeNum":
+            amount =
+              (item.price ? Number(item.price) : 0) *
+              (item.serviceNum ? Number(item.serviceNum) : 0) - (item.discountAmount ? Number(item.discountAmount) : 0);
+            item.amount = amount;
+            break;
+          case "discountAmount":
+            amount =
+              (item.price ? Number(item.price) : 0) *
+              (item.serviceNum ? Number(item.serviceNum) : 0) - (value ? Number(value) : 0);
+            item.amount = amount;
+        }
+        break;
+      case "once":
+        computedItem(item);
+        break;
+      case "process":
+        computedItem(parent);
+        break;
+      default:
+        break;
+    }
+    computedService();
+  }
+  function computedItem(parent) {
+    let amount = 0;
+    amount +=
+      parent.payAddress === 1 && parent.addressStyle === 2 && parent.addressAmount
+        ? Number(parent.addressAmount)
+        : 0;
+    amount +=
+      parent.taskTypeId === "6" &&
+        parent.alterType === "跨区变更" &&
+        parent.addressStyle === 2 &&
+        parent.addressAmount
+        ? Number(parent.addressAmount)
+        : 0;
+    parent.processes.forEach((l) => {
+      amount += l.amount ? Number(l.amount) : 0;
+    });
+    parent.amount = amount;
+  }
+
+  function computedService() {
+    //子表中的实际金额
+    let amount = 0;
+    let discountAmount = 0;
+    let trueAmount = 0;
+    switch (form.value.serviceType) {
+      case 1:
+        loopDetails.value.forEach((l) => {
+          amount += l.amount;
+          discountAmount += l.discountAmount;
+          trueAmount += l.trueAmount;
+        });
+        amount = amount >= 0 ? amount : 0;
+        discountAmount = discountAmount >= 0 ? discountAmount : 0;
+        break;
+      case 2:
+        onceDetails.value.forEach((l) => {
+          amount +=
+            l.payAddress === 1 && l.addressStyle === 2 && l.addressAmount
+              ? Number(l.addressAmount)
+              : 0;
+          if (l.alterType === "跨区变更" && l.addressStyle === 2 && l.addressAmount) {
+            amount += Number(l.addressAmount)
+          }
+          l.processes.forEach((v) => {
+            amount += v.amount ? Number(v.amount) : 0;
+          });
+        });
+        break;
+    }
+    form.value.discountAmount = discountAmount;
+    form.value.trueAmount = amount
+    form.value.amount = match.add(amount, discountAmount);
+  }
+
+  /** 输入框输出建议 */
+  function querySearchAsync(queryString, cb) {
+    const query = { keyword: queryString };
+    listUser(query).then((res) => {
+      cb(res.rows);
+    });
+  }
+
+  function querySearchCompanyAsync(queryString, cb) {
+    const query =
+      queryString.length > 0
+        ? {
+          keyword: queryString,
+          pageSize: 50,
+          pageNum: 1,
+          orderByColumn: "create_time",
+        }
+        : { pageSize: 50, pageNum: 1, orderByColumn: "create_time" };
+    listCompany(query).then((res) => {
+      cb(res.rows);
+    });
+  }
+  function handleSelectEmployee(item) {
+    form.value.signerName = item.nickName;
+    form.value.signerId = item.userId;
+  }
+
+  function handleSelectCompany(item) {
+    form.value.companyName = item.name;
+    form.value.companyId = item.id;
+    form.value.customerLabelId = item.customerLabelId
+  }
+  function handleClearCompany() {
+    form.value.customerLabelId = "";
+  }
+  function handleSelectProvince(item, index) {
+    const _provinceCode = item.provinceCode;
+    const _province = provincesArr.value[index].find((i) => {
+      return i.code === _provinceCode;
+    });
+
+    item.province = _province.name;
+    citiesArr.value[index] = proxy.region.getCities(_provinceCode);
+
+    if (citiesArr.value[index].length === 0) {
+      // 清空城市数据
+      item.cityCode = "";
+      item.city = "";
+      cities.value = [{ code: "", name: "全部" }];
+      // 清空行政区数据
+      item.districtCode = "";
+      item.district = "";
+
+      districts.value = [{ code: "", name: "全部" }];
+    } else {
+      citiesArr.value[index].unshift({ code: "", name: "全部" });
+      item.cityCode = citiesArr.value[index][0].code;
+      item.city = citiesArr.value[index][0].name;
+      handleSelectCity(item, index);
+    }
+  }
+
+  function handleSelectCity(item, index) {
+    const _cityCode = item.cityCode;
+    const _city = citiesArr.value[index].find((i) => {
+      return i.code === _cityCode;
+    });
+    item.city = _city.name;
+    districtsArr.value[index] = proxy.region.getDistricts(_cityCode);
+    if (districtsArr.value[index].length === 0) {
+      // 清空行政区数据
+      item.districtCode = "";
+      item.district = "";
+      districtsArr.value[index] = [{ code: "", name: "全部" }];
+    } else {
+      districtsArr.value[index].unshift({ code: "", name: "全部" });
+      item.districtCode = districtsArr.value[index][0].code;
+      item.district = districtsArr.value[index][0].name;
+    }
+  }
+
+  function handleSelectDistrict(item, index) {
+    const _districtCode = item.districtCode;
+    const _district = districtsArr.value[index].find((i) => {
+      return i.code === _districtCode;
+    });
+    item.district = _district.name;
+  }
+
+  function getProcess(item) {
+    const typeItem = onceTasks.value.find((i) => i.id === item.taskTypeId);
+    return typeItem.processes;
+  }
+
+  function checkedProcess(processId, item) {
+    const processes = item.processes;
+    return processes.findIndex((v) => v.taskTypeDetailId == processId) < 0;
+  }
+
+  function changeProcesses(item) {
+    computedItem(item);
+    computedService();
+  }
+
+  function parseDetail(details, form) {
+    loops.value = [];
+    onces.value = [];
+    loopDetails.value = [];
+    onceDetails.value = [];
+    switch (form.serviceType) {
+      case 1:
+        // 循环任务
+        details.forEach((i) => {
+          loops.value.push(i.taskTypeId);
+          loopDetails.value.push(i);
+        });
+        break;
+      case 2:
+        // 代办任务
+        details.forEach((i) => {
+          onces.value.push(i.taskTypeId);
+          const taskType = onceTasks.value.find((j) => j.id === i.taskTypeId);
+          onceDetails.value.push({
+            ...i,
+            defaultProcesses: parseProcess(i, taskType.processes),
+          });
+          onceDetails.value.forEach((j) => {
+            j.processes = j.defaultProcesses.filter((v) => v.checked);
+          });
+        });
+        break;
+      default:
+        break;
+    }
+  }
+
+  function parseProcess(item, processes) {
+    return processes.map((l) => {
+      // console.log(item.processes.find((i) => i.taskTypeDetailId === l.id));
+      if (item.processes.findIndex((i) => i.taskTypeDetailId === l.id) < 0) {
+        return {
+          taskTypeId: item.taskTypeId,
+          taskTypeDetailId: l.id,
+          taskTypeDetailName: l.name,
+          checked: false,
+          amount: undefined,
+        };
+      } else {
+        return {
+          ...item.processes.find((i) => i.taskTypeDetailId === l.id),
+          checked: true,
+        };
+      }
+    });
+  }
+
+  function verifyHandler() {
+    proxy.$modal
+      .confirm("是否确认审核?")
+      .then((_) => {
+
+        // form.value.details.forEach(item => {
+        //   item.timeVo = null
+        // })
+        verifyCheckOrder(form.value).then((res) => {
+          console.log(123, res);
+          if (res.data == null) {
+            verifyUpload(1);
+          } else {
+            verifyOpen.value = true;
+            redirectDetails.value = res.data;
+          }
+        });
+      })
+      .catch((_) => {
+        proxy.$modal.msg("取消审核");
+      });
+  }
+
+  function verifyFormClose() {
+    redirectDetails.value = [];
+    verifyForm.value = {};
+    verifyOpen.value = false;
+  }
+
+  function redirectVerify() {
+    redirectDetails.value.forEach((l) => {
+      const index = form.value.details.findIndex((v) => v.id === l.id);
+      form.value.details[index].redirect = l.redirect;
+    });
+    verifyUpload(1);
+    verifyFormClose();
+  }
+
+  function rejectHandler() {
+    rejectOpen.value = true;
+  }
+
+  function rejectCancel() {
+    rejectOpen.value = false;
+  }
+
+  function rejectSubmitHandler() {
+    if (form.value.verifyRemark === "" || form.value.verifyRemark == null) {
+      proxy.$modal.msgError("请填写驳回原因");
+      return;
+    }
+  }
+
+  function verifyUpload(status) {
+    const formValue = proxy.deepClone(form.value);
+    formValue.verifyStatus = status;
+    formValue.status = status;
+    verifyOrder(formValue).then((res) => {
+      getForm();
+      getList.value();
+      rejectCancel();
+      proxy.$modal.msgSuccess("保存成功");
+    });
+  }
+
+  /** 文件上传 */
+  function upload(param) {
+    const formData = new FormData();
+    formData.append("file", param.file);
+    uploadFile(formData).then((res) => {
+      if (res.code === 200) {
+        const file = {};
+        file.fileName = res.newFileName;
+        file.url = res.url;
+        file.originalFileName = res.originalFilename;
+        file.fileUrl = res.fileName;
+        form.value.files.push(file);
+      }
+    });
+  }
+
+  function handleDelFile(index) {
+    form.value.files.splice(index, 1);
+  }
+
+  function initRegion() {
+    console.log("initRegion开始", form.value);
+
+    for (let i = 0; i < form.value.details.length; i++) {
+      cities.value = proxy.region.getCities(form.value.details[i].provinceCode);
+      cities.value.unshift({ code: "", name: "全部" });
+      districts.value = proxy.region.getDistricts(form.value.details[i].cityCode);
+      districts.value.unshift({ code: "", name: "全部" });
+      console.log("市", cities.value);
+
+      provincesArr.value.push(provinces.value);
+      citiesArr.value.push(cities.value);
+      districtsArr.value.push(districts.value);
+    }
+  }
+
+  function showAddCompanyDialog() {
+    addCompanyDialogRef.value.open();
+  }
+
+  function contractTypeChangeHandler() {
+    if (form.value.contractType === 1) {
+      form.value.serviceType = 1;
+    }
+  }
+
+  function showHistoryList() {
+    historyChoiceRef.value.open(
+      form.value.fromId === "0" ? form.value.id : form.value.fromId
+    );
+  }
+
+  function historyChoiceHandle(row) {
+    open(row.id);
+  }
+  function workOrderIdUpdate(){
+      workOrderDialogRef.value.open()
+  }
+  /** 暴露给父组件的方法 */
+  defineExpose({
+    open,
+    openSimple,
+  });
+</script>
+<style scoped>
+  .my-autocomplete .el-input-group__append {
+    padding: 0 10px !important;
+  }
+</style>

+ 327 - 0
src/views/business/upgrade/order/importExcelDialog.vue

@@ -0,0 +1,327 @@
+<template>
+  <!-- 添加或修改菜单对话框 -->
+  <el-dialog
+    title="合同导入"
+    v-model="visible"
+    width="680px"
+    append-to-body
+    draggable
+    :close-on-click-modal = "false"
+  >
+    <el-form
+      ref="menuRef"
+      :model="form"
+      size="small"
+      :rules="rules"
+      label-width="100px"
+    >
+      <el-row>
+        <el-col :span="24">
+          <el-radio-group v-model="addType">
+            <el-radio-button :label="1">循环订单导入</el-radio-button>
+            <el-radio-button :label="2">单次订单导入</el-radio-button>
+          </el-radio-group>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="上传">
+            <el-upload
+              ref="uploadRef"
+              :limit="1"
+              accept=".xlsx, .xls"
+              :headers="addType === 1 ? uploadLoop.headers : uploadOnce.headers"
+              :action="
+                (addType === 1 ? uploadLoop.url : uploadOnce.url) +
+                '?updateSupport=' +
+                (addType === 1
+                  ? uploadLoop.updateSupport
+                  : uploadOnce.updateSupport)
+              "
+              :fileList="fileList"
+              :before-upload="handleBeforeUpload"
+              :disabled="
+                addType === 1 ? uploadLoop.isUploading : uploadOnce.isUploading
+              "
+              :on-progress="handleFileUploadProgress"
+              :on-success="handleFileSuccess"
+              :auto-upload="false"
+              drag
+            >
+              <el-icon class="el-icon--upload">
+                <upload-filled />
+              </el-icon>
+              <div class="el-upload__text">
+                将文件拖到此处,或<em>点击上传</em>
+              </div>
+              <template #tip>
+                <div class="el-upload__tip text-center">
+                  <!-- <div class="el-upload__tip">
+                    <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
+                  </div> -->
+                  <span
+                    >仅允许导入xls、xlsx格式文件。文件大小限制为&lt;50Mb</span
+                  >
+                  <el-link
+                    type="primary"
+                    :underline="false"
+                    style="font-size: 12px; vertical-align: baseline"
+                    @click="importTemplate"
+                    >下载模板</el-link
+                  >
+                </div>
+              </template>
+            </el-upload>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button
+          v-loading.fullscreen.lock="fullscreenLoading"
+          type="primary"
+          icon="Finished"
+          size="small"
+          @click="submitForm"
+          >确 定</el-button
+        >
+        <el-button icon="Clsoe" size="small" @click="cancel">取 消</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+
+<script setup>
+import { getToken, getTenant } from "@/utils/auth";
+import useUserStore from "@/store/modules/user";
+import { deepClone } from "@/utils";
+// import { incomeDefault, taxTypes, confirmDefault } from "@/utils/default"
+import {
+  exportLoopTemplate,
+  exportOnceTemplate,
+  importLoop,
+  importOnce,
+} from "@/api/upgrade/contract";
+const { proxy } = getCurrentInstance();
+/** 父组件传参 */
+const props = defineProps({
+  getList: {
+    type: Function,
+    default: () => {},
+  },
+});
+const { getList } = toRefs(props);
+/** 字典数组区 */
+/** 表单抽屉 页变量 */
+const fileList = ref([]);
+const visible = ref(false);
+const fullscreenLoading = ref(false);
+const addType = ref(1);
+const webHost = import.meta.env.VITE_APP_BASE_API;
+
+const setHeaders = {
+  Authorization: getToken(),
+};
+
+const data = reactive({
+  form: {},
+  followData: {},
+});
+const addComRef = ref(null);
+
+/*** 客户导入参数 */
+const uploadLoop = reactive({
+  // 是否禁用上传
+  isUploading: false,
+  // 设置上传的请求头部
+  headers: { Authorization: "Bearer " + getToken(), tenantId: getTenant() },
+  // 上传的地址
+  url: "/ezhizao-yzbh-crm/upgrade/crm/order/importLoop",
+});
+const uploadOnce = reactive({
+  // 是否禁用上传
+  isUploading: false,
+  // 设置上传的请求头部
+  headers: { Authorization: "Bearer " + getToken(), tenantId: getTenant() },
+  // 上传的地址
+  url: "/ezhizao-yzbh-crm/upgrade/crm/order/importOnce",
+});
+
+const contactorEmptyData = {
+  id: null,
+  name: "",
+  position: "",
+  gender: "男",
+  phone: "",
+  email: "",
+  isMain: "是",
+  remark: "",
+};
+
+const companyEmptyData = {
+  id: null,
+  code: "",
+  name: "",
+  oldName: "",
+  shortName: "",
+  ownerId: "",
+  ownerName: "",
+  sourceCategoryId: "",
+  sourceCategoryName: "",
+  sourceId: "",
+  sourceName: "",
+  stageId: "",
+  stageName: "",
+  phone: "",
+  email: "",
+  contactAddress: "",
+  remark: "",
+  socialCreditCode: "",
+  mainBusinessId: "",
+  mainBusinessName: "",
+  typeId: "",
+  typeName: "",
+  legalRepresentative: "",
+  foundationDate: "",
+  licenceDate: "",
+  businessStartDate: "",
+  collectionMethod: "",
+  businessEndDate: "",
+  isPermanentlyEffective: "",
+  registerMoney: "",
+  registerMoneyUnitId: "",
+  registerMoneyUnitName: "",
+  provinceCode: "",
+  province: "",
+  cityCode: "",
+  city: "",
+  districtCode: "",
+  district: "",
+  address: "",
+  businessField: "",
+  taxTypeId: "",
+  taxTypeName: "",
+  taxDeclarationCategoryId: "",
+  taxDeclarationCategoryName: "",
+  isZero: "",
+  taxDishId: "",
+  taxDishName: "",
+  competentTaxAuthority: "",
+  annualIncome: "",
+  taxType: "",
+  taxCollectorName: "",
+  taxCollectorPhone: "",
+  taxMonth: "",
+  openingBank: "",
+  bankAccount: "",
+  companyTags: [],
+  companyTagIds: [],
+  contactors: [],
+  serviceTeams: [],
+  companyFiles: [],
+  stores: [],
+  creatorId: useUserStore().user.id,
+};
+
+const followQuery = ref({});
+const { form, rules, followData } = toRefs(data);
+
+/***********************  表单页方法 ****************************/
+
+/** 抽屉打开 */
+function open() {
+  reset();
+  visible.value = true;
+}
+
+function reset() {
+  form.value = deepClone(companyEmptyData);
+  // console.log(addComRef.value)
+  if (addComRef.value != null) addComRef.value.reset();
+}
+
+function cancel() {
+  visible.value = false;
+}
+
+function submitForm() {
+  submitFileForm();
+}
+
+const importTemplate = () => {
+  if (addType.value === 1) {
+    // 循环
+    exportLoopTemplate();
+  } else if (addType.value === 2) {
+    // 单次
+    exportOnceTemplate();
+  }
+};
+
+function handleBeforeUpload(file) {
+  console.log(file);
+  if (
+    file.type !==
+      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" &&
+    file.type !== "application/vnd.ms-excel"
+  ) {
+    proxy.$modal.msgError("请选择excel文件");
+    return false;
+  }
+  return true;
+}
+
+/**文件上传中处理 */
+const handleFileUploadProgress = (event, file, fileList) => {
+  if (addType === 1) {
+    uploadLoop.isUploading = true;
+  } else {
+    uploadOnce.isUploading = true;
+  }
+};
+/** 文件上传成功处理 */
+const handleFileSuccess = (response, file, fileList) => {
+  if (addType === 1) {
+    uploadLoop.open = false;
+    uploadLoop.isUploading = false;
+    proxy.$refs["uploadRef"].handleRemove(file);
+    proxy.$alert(
+      "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+        response.msg +
+        "</div>",
+      "导入结果",
+      { dangerouslyUseHTMLString: true }
+    );
+    getList.value();
+  } else {
+    uploadOnce.open = false;
+    uploadOnce.isUploading = false;
+    proxy.$refs["uploadRef"].handleRemove(file);
+    proxy.$alert(
+      "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+        response.msg +
+        "</div>",
+      "导入结果",
+      { dangerouslyUseHTMLString: true }
+    );
+    getList.value();
+  }
+};
+/** 提交上传文件 */
+function submitFileForm() {
+  fullscreenLoading.value = true;
+  const promise = Promise.resolve(proxy.$refs["uploadRef"].submit());
+  promise.then((result) => {
+    fullscreenLoading.value = false;
+  }).catch((err) => {
+    fullscreenLoading.value = false;
+  })
+}
+
+// 暴露给父组件的方法
+defineExpose({
+  open,
+});
+</script>
+
+<style></style>

+ 490 - 0
src/views/business/upgrade/order/index.vue

@@ -0,0 +1,490 @@
+<template>
+  <div class="page-container list-container">
+    <!-- 功能按钮区 -->
+    <div class="list-btns-container">
+<!--      <el-button type="primary" size="small" icon="Plus" @click="handleAdd"-->
+<!--        v-hasPermi="['business:upgrade:order:add']">新增</el-button>-->
+
+      <!-- <el-button type="danger" size="small" icon="Delete" :disabled="multiple" @click="handleDelete"
+        v-hasPermi="['business:upgrade:order:remove']">删除</el-button> -->
+      <el-dropdown trigger="click">
+        <el-button type="primary" size="small">
+          其它<el-icon class="el-icon--right"><arrow-down /></el-icon>
+        </el-button>
+        <template #dropdown>
+          <el-dropdown-menu>
+<!--            <el-dropdown-item icon="Delete" :disabled="single" @click="handleAlter" v-if="viewAlter()">-->
+<!--              合同变更</el-dropdown-item>-->
+<!--            <el-dropdown-item icon="Delete" :disabled="single" @click="handleDissolution" v-if="viewDissolution()">-->
+<!--              合同解除</el-dropdown-item>-->
+<!--            <el-dropdown-item icon="Delete" :disabled="multiple" @click="handleDelete" v-if="viewDelete()">-->
+<!--              删除合同</el-dropdown-item>-->
+<!--            <el-dropdown-item icon="Delete" :disabled="multiple" @click="handleBinDelete" v-if="viewBinDelete()">-->
+<!--              放入回收站</el-dropdown-item>-->
+<!--            <el-dropdown-item icon="Download" @click="handleExport" v-if="viewExport()"-->
+<!--              v-hasPermi="['business:upgrade:order:export']">-->
+<!--              导出</el-dropdown-item>-->
+            <el-dropdown-item icon="Upload" @click="handleImport" v-hasPermi="['business:upgrade:order:export']"
+              v-if="viewExport()">导入</el-dropdown-item>
+            <!-- <el-dropdown-item type="warning" size="small" icon="Download" @click="handleArea"
+              v-hasPermi="['business:upgrade:order:export']"> area</el-dropdown-item> -->
+          </el-dropdown-menu>
+        </template>
+      </el-dropdown>
+      <!-- <el-button type="warning" size="small" icon="Download" @click="handleExport"
+        v-hasPermi="['business:upgrade:order:export']">导出</el-button> -->
+      <!--<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>-->
+    </div>
+    <!-- 搜索区 -->
+    <el-form class="list-search-container" :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
+      <el-form-item label="客户名称:" prop="companyName">
+        <el-input v-model="queryParams.companyName" size="small" placeholder="请输入客户名称" clearable style="width: 120px"
+                  @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="客户名称:" prop="companyName">
+        <el-input v-model="queryParams.companyName" size="small" placeholder="请输入客户名称" clearable style="width: 120px"
+          @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="合同编号:" prop="contractNo">
+        <el-input v-model="queryParams.contractNo" size="small" placeholder="请输入合同编号" clearable style="width: 120px"
+          @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="客户标签:">
+        <el-select v-model="queryParams.customerLabelId" size="small" style="width: 120px" multiple>
+          <el-option v-for="item in options" :key="item.id" :label="item.lable" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="甲方:">
+        <el-input v-model="queryParams.boss" size="small" placeholder="请输入甲方名称" clearable style="width: 120px"
+          @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="合同类型:" prop="contractType">
+        <el-select size="small" v-model="queryParams.contractType" placeholder="合同类型" clearable style="width: 120px">
+          <el-option v-for="item in contractTypes" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="服务类型:" prop="serviceType">
+        <el-select size="small" v-model="queryParams.serviceType" placeholder="服务类型" clearable style="width: 120px">
+          <el-option v-for="item in serviceTypes" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery" size="small">搜索</el-button>
+        <el-button icon="operation" @click="moreSearch = true" size="small">更多</el-button>
+        <el-button icon="Refresh" @click="resetQuery" size="small">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 列表区 -->
+    <el-table v-loading="loading" :data="orderList" size="small" border height="100%"
+      @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="客户名称" align="center" prop="companyName" min-width="250" />
+      <el-table-column label="税号" align="center" prop="socialCreditCode" min-width="200" />
+      <el-table-column label="合同编号" align="center" prop="contractNo" min-width="150" />
+      <el-table-column label="签约日期" align="center" prop="formDate" width="100">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.formDate, "{y}-{m}-{d}") }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="签约金额" header-align="center" align="right" prop="trueAmount" width="80">
+        <template #default="scope">{{
+          scope.row.trueAmount.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, "$&,")
+          }}</template>
+      </el-table-column>
+      <el-table-column label="签单人" align="center" prop="signerName" min-width="120" />
+      <el-table-column label="合同来源" align="center" prop="sourceCategoryName" min-width="120" />
+      <el-table-column label="客户标签" align="center" prop="customerLabelName" min-width="120" />
+
+      <el-table-column label="甲方" align="center" prop="boss" min-width="120" />
+      <el-table-column label="审核状态" align="center" prop="verifyStatus" width="110">
+        <template #default="scope">
+          <dict-tag :options="contract_verify_status" :value="scope.row.verifyStatus" />
+        </template>
+      </el-table-column>
+      <el-table-column label="合同类型" align="center" prop="contractType" width="80">
+        <template #default="scope">
+          {{ scope.row.contractType === 0 ? "新签" : "续签" }}
+        </template>
+      </el-table-column>
+      <el-table-column label="服务类型" align="center" prop="serviceType" width="80">
+        <template #default="scope">
+          {{ scope.row.serviceType === 1 ? "循环" : "代办" }}
+        </template>
+      </el-table-column>
+      <el-table-column label="合同状态" width="110" align="center" prop="status">
+        <template #default="scope">
+          <dict-tag :options="contract_status" :value="scope.row.status" />
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" fixed="right" align="center" width="130" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="handleUpdate(scope.row)"
+            v-hasPermi="['business:upgrade:order:edit']">查看</el-button>
+          <el-button link type="danger" size="small" @click="handleDelete(scope.row)"
+            v-hasPermi="['business:upgrade:order:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <contract-form ref="contractRef" :get-list="getList" />
+    <import-excel-dialog ref="importExcelDialogRef" :get-list="getList" />
+    <!-- 分页 -->
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize" @pagination="getList" />
+    <el-dialog title="更多搜索" v-model="moreSearch" width="720px" append-to-body size="small" draggable
+      :close-on-click-modal="false">
+      <el-form :model="queryParams" ref="queryRef" size="small" label-width="100">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="客户名称:" prop="companyName">
+              <el-input v-model="queryParams.companyName" placeholder="请输入客户名称" clearable style="width: 200px"
+                @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="服务类型:" prop="serviceType">
+              <el-select size="small" v-model="queryParams.serviceType" placeholder="合同类型" clearable
+                style="width: 100%">
+                <el-option v-for="item in serviceTypes" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="代理记账:" prop="isKeepAccount">
+              <el-select size="small" v-model="queryParams.isKeepAccount" placeholder="是否记账" clearable
+                style="width: 100%">
+                <el-option v-for="item in yesOrNo" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="公积金代缴:" prop="isHousingFund">
+              <el-select size="small" v-model="queryParams.isHousingFund" placeholder="是否代缴公积金" clearable
+                style="width: 100%">
+                <el-option v-for="item in yesOrNo" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="注册:" prop="isRegister">
+              <el-select size="small" v-model="queryParams.isRegister" placeholder="是否注册" clearable style="width: 100%">
+                <el-option v-for="item in yesOrNo" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="合同类型:" prop="contractType">
+              <el-select size="small" v-model="queryParams.contractType" placeholder="服务类型" clearable
+                style="width: 100%">
+                <el-option v-for="item in contractTypes" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="签约日期:" prop="formDate">
+              <el-date-picker v-model="queryParams.formDate" type="daterange" clearable format="YYYY - MM - DD "
+                value-format="YYYY-MM-DD" range-separator="至" start-placeholder="业务日期" end-placeholder="业务日期"
+                style="width: 100%;"></el-date-picker>
+            </el-form-item>
+            <el-form-item label="社保代缴:" prop="isSocialSecurity">
+              <el-select size="small" v-model="queryParams.isSocialSecurity" placeholder="是否代缴社保" clearable
+                style="width: 100%">
+                <el-option v-for="item in yesOrNo" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="返税申报:" prop="isReturnTax">
+              <el-select size="small" v-model="queryParams.isReturnTax" placeholder="是否申报返税" clearable
+                style="width: 100%">
+                <el-option v-for="item in yesOrNo" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="变更:" prop="isAlter">
+              <el-select size="small" v-model="queryParams.isAlter" placeholder="是否变更" clearable style="width: 100%">
+                <el-option v-for="item in yesOrNo" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" icon="Finished" size="small" @click="handleQuery">确 定</el-button>
+          <el-button icon="close" size="small" @click="moreSearch = false">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="Order">
+  import { dissolutionOrder } from "../../../../api/business/crm/contract";
+  import contractForm from "./form";
+  import useUserStore from "@/store/modules/user";
+  import {
+    listOrder,
+    delOrder,
+    delBinOrder,
+    exportOrder,
+  } from "@/api/upgrade/contract";
+  import { listLableNoPage } from "@/api/business/lable";
+  import importExcelDialog from "./importExcelDialog.vue";
+  import { yesOrNo } from "@/utils/default";
+  const { proxy } = getCurrentInstance();
+  /** 字典数组区 */
+  /** 查询 对象 */
+
+  const orderList = ref([]);
+  const loading = ref(true);
+  const ids = ref([]);
+  const single = ref(true);
+  const multiple = ref(true);
+  const total = ref(0);
+  const permissions = useUserStore().permissions;
+  const all_permission = "*:*:*";
+  const importExcelDialogRef = ref(null);
+  const moreSearch = ref(false);
+  const options = ref([]);
+  const contractTypes = ref([
+    {
+      label: "新签",
+      value: 0,
+    },
+    {
+      label: "续签",
+      value: 1,
+    },
+  ]);
+
+  const serviceTypes = ref([
+    {
+      label: "循环服务",
+      value: 1,
+    },
+    {
+      label: "单次服务",
+      value: 2,
+    },
+  ]);
+
+  const { contract_verify_status } = proxy.useDict("contract_verify_status");
+  const { contract_status } = proxy.useDict("contract_status");
+  /** 查询对象 */
+  const queryParams = ref({
+    pageNum: 1,
+    pageSize: 20,
+    fromId: 0,
+    orderByColumn: "create_time",
+    category: null,
+    code: null,
+    name: null,
+    shortName: null,
+    companyName: null,
+    oldName: null,
+    owner: null,
+    phone: null,
+    email: null,
+    contactAddress: null,
+    source: null,
+    type: null,
+    socialCreditCode: null,
+    mainBusiness: null,
+    legalRepresentative: null,
+    foundationDate: null,
+    licenceDate: null,
+    businessStartDate: null,
+    businessEndDate: null,
+    isPermanentlyEffective: null,
+    registerMoney: null,
+    registerMoneyUnit: null,
+    provinceCode: null,
+    province: null,
+    cityCode: null,
+    city: null,
+    districtCode: null,
+    district: null,
+    address: null,
+    businessField: null,
+    taxType: null,
+    isZero: null,
+    competentTaxAuthority: null,
+    taxCollectorName: null,
+    taxCollectorPhone: null,
+    taxMonth: null,
+    openingBank: null,
+    bankAccount: null,
+    annualIncome: null,
+    governmentAccountNo: null,
+    governmentPassword: null,
+    socialSecurityAccountNo: null,
+    socialSecurityPassword: null,
+    employeePassword: null,
+    housingFundPassword: null,
+    housingFundUnitAccount: null,
+    housingFundDeductionPassword: null,
+    collectionMethod: null,
+    quotaAmount: null,
+    isPayOnWindow: null,
+    isFirstSocialSecurity: null,
+    isFirstHousingFund: null,
+    customerLabelId: [],
+    boss: null
+  });
+  onActivated(() => {
+    // 你的逻辑
+    getList();
+  });
+  /***********************  方法区  ****************************/
+
+  /** 查询company列表 */
+  function getList() {
+    loading.value = true;
+    listOrder(queryParams.value).then((response) => {
+      orderList.value = response.rows;
+      total.value = response.total;
+      loading.value = false;
+    });
+  }
+
+  function viewAlter() {
+    return (
+      permissions.includes(all_permission) ||
+      permissions.includes("business:upgrade:order:alter")
+    );
+  }
+
+  function viewDissolution() {
+    return (
+      permissions.includes(all_permission) ||
+      permissions.includes("business:upgrade:order:dissolution")
+    );
+  }
+  function getOption() {
+    listLableNoPage().then(res => {
+      options.value = res.data
+    })
+  }
+  function viewDelete() {
+    return (
+      permissions.includes(all_permission) ||
+      permissions.includes("business:upgrade:order:remove")
+    );
+  }
+
+  function viewBinDelete() {
+    return (
+      permissions.includes(all_permission) ||
+      permissions.includes("business:upgrade:order:bin")
+    );
+  }
+  function viewExport() {
+    return (
+      permissions.includes(all_permission) ||
+      permissions.includes("business:upgrade:order:export")
+    );
+  }
+
+  /** 搜索按钮操作 */
+  function handleQuery() {
+    queryParams.value.pageNum = 1;
+    getList();
+  }
+
+  /** 重置按钮操作 */
+  function resetQuery() {
+    proxy.resetForm("queryRef");
+    queryParams.value.customerLabelId = [];
+    queryParams.value.formDate = [];
+    queryParams.value.boss = null
+    handleQuery();
+  }
+
+  // 多选框选中数据
+  function handleSelectionChange(selection) {
+    ids.value = selection.map((item) => item.id);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
+  }
+
+  /** 新增按钮操作 */
+  function handleAdd() {
+    proxy.$refs.contractRef.open();
+  }
+
+  /** 修改按钮操作 */
+  function handleUpdate(row) {
+    const id = row.id || ids.value;
+    proxy.$refs.contractRef.open(id);
+  }
+
+  /** 删除按钮操作 */
+  function handleDelete(row) {
+    const _ids = row.id || ids.value;
+    proxy.$modal
+      .confirm("是否确认删除选中的数据项?")
+      .then(function () {
+        return delOrder(_ids);
+      })
+      .then(() => {
+        getList();
+        proxy.$modal.msgSuccess("删除成功!");
+      })
+      .catch(() => { });
+  }
+
+  /** 放入回收站按钮操作 */
+  function handleBinDelete(row) {
+    const _ids = row.id || ids.value;
+    proxy.$modal
+      .confirm("是否确认选中的数据项放入回收站?")
+      .then(function () {
+        return delBinOrder(_ids);
+      })
+      .then(() => {
+        getList();
+        proxy.$modal.msgSuccess("数据已放入回收站!");
+      })
+      .catch(() => { });
+  }
+
+  function handleAlter() {
+    const id = ids.value;
+    const row = orderList.value.find((item) => item.id === ids.value[0]);
+    if (row.verifyStatus == 0) {
+      proxy.$modal.msgError("未审核合同无法变更!");
+      return;
+    }
+    if (row.status == 9) {
+      proxy.$modal.msgError("已解除合同无法变更!");
+      return;
+    }
+    proxy.$refs.contractRef.openSimple(id, "alterOrder");
+  }
+
+  function handleDissolution() {
+    const row = orderList.value.find((item) => item.id === ids.value[0]);
+    console.log(row);
+    if (row.verifyStatus == 0) {
+      proxy.$modal.msgError("未审核合同无法解除!");
+      return;
+    }
+    proxy.$modal
+      .confirm("是否确认解除合同?")
+      .then(function () {
+        return dissolutionOrder(row);
+      })
+      .then(() => {
+        getList();
+        proxy.$modal.msgSuccess("解除成功!");
+      });
+    // .catch(() => {});
+  }
+
+  /** 导出按钮操作 */
+  function handleExport() {
+    // proxy.download(
+    //   "business/archive/order/export",
+    //   {
+    //     ...queryParams.value,
+    //   },
+    //   `合同导出_${new Date().getTime()}.xlsx`
+    // );
+    exportOrder(queryParams.value);
+  }
+
+  function handleImport() {
+    importExcelDialogRef.value.open();
+  }
+
+  getList();
+  getOption();
+</script>

+ 356 - 0
src/views/business/upgrade/workorder/index.vue

@@ -0,0 +1,356 @@
+<template>
+  <div class="page-container list-container">
+    <!-- 功能按钮区 -->
+    <div class="list-btns-container">
+        <el-button type="primary" size="small" icon="Download" @click="handleExport" v-if="viewAdviser('business:upgrade:workOrder:export')">
+          导出
+        </el-button>
+    </div>
+    <!-- 搜索区 -->
+    <el-form class="list-search-container" size="small" :model="queryParams" ref="queryRef" :inline="true"
+      label-width="68px">
+      <el-form-item label="客户名称:" prop="companyName">
+        <el-input v-model="queryParams.companyName" style="width: 150px" placeholder="请输入客户名称" clearable
+          @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="工单类型:" prop="type">
+        <el-select size="small" v-model="queryParams.type" placeholder="工单类型" clearable>
+          <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 列表区 -->
+    <el-table v-loading="loading" :data="orderList" size="small" border height="100%"
+      @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="工单编号" align="center" min-width="250" prop="id" :resizable="false" />
+      <el-table-column label="客户名称" align="center" min-width="250" prop="companyName" :resizable="false" />
+      <el-table-column label="税号" align="center" min-width="200" prop="socialCreditCode" :resizable="false" />
+      <el-table-column label="工单类型" align="center" prop="amount" min-width="80" :resizable="false">
+        <template #default="scope">
+          {{ scope.row.type === 1 ? "循环工单" : "代办工单" }}
+        </template>
+      </el-table-column>
+      <el-table-column label="项目" align="center" prop="taskTypeName" :resizable="false" min-width="110">
+        <template #default="scope">
+          {{ scope.row.taskTypeName }}
+          {{
+          scope.row.taskTypeDetailName
+          ? `-${scope.row.taskTypeDetailName}`
+          : ""
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="是否延续" align="center" prop="isContinue" :resizable="false">
+        <template #default="scope">
+          {{ scope.row.isContinue === 0 ? "否" : "是" }}
+        </template>
+      </el-table-column>
+      <el-table-column label="合同状态" align="center" width="150" prop="socialCreditCode" :resizable="false">
+        <template #default="scope">
+          <span v-if="scope.row.type === 1">{{ scope.row.closingMonth }}</span>
+          <span v-else>{{ scope.row.onceContractStatus }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="起始月" align="center" min-width="120" prop="startMonth" :resizable="false">
+        <template #default="scope">
+          <div v-if="scope.row.type === 1">
+            <div v-if="scope.row.editStatus.startMonth" style="
+                display: flex;
+                flex-direction: row;
+                justify-content: center;
+              ">
+              <el-date-picker v-model="scope.row.startMonth" size="small" placeholder="起始月" :clearable="true"
+                value-format="YYYY-MM-DD" format="YYYY年MM月" type="month"
+                @change="(arg) => startDateChangeHandler(scope.row, arg)" />
+              <el-button link type="primary" icon="Check" size="small" style="padding: 0"
+                @click="saveHandler(scope.row, 'startMonth')" />
+            </div>
+            <div v-else style="
+                display: flex;
+                flex-direction: row;
+                justify-content: center;
+              ">
+              <div style="width: auto">
+                {{
+                scope.row.startMonth
+                ? moment(scope.row.startMonth).format("YYYY年MM月")
+                : ""
+                }}
+              </div>
+              <el-button v-show="
+                  scope.row.isStop === 0 && scope.row.records.length === 0  && scope.row.isNew === 1
+                " link type="primary" icon="Edit" size="small" style="padding: 0"
+                v-hasPermi="['business:upgrade:workOrder:edit']" @click="
+                  () => {
+                    scope.row.editStatus.startMonth =
+                      !scope.row.editStatus.startMonth;
+                  }
+                " />
+            </div>
+          </div>
+          <div v-else>-</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="结束月" align="center" min-width="90" :resizable="false">
+        <template #default="scope">
+          <div v-if="scope.row.monthNum > 0">
+            {{
+            scope.row.type === 1
+            ? scope.row.endMonth
+            ? moment(scope.row.endMonth).format("YYYY年MM月")
+            : ""
+            : "-"
+            }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="工单月数" align="center" :resizable="false" width="80" prop="monthNum">
+        <template #default="scope">
+          {{ scope.row.type === 1 ? scope.row.monthNum : "-" }}
+        </template>
+      </el-table-column>
+      <el-table-column label="工单执行人" align="center" :resizable="false" min-width="100">
+        <template #default="scope">{{ getTransactor(scope.row) }}</template>
+      </el-table-column>
+    </el-table>
+    <!-- <contract-form ref="contractRef" :get-list="getList" /> -->
+    <!-- 分页 -->
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize" @pagination="getList" />
+    <ZeroChangeDialog ref="zeroChangeDialogRef" :save-call-back="thenSave" />
+    <el-dialog title="延续设置" v-model="continueOpen" width="500px" append-to-body draggable @close="close"
+      :close-on-click-modal="false">
+      <div style="padding: 8px 24px 16px 24px">
+        <el-form size="small" label-width="100px">
+          <el-form-item label="是否延续">
+            <el-select v-model="cont" placeholder="请选择" style="width: 100%">
+              <el-option v-for="item in yesOrNo" :key="item.label" :label="item.label" :value="item.value" />
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="form-btns-container" style="height: 40px">
+        <el-button size="small" style="float: right" @click="close" icon="close">
+          取消</el-button>
+        <el-button type="primary" icon="Finished" size="small"
+          style="float: right; margin-left: 12px; margin-right: 12px" @click="handleSave">保存</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="ContractWorkOrder">
+  import {
+    listWorkOrder,
+    delWorkOrder,
+    exportWorkOrder,
+    updateWorkOrder,
+    setContract,
+  } from "@/api/upgrade/workOrder";
+  import useUserStore from "@/store/modules/user";
+  import { yesOrNo } from "@/utils/default";
+  import { get } from "@vueuse/core";
+  import { ref } from "vue";
+  import ZeroChangeDialog from "../ZeroChangeDialog";
+  const { proxy } = getCurrentInstance();
+  /** 字典数组区 */
+  /** 查询 对象 */
+
+  const orderList = ref([]);
+  const permissions = useUserStore().permissions;
+  const all_permission = "*:*:*";
+  const continueOpen = ref(false);
+  const loading = ref(true);
+  const ids = ref([]);
+  const single = ref(true);
+  const cont = ref(1);
+  const setContinue = ref(true);
+  const multiple = ref(true);
+  const total = ref(0);
+  const prev = ref([]);
+  const zeroChangeDialogRef = ref(null);
+
+  const { contract_verify_status } = proxy.useDict("contract_verify_status");
+  const { contract_status } = proxy.useDict("contract_status");
+  /** 查询对象 */
+  const queryParams = ref({
+    pageNum: 1,
+    pageSize: 20,
+    companyName: "",
+    orderByColumn: "create_time",
+    noContract: 0,
+  });
+
+  const types = ref([
+    {
+      value: 1,
+      label: "循环工单",
+    },
+    {
+      value: 2,
+      label: "代办工单",
+    },
+  ]);
+
+  const editStatus = {
+    startMonth: false,
+  };
+
+  /***********************  方法区  ****************************/
+  onActivated(() => {
+    // 你的逻辑
+    getList();
+  });
+  /** 查询company列表 */
+  function getList() {
+    loading.value = true;
+    listWorkOrder(queryParams.value).then((response) => {
+      orderList.value = response.rows.map((l) => ({
+        ...l,
+        editStatus: proxy.deepClone(editStatus),
+      }));
+      prev.value = proxy.deepClone(response.rows);
+      total.value = response.total;
+      loading.value = false;
+      console.log("查询", orderList);
+    });
+  }
+
+  /** 搜索按钮操作 */
+  function handleSetContinue() {
+    if (ids.value.length < 1) {
+      proxy.$modal.msgError("至少选择一条数据");
+    } else {
+      if (setContinue) {
+        proxy.$modal.msgError("只能修改循环工单");
+      } else {
+        continueOpen.value = true;
+      }
+    }
+  }
+
+  /** 延续设置保存操作 */
+  function handleSave() {
+    setContract(ids.value, cont.value).then((response) => {
+      proxy.$modal.msgSuccess("保存成功");
+      continueOpen.value = false;
+      getList();
+    });
+  }
+
+  //判断是否有权限
+  function viewAdviser(quer) {
+    return permissions.includes(all_permission) || permissions.includes(quer);
+  }
+
+  /** 搜索按钮操作 */
+  function handleQuery() {
+    queryParams.value.pageNum = 1;
+    getList();
+  }
+
+  /** 重置按钮操作 */
+  function resetQuery() {
+    proxy.resetForm("queryRef");
+    handleQuery();
+  }
+
+  function close() {
+    continueOpen.value = false;
+    cont.value = 1;
+  }
+
+  // 多选框选中数据
+  function handleSelectionChange(selection) {
+    ids.value = selection.map((item) => item.id);
+    setContinue.value = selection.map((item) => item.type === 2);
+  }
+
+  /** 新增按钮操作 */
+  function handleAdd() {
+    proxy.$refs.contractRef.open();
+  }
+
+  /** 修改按钮操作 */
+  function handleUpdate(row) {
+    const id = row.id || ids.value;
+    proxy.$refs.contractRef.open(id);
+  }
+
+  /** 删除按钮操作 */
+  function handleDelete(row) {
+    const _ids = row.id || ids.value;
+    proxy.$modal
+      .confirm("是否确认删除选中的数据项?")
+      .then(function () {
+        return delWorkOrder(_ids);
+      })
+      .then(() => {
+        getList();
+        proxy.$modal.msgSuccess("删除成功!");
+      })
+      .catch(() => { });
+  }
+
+  /** 导出按钮操作 */
+  function handleExport() {
+    exportWorkOrder(queryParams.value);
+  }
+
+  function startDateChangeHandler(row, startDate) {
+    if (startDate) {
+      row.endMonth = proxy
+        .moment(startDate)
+        .add(row.monthNum - 1, "M")
+        .format("YYYY-MM-DD");
+    } else row.endMonth = null;
+    console.log(row);
+  }
+
+  function saveHandler(row, field) {
+    const index = prev.value.findIndex((l) => l.id === row.id);
+    if (prev.value[index][field] === row[field]) {
+      row.editStatus[field] = !row.editStatus[field];
+    } else {
+      if (row.isZero == null) {
+        zeroChangeDialogRef.value.open(row.companyId, row);
+      } else {
+        proxy.$modal
+          .confirm("确定修改起始月么?")
+          .then((_) => {
+            updateWorkOrder(row).then((res) => {
+              getList();
+            });
+          })
+          .catch((_) => { });
+      }
+    }
+  }
+
+  function thenSave(row) {
+    proxy.$modal
+      .confirm("确定修改起始月么?")
+      .then((_) => {
+        updateWorkOrder(row).then((res) => {
+          getList();
+        });
+      })
+      .catch((_) => { });
+  }
+
+  function getTransactor(row) {
+    if (row.entrusts != null && row.entrusts.length > 0) {
+      const names = Array.from(new Set(row.entrusts.map((v) => v.toAccountName)));
+      return names.join(",");
+    } else {
+      return row.serviceName;
+    }
+  }
+  getList();
+</script>