Explorar o código

Merge branch 'master' of http://36.137.93.232:3000/hf/byte-sailing-new

lxf %!s(int64=2) %!d(string=hai) anos
pai
achega
7f1e7a8528
Modificáronse 41 ficheiros con 8962 adicións e 215 borrados
  1. 227 0
      src/components/WDLY/process/ReturnGood.vue
  2. 498 0
      src/components/WDLY/process/SendFunds.vue
  3. 447 0
      src/components/WDLY/process/SendPurchase.vue
  4. 252 0
      src/components/WDLY/process/SendSubscribe.vue
  5. 1 2
      src/components/byForm/index.vue
  6. 10 5
      src/components/byTable/index.vue
  7. 1 0
      src/components/process/SendPurchase.vue
  8. 3 1
      src/main.js
  9. 11 0
      src/store/modules/mail.js
  10. 46 0
      src/utils/util.js
  11. 10 10
      src/views/WDLY/basic/product/index.vue
  12. 623 0
      src/views/WDLY/basic/supplier/index.vue
  13. 98 26
      src/views/WDLY/outInBound/abnormal/index.vue
  14. 297 0
      src/views/WDLY/outInBound/waitInBound/index.vue
  15. 286 0
      src/views/WDLY/process/porcessDefinition/index.vue
  16. 346 0
      src/views/WDLY/process/processApproval/index.vue
  17. 22 0
      src/views/WDLY/process/processConfig/Sidebar.vue
  18. 325 0
      src/views/WDLY/process/processConfig/index.vue
  19. 39 0
      src/views/WDLY/process/processConfig/processChart.vue
  20. 436 0
      src/views/WDLY/process/processConfig/vueFlow.vue
  21. 107 0
      src/views/WDLY/process/processConfig/vueFlow2.vue
  22. 497 0
      src/views/WDLY/purchaseManage/alreadyPurchase/index.vue
  23. 478 0
      src/views/WDLY/purchaseManage/arrival/index.vue
  24. 503 0
      src/views/WDLY/purchaseManage/purchase/index.vue
  25. 479 0
      src/views/WDLY/purchaseManage/returnGoods/index.vue
  26. 521 0
      src/views/WDLY/purchaseManage/subscribe/index.vue
  27. 288 0
      src/views/WDLY/stockManage/query/index.vue
  28. 167 0
      src/views/connect/E-mail/mail/com/left.vue
  29. 149 0
      src/views/connect/E-mail/mail/com/mailDetail.vue
  30. 121 0
      src/views/connect/E-mail/mail/com/mailList.vue
  31. 78 0
      src/views/connect/E-mail/mail/com/mailWrite.vue
  32. 120 0
      src/views/connect/E-mail/mail/com/main.vue
  33. 34 0
      src/views/connect/E-mail/mail/index.vue
  34. 509 0
      src/views/finance/fundManage/accountPayment/index.vue
  35. 355 0
      src/views/process/flowExample/index.vue
  36. 38 121
      src/views/process/processApproval/index.vue
  37. 2 1
      src/views/process/processConfig/index.vue
  38. 18 4
      src/views/process/processConfig/processChart.vue
  39. 474 14
      src/views/process/processConfig/vueFlow.vue
  40. 13 4
      src/views/purchaseManage/purchaseManage/purchase/index.vue
  41. 33 27
      src/views/purchaseManage/purchaseManage/subscribe/index.vue

+ 227 - 0
src/components/WDLY/process/ReturnGood.vue

@@ -0,0 +1,227 @@
+<template>
+  <div style="width: 100%; padding: 0px 15px">
+    <byForm
+      :formConfig="formConfig"
+      :formOption="formOption"
+      v-model="formData.data"
+      :rules="rules"
+      ref="formDom"
+    >
+      <template #details>
+        <div style="width: 100%">
+          <el-button
+            type="primary"
+            @click="openProduct = true"
+            style="margin-bottom: 10px"
+          >
+            添加物品
+          </el-button>
+          <el-table :data="formData.data.salesReturnDetailList">
+            <el-table-column prop="productCode" label="货品编码" />
+            <el-table-column prop="productName" label="货品名称" />
+            <el-table-column prop="productSpec" label="规格型号" />
+            <el-table-column prop="productUnit" label="单位" />
+            <el-table-column prop="count" label="退货数量" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'salesReturnDetailList.' + $index + '.count'"
+                  :rules="rules.count"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.count"
+                    :precision="4"
+                    :controls="false"
+                    :min="0"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column prop="remark" label="退货原因" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'salesReturnDetailList.' + $index + '.remark'"
+                  :rules="rules.remark"
+                  :inline-message="true"
+                >
+                  <el-input v-model="row.remark" placeholder="请输入" />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column prop="zip" label="操作" width="100">
+              <template #default="{ $index }">
+                <el-button type="primary" link @click="handleRemove($index)"
+                  >删除</el-button
+                >
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+    </byForm>
+    <el-dialog
+      v-model="openProduct"
+      title="选择货品"
+      width="70%"
+      append-to-body
+    >
+      <SelectGoods
+        @cancel="openProduct = false"
+        @pushGoods="pushGoods"
+      ></SelectGoods>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import byForm from "@/components/byForm/index";
+import { ElMessage, ElMessageBox } from "element-plus";
+import SelectGoods from "@/components/product/SelectGoods";
+import useUserStore from "@/store/modules/user";
+const { proxy } = getCurrentInstance();
+
+let formData = reactive({
+  data: {
+    supplyId: "",
+    salesReturnDetailList: [],
+    returnName: "",
+  },
+});
+let rules = ref({
+  supplyId: [{ required: true, message: "请选择供应商", trigger: "change" }],
+  count: [{ required: true, message: "请输入退货数量", trigger: "blur" }],
+  remark: [{ required: true, message: "请输入退货原因", trigger: "blur" }],
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "returnDept",
+      label: "申请部门",
+      itemWidth: 25,
+      disabled: true,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "input",
+      prop: "returnName",
+      label: "申请人",
+      itemWidth: 25,
+      disabled: true,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "date",
+      prop: "purchaseTime",
+      label: "申请时间",
+      itemWidth: 25,
+      disabled: true,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "select",
+      prop: "supplyId",
+      label: "供应商",
+      isLoad: {
+        url: "/supplierInfo/page",
+        req: {
+          pageNum: 1,
+          pageSize: 9999,
+        },
+        labelKey: "name",
+        labelVal: "id",
+        method: "post",
+        resUrl: "rows",
+      },
+    },
+    {
+      type: "slot",
+      slotName: "details",
+      label: "退货明细",
+    },
+  ];
+});
+const formDom = ref(null);
+const handleSubmit = async () => {
+  const vaild = await formDom.value.handleSubmit(() => {}); //拿到内部表单是否验证通过
+  if (vaild) {
+    if (formData.data.salesReturnDetailList.length > 0) {
+      const list = formData.data.salesReturnDetailList;
+      for (let i = 0; i < list.length; i++) {
+        const e = list[i];
+        if (e.count == 0) {
+          ElMessage({
+            message: "退货数量不能为0!",
+            type: "info",
+          });
+          return false;
+        }
+      }
+      return true;
+    }
+    ElMessage({
+      message: "请添加退货明细!",
+      type: "info",
+    });
+    return false;
+  }
+};
+let openProduct = ref(false);
+const handleRemove = (index) => {
+  formData.data.salesReturnDetailList.splice(index, 1);
+  return ElMessage({
+    message: "删除成功!",
+    type: "success",
+  });
+};
+const pushGoods = (goods) => {
+  const arr = goods.map((x) => ({
+    goodType: x.goodType,
+    productCode: x.code,
+    productName: x.name,
+    productSpec: x.spec,
+    productUnit: x.unit,
+    count: 0,
+    bussinessId: x.id,
+    remark: "",
+  }));
+  formData.data.salesReturnDetailList =
+    formData.data.salesReturnDetailList.concat(arr);
+  return ElMessage({
+    message: "添加成功!",
+    type: "success",
+  });
+};
+
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+
+// 获取用户信息并赋默认值
+const userInfo = useUserStore().user;
+onMounted(() => {
+  formData.data.purchaseTime = proxy.parseTime(new Date());
+  formData.data.returnDept = userInfo.dept.deptName;
+  formData.data.returnName = userInfo.nickName;
+});
+// 向父组件暴露
+defineExpose({
+  submitData: formData.data,
+  handleSubmit,
+});
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 498 - 0
src/components/WDLY/process/SendFunds.vue

@@ -0,0 +1,498 @@
+<template>
+  <div style="width: 100%; padding: 0px 15px">
+    <el-form
+      :model="formData.data"
+      :rules="rules"
+      ref="formDom"
+      label-position="top"
+    >
+      <div class="_t">基础信息</div>
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="归属公司" prop="corporationId">
+            <el-select
+              v-model="formData.data.corporationId"
+              placeholder="请选择"
+              filterable
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in companyData"
+                :label="item.name"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="归属部门" prop="departmentId">
+            <el-cascader
+              v-model="formData.data.departmentId"
+              :options="deptTreeData"
+              :props="{
+                value: 'deptId',
+              }"
+              clearable
+              filterable
+              style="width: 100%"
+              @change="handleChangeDept"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="请款类型" prop="type">
+            <el-select
+              v-model="formData.data.type"
+              placeholder="请选择"
+              filterable
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in fundsType"
+                :label="item.dictValue"
+                :value="item.dictKey"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="币种" prop="currency">
+            <el-select
+              v-model="formData.data.currency"
+              placeholder="请选择"
+              filterable
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in currencyType"
+                :label="item.dictValue"
+                :value="item.dictKey"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="6">
+          <el-form-item label="用款时间" prop="paymentTime">
+            <el-date-picker
+              v-model="formData.data.paymentTime"
+              type="datetime"
+              placeholder="请选择"
+              value-format="YYYY-MM-DD HH:mm:ss"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-form-item label="用款说明" prop="paymentRemarks">
+        <el-input
+          v-model="formData.data.paymentRemarks"
+          placeholder="请输入"
+          type="textarea"
+        >
+        </el-input>
+      </el-form-item>
+      <el-form-item label="上传附件">
+        <el-upload
+          v-model="fileList"
+          :show-file-list="false"
+          class="upload-demo"
+          action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+          :data="uploadData"
+          :on-preview="handlePreview"
+          :before-upload="handleBeforeUpload"
+        >
+          <el-button type="primary">选择</el-button>
+        </el-upload>
+      </el-form-item>
+      <div style="margin-bottom: 15px">
+        <el-tag
+          style="margin-right: 10px"
+          class="ml-2"
+          type="info"
+          v-for="(item, index) in fileList"
+          :key="index"
+          closable
+          @close="handleClose(index)"
+          >{{ item.fileName }}</el-tag
+        >
+      </div>
+      <div class="_t">请款明细</div>
+      <el-form-item>
+        <el-button type="primary" @click="handleAddRow" style="margin: 10px 0">
+          添加行
+        </el-button>
+        <el-table :data="formData.data.accountRequestFundsDetailList">
+          <el-table-column prop="count" label="费用类型" min-width="150">
+            <template #default="{ row, $index }">
+              <el-form-item
+                :prop="'accountRequestFundsDetailList.' + $index + '.costType'"
+                :rules="rules.costType"
+                :inline-message="true"
+              >
+                <el-select
+                  v-model="row.costType"
+                  placeholder="请选择"
+                  filterable
+                  style="width: 100%"
+                >
+                  <el-option
+                    v-for="item in fundsCostType"
+                    :label="item.dictValue"
+                    :value="item.dictKey"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </template>
+          </el-table-column>
+          <el-table-column prop="count" label="款项说明" min-width="150">
+            <template #default="{ row, $index }">
+              <el-form-item
+                :prop="'accountRequestFundsDetailList.' + $index + '.remarks'"
+                :rules="rules.remarks"
+                :inline-message="true"
+              >
+                <el-input
+                  v-model="row.remarks"
+                  placeholder="请输入"
+                  type="textarea"
+                />
+              </el-form-item>
+            </template>
+          </el-table-column>
+          <el-table-column prop="amount" label="请款金额" min-width="150">
+            <template #default="{ row, $index }">
+              <el-form-item
+                :prop="'accountRequestFundsDetailList.' + $index + '.amount'"
+                :rules="rules.amount"
+                :inline-message="true"
+              >
+                <el-input-number
+                  v-model="row.amount"
+                  :precision="4"
+                  :controls="false"
+                  :min="0"
+                  @change="handleChangeAmount"
+                />
+              </el-form-item>
+            </template>
+          </el-table-column>
+
+          <el-table-column prop="zip" label="操作" width="100">
+            <template #default="{ $index }">
+              <el-button type="primary" link @click="handleRemove($index)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="请款总额" prop="total">
+            <el-input
+              v-model="formData.data.total"
+              placeholder="请输入"
+              disabled
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="单据数量" prop="quantity">
+            <el-input v-model="formData.data.quantity" placeholder="请输入" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <div class="_t">收付款信息</div>
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="付款方式" prop="paymentMethod">
+            <el-select
+              v-model="formData.data.paymentMethod"
+              placeholder="请选择"
+              filterable
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in fundsPaymentMethod"
+                :label="item.dictValue"
+                :value="item.dictKey"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="付款账户" prop="accountManagementId">
+            <el-select
+              v-model="formData.data.accountManagementId"
+              placeholder="请选择"
+              filterable
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in accountData"
+                :label="item.alias"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="户名" prop="name">
+            <el-input v-model="formData.data.name" placeholder="请输入" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="银行账号" prop="accountOpening">
+            <el-input
+              v-model="formData.data.accountOpening"
+              placeholder="请输入"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="开户银行" prop="openingBank">
+            <el-input
+              v-model="formData.data.openingBank"
+              placeholder="请输入"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="联行号" prop="interbankNumber">
+            <el-input
+              v-model="formData.data.interbankNumber"
+              placeholder="请输入"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import useUserStore from "@/store/modules/user";
+
+const { proxy } = getCurrentInstance();
+
+let formData = reactive({
+  data: {
+    paymentTime: "",
+    accountRequestFundsDetailList: [],
+  },
+});
+let rules = ref({
+  corporationId: [
+    { required: true, message: "请选择归属公司", trigger: "change" },
+  ],
+  departmentId: [
+    { required: true, message: "请选择归属部门", trigger: "change" },
+  ],
+  type: [{ required: true, message: "请选择请款类型", trigger: "change" }],
+  paymentTime: [
+    { required: true, message: "请选择用款时间", trigger: "change" },
+  ],
+  currency: [{ required: true, message: "请选择币种", trigger: "change" }],
+  paymentMethod: [
+    { required: true, message: "请选择付款方式", trigger: "change" },
+  ],
+  accountManagementId: [
+    { required: true, message: "请选择付款账号", trigger: "change" },
+  ],
+  costType: [{ required: true, message: "请选择费用类型", trigger: "change" }],
+  remarks: [{ required: true, message: "请输入款项说明", trigger: "blur" }],
+  amount: [{ required: true, message: "请输入请款金额", trigger: "blur" }],
+});
+
+const handleAddRow = () => {
+  formData.data.accountRequestFundsDetailList.push({
+    costType: "",
+    remarks: "",
+    amount: 0,
+  });
+};
+
+const handleRemove = (index) => {
+  formData.data.accountRequestFundsDetailList.splice(index, 1);
+  handleChangeAmount();
+};
+
+// 提交方法
+const formDom = ref(null);
+const handleSubmit = async () => {
+  const vaild = await formDom.value.validate();
+  if (vaild) {
+    if (formData.data.accountRequestFundsDetailList.length > 0) {
+      return true;
+    }
+    ElMessage({
+      message: "请添加请款明细!",
+      type: "info",
+    });
+    return false;
+  }
+  return false;
+};
+// 获取用户信息并赋默认值
+const userInfo = useUserStore().user;
+const tenantId = "@福建宏星!#¥%……&*()";
+// const tenantId = userInfo.tenantId;
+
+onMounted(() => {
+  formData.data.paymentTime = proxy.parseTime(new Date());
+  getDictData();
+});
+const companyData = ref([]);
+const accountData = ref([]);
+const deptTreeData = ref([]);
+const fundsType = ref([]);
+const fundsCostType = ref([]);
+const fundsPaymentMethod = ref([]);
+const currencyType = ref([]);
+
+const getDictData = () => {
+  // 获取归属公司数据
+  proxy
+    .post("/corporation/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      companyData.value = res.rows;
+    });
+  // 账户数据
+  proxy
+    .post("/accountManagement/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      accountData.value = res.rows;
+    });
+
+  // 部门树
+  proxy
+    .get("/tenantDept/list", {
+      pageNum: 1,
+      pageSize: 9999,
+      tenantId: userInfo.tenantId,
+    })
+    .then((message) => {
+      recursive(message.data);
+      deptTreeData.value = proxy.handleTree(message.data, "corporationId");
+    });
+  // 请款类型数据
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      tenantId: tenantId,
+      dictCode: "founds_type",
+    })
+    .then((res) => {
+      fundsType.value = res.rows;
+    });
+  // 请款费用类型数据
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      tenantId: tenantId,
+      dictCode: "funds_cost_type",
+    })
+    .then((res) => {
+      fundsCostType.value = res.rows;
+    });
+  // 请款付款方式数据
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      tenantId: tenantId,
+      dictCode: "funds_payment_method",
+    })
+    .then((res) => {
+      fundsPaymentMethod.value = res.rows;
+    });
+
+  // 币种数据
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      tenantId: tenantId,
+      dictCode: "account_currency",
+    })
+    .then((res) => {
+      currencyType.value = res.rows;
+    });
+};
+const recursive = (data) => {
+  data.map((item) => {
+    item.label = item.deptName;
+    item.id = item.corporationId;
+    if (item.children) {
+      recursive(item.children);
+    } else {
+      item.children = [];
+    }
+  });
+};
+
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+
+// 部门变更逻辑
+const handleChangeDept = (val) => {
+  formData.data.departmentId = val[val.length - 1];
+};
+// 计算请款总金额
+const handleChangeAmount = () => {
+  let sum = 0;
+  for (let i = 0; i < formData.data.accountRequestFundsDetailList.length; i++) {
+    const e = formData.data.accountRequestFundsDetailList[i];
+    sum += e.amount;
+  }
+  formData.data.total = sum;
+};
+// 上传附件
+const uploadData = ref({});
+const fileList = ref([]);
+const handleBeforeUpload = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  fileList.value.push({
+    id: res.id,
+    fileName: res.fileName,
+    path: res.fileUrl,
+    url: res.fileUrl,
+    uid: file.uid,
+  });
+};
+const handleClose = (index) => {
+  fileList.value.splice(index, 1);
+};
+// 向父组件暴露
+defineExpose({
+  submitData: formData.data,
+  handleSubmit,
+});
+</script>
+
+
+<style lang="scss" scoped>
+._t {
+  margin-bottom: 5px;
+  font-size: 14px;
+}
+</style>

+ 447 - 0
src/components/WDLY/process/SendPurchase.vue

@@ -0,0 +1,447 @@
+<template>
+  <div style="width: 100%; padding: 0px 15px">
+    <el-form
+      :model="formData.data"
+      :rules="rules"
+      ref="formDom"
+      label-position="top"
+    >
+      <div class="_t">基础信息</div>
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="采购部门" prop="deptName">
+            <el-input v-model="formData.data.deptName" placeholder="请输入">
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="采购人" prop="purchaseName">
+            <el-input v-model="formData.data.purchaseName" placeholder="请输入">
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="采购时间" prop="purchaseTime">
+            <el-date-picker
+              v-model="formData.data.purchaseTime"
+              type="datetime"
+              placeholder="请选择"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="供应商" prop="supplyId">
+            <el-select
+              v-model="formData.data.supplyId"
+              placeholder="请选择"
+              @change="handleChangeSupplier"
+              filterable
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in supplierData"
+                :label="item.name"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="是否合同" prop="isAgreement">
+            <el-select
+              v-model="formData.data.isAgreement"
+              placeholder="请选择"
+              style="width: 100%"
+            >
+              <el-option label="是" value="1"> </el-option>
+              <el-option label="否" value="0"> </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="付款方式" prop="paymentMethod">
+            <el-select
+              v-model="formData.data.paymentMethod"
+              placeholder="请选择"
+              filterable
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in fundsPaymentMethod"
+                :label="item.dictValue"
+                :value="item.dictKey"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-form-item label="采购说明" prop="purchaseContent">
+        <el-input
+          v-model="formData.data.purchaseContent"
+          placeholder="请输入"
+          type="textarea"
+        >
+        </el-input>
+      </el-form-item>
+      <div class="_t">采购明细</div>
+      <el-form-item>
+        <el-button
+          type="primary"
+          @click="openProduct = true"
+          style="margin: 10px 0"
+          v-if="ids.length == 0"
+        >
+          添加货品
+        </el-button>
+        <el-table :data="formData.data.purchaseDetailList">
+          <el-table-column
+            prop="goodType"
+            label="货品类型"
+            :formatter="(row) => (row.goodType == 1 ? '产品' : '物料')"
+          />
+          <el-table-column prop="productCode" label="货品编码" />
+          <el-table-column prop="productName" label="货品名称" />
+          <el-table-column prop="productSpec" label="规格型号" />
+          <el-table-column prop="productUnit" label="单位" />
+          <el-table-column
+            prop="subscribeCount"
+            label="申购数量"
+            v-if="ids.length > 0"
+          />
+          <el-table-column
+            prop="purchaseCount"
+            label="已采购数量"
+            v-if="ids.length > 0"
+          />
+          <el-table-column prop="count" label="本次采购" min-width="150">
+            <template #default="{ row, $index }">
+              <el-form-item
+                :prop="'purchaseDetailList.' + $index + '.count'"
+                :rules="rules.count"
+                :inline-message="true"
+              >
+                <el-input-number
+                  v-model="row.count"
+                  :precision="4"
+                  :controls="false"
+                  :min="0"
+                  @change="handleChangeAmount"
+                />
+              </el-form-item>
+            </template>
+          </el-table-column>
+          <el-table-column prop="price" label="单价" min-width="150">
+            <template #default="{ row, $index }">
+              <el-form-item
+                :prop="'purchaseDetailList.' + $index + '.price'"
+                :rules="rules.price"
+                :inline-message="true"
+              >
+                <el-input-number
+                  v-model="row.price"
+                  :precision="4"
+                  :controls="false"
+                  :min="0"
+                  @change="handleChangeAmount"
+                />
+              </el-form-item>
+            </template>
+          </el-table-column>
+          <el-table-column prop="amount" label="金额" />
+          <el-table-column prop="zip" label="操作" width="100">
+            <template #default="{ $index }">
+              <el-button type="primary" link @click="handleRemove($index, 20)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+      <div class="_t">其他费用</div>
+      <el-form-item>
+        <el-button type="primary" style="margin: 10px 0" @click="handleAdd">
+          添加
+        </el-button>
+        <el-table :data="formData.data.otherFeeList">
+          <el-table-column prop="name" label="费用名称" min-width="150">
+            <template #default="{ row, $index }">
+              <el-form-item
+                :prop="'otherFeeList.' + $index + '.name'"
+                :rules="rules.name"
+                :inline-message="true"
+              >
+                <el-input v-model="row.name" placeholder="请输入" />
+              </el-form-item>
+            </template>
+          </el-table-column>
+          <el-table-column prop="price" label="金额" min-width="150">
+            <template #default="{ row, $index }">
+              <el-form-item
+                :prop="'purchaseDetailList.' + $index + '.price'"
+                :rules="rules.price"
+                :inline-message="true"
+              >
+                <el-input-number
+                  v-model="row.price"
+                  :precision="4"
+                  :controls="false"
+                  :min="0"
+                  @change="handleChangeAmount"
+                />
+              </el-form-item>
+            </template>
+          </el-table-column>
+
+          <el-table-column prop="remark" label="备注" min-width="150">
+            <template #default="{ row, $index }">
+              <el-form-item
+                :prop="'otherFeeList.' + $index + '.remark'"
+                :rules="rules.remark"
+                :inline-message="true"
+              >
+                <el-input v-model="row.remark" placeholder="请输入" />
+              </el-form-item>
+            </template>
+          </el-table-column>
+          <el-table-column prop="zip" label="操作" width="100">
+            <template #default="{ $index }">
+              <el-button type="primary" link @click="handleRemove($index, 10)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+      <el-row>
+        <el-col :span="4">
+          <el-form-item label="采购金额" prop="amount">
+            <el-input
+              v-model="formData.data.amount"
+              placeholder="请输入"
+              disabled
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+  <el-dialog v-model="openProduct" title="选择货品" width="70%" append-to-body>
+    <SelectGoods
+      @cancel="openProduct = false"
+      @pushGoods="pushGoods"
+    ></SelectGoods>
+  </el-dialog>
+</template>
+
+<script setup>
+import SelectGoods from "@/components/product/SelectGoods";
+import { ElMessage, ElMessageBox } from "element-plus";
+import useUserStore from "@/store/modules/user";
+
+const { proxy } = getCurrentInstance();
+
+let formData = reactive({
+  data: {
+    purchaseTime: "",
+    purchaseDetailList: [],
+    otherFeeList: [],
+  },
+});
+let rules = ref({
+  deptName: [{ required: true, message: "请输入采购部门", trigger: "blur" }],
+  purchaseName: [
+    { required: true, message: "请输入采购人名称", trigger: "blur" },
+  ],
+  purchaseTime: [
+    { required: true, message: "请选择采购时间", trigger: "change" },
+  ],
+  supplyId: [{ required: true, message: "请选择供应商", trigger: "change" }],
+  count: [{ required: true, message: "请输入本次采购数量", trigger: "blur" }],
+  price: [{ required: true, message: "请输入单价/金额", trigger: "blur" }],
+  remark: [{ required: true, message: "请输入备注", trigger: "blur" }],
+  isAgreement: [
+    { required: true, message: "请选择是否合同", trigger: "change" },
+  ],
+  paymentMethod: [
+    { required: true, message: "请选择付款方式", trigger: "change" },
+  ],
+});
+
+let openProduct = ref(false);
+const handleAdd = () => {
+  formData.data.otherFeeList.push({
+    name: "",
+    price: 0,
+    remark: "",
+  });
+};
+// 物品相应逻辑
+const handleRemove = (index, type) => {
+  if (type == 10) {
+    formData.data.otherFeeList.splice(index, 1);
+  } else if (type == 20) {
+    formData.data.purchaseDetailList.splice(index, 1);
+  }
+  handleChangeAmount();
+  return ElMessage({
+    message: "删除成功!",
+    type: "success",
+  });
+};
+
+const pushGoods = (goods) => {
+  const arr = goods.map((x) => ({
+    goodType: x.goodType,
+    productCode: x.code,
+    productName: x.name,
+    productSpec: x.spec,
+    productUnit: x.unit,
+    count: 0,
+    price: 0,
+    bussinessId: x.id,
+    amount: 0,
+  }));
+  formData.data.purchaseDetailList =
+    formData.data.purchaseDetailList.concat(arr);
+  return ElMessage({
+    message: "添加成功!",
+    type: "success",
+  });
+};
+// 提交方法
+const formDom = ref(null);
+const handleSubmit = async () => {
+  const vaild = await formDom.value.validate();
+  if (vaild) {
+    if (formData.data.purchaseDetailList.length > 0) {
+      const list = formData.data.purchaseDetailList;
+      for (let i = 0; i < list.length; i++) {
+        const e = list[i];
+        if (ids.value.length > 0) {
+          if (Number(e.subscribeCount) - Number(e.purchaseCount) > 0) {
+            if (e.count == 0) {
+              ElMessage({
+                message: "本次采购数量不能为0!",
+                type: "info",
+              });
+              return false;
+            }
+          }
+          if (e.count + Number(e.purchaseCount) > Number(e.subscribeCount)) {
+            ElMessage({
+              message: "本次采购数量和已采购数量和不可大于申购数量!",
+              type: "info",
+            });
+            return false;
+          }
+        } else {
+          if (e.count == 0) {
+            ElMessage({
+              message: "本次采购数量不能为0!",
+              type: "info",
+            });
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+    ElMessage({
+      message: "请添加采购明细!",
+      type: "info",
+    });
+    return false;
+  }
+
+  return false;
+};
+// 获取用户信息并赋默认值
+const userInfo = useUserStore().user;
+onMounted(() => {
+  formData.data.purchaseTime = proxy.parseTime(new Date());
+  formData.data.deptName = userInfo.dept.deptName;
+  formData.data.purchaseName = userInfo.nickName;
+  getSupplierList();
+  if (props.queryData.ids) {
+    ids.value = props.queryData.ids.split(",") || [];
+    getDetails();
+  }
+});
+
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+
+const ids = ref([]);
+const getDetails = () => {
+  proxy.post("/subscribeDetail/detail", { ids: ids.value }).then((res) => {
+    formData.data.purchaseDetailList = res.map((x) => ({
+      ...x,
+      subscribeCount: x.count,
+      count: Number(x.count) - Number(x.purchaseCount),
+      price: null,
+      amount: null,
+    }));
+  });
+};
+// 获取用户信息并赋默认值
+const tenantId = "@福建宏星!#¥%……&*()";
+// const tenantId = userInfo.tenantId;
+// 获取供应商数据
+const supplierData = ref([]);
+const fundsPaymentMethod = ref([]);
+const getSupplierList = async (req) => {
+  proxy
+    .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      supplierData.value = res.rows;
+    });
+
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      tenantId: tenantId,
+      dictCode: "funds_payment_method",
+    })
+    .then((res) => {
+      fundsPaymentMethod.value = res.rows;
+    });
+};
+// 供应商改变逻辑
+const handleChangeSupplier = (val) => {
+  console.log(val, "as");
+};
+// 计算采购总金额
+const handleChangeAmount = () => {
+  let sum = 0;
+  for (let i = 0; i < formData.data.purchaseDetailList.length; i++) {
+    const e = formData.data.purchaseDetailList[i];
+    e.amount = e.count * e.price;
+    sum += e.amount;
+  }
+  for (let i = 0; i < formData.data.otherFeeList.length; i++) {
+    const e = formData.data.otherFeeList[i];
+    sum += e.price;
+  }
+  formData.data.amount = sum;
+};
+// 向父组件暴露
+defineExpose({
+  submitData: formData.data,
+  handleSubmit,
+});
+</script>
+
+
+<style lang="scss" scoped>
+._t {
+  margin-bottom: 5px;
+  font-size: 14px;
+}
+</style>

+ 252 - 0
src/components/WDLY/process/SendSubscribe.vue

@@ -0,0 +1,252 @@
+<template>
+  <div style="width: 100%; padding: 0px 15px">
+    <byForm
+      :formConfig="formConfig"
+      :formOption="formOption"
+      v-model="formData.data"
+      :rules="rules"
+      ref="formDom"
+    >
+      <template #details>
+        <div style="width: 100%">
+          <el-button
+            type="primary"
+            @click="openProduct = true"
+            style="margin-bottom: 10px"
+          >
+            添加物品
+          </el-button>
+          <el-table :data="formData.data.subscribeDetailList">
+            <el-table-column
+              prop="goodType"
+              label="物品类型"
+              :formatter="(row) => (row.goodType == 1 ? '产品' : '物料')"
+            />
+            <el-table-column prop="productCode" label="物品编码" />
+            <el-table-column prop="productName" label="物品名称" />
+            <el-table-column prop="productSpec" label="规格型号" />
+            <el-table-column prop="productUnit" label="单位" />
+            <el-table-column prop="count" label="申购数量" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'subscribeDetailList.' + $index + '.count'"
+                  :rules="rules.count"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.count"
+                    :precision="4"
+                    :controls="false"
+                    :min="0"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column prop="remark" label="备注" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'subscribeDetailList.' + $index + '.remark'"
+                  :rules="rules.remark"
+                  :inline-message="true"
+                >
+                  <el-input v-model="row.remark" placeholder="请输入" />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column prop="zip" label="操作" width="100">
+              <template #default="{ $index }">
+                <el-button type="primary" link @click="handleRemove($index)"
+                  >删除</el-button
+                >
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+    </byForm>
+    <el-dialog
+      v-model="openProduct"
+      title="选择物品"
+      width="70%"
+      append-to-body
+    >
+      <SelectGoods
+        @cancel="openProduct = false"
+        @pushGoods="pushGoods"
+      ></SelectGoods>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import byForm from "@/components/byForm/index";
+import { ElMessage, ElMessageBox } from "element-plus";
+import SelectGoods from "@/components/product/SelectGoods";
+import useUserStore from "@/store/modules/user";
+const { proxy } = getCurrentInstance();
+
+let formData = reactive({
+  data: {
+    subscribeDetailList: [],
+  },
+});
+let rules = ref({
+  receiptWarehouseId: [
+    { required: true, message: "请选择收获仓库", trigger: "change" },
+  ],
+  planArrivalTime: [
+    { required: true, message: "请选择要求到货时间", trigger: "change" },
+  ],
+  count: [{ required: true, message: "请输入申购数量", trigger: "blur" }],
+  remark: [{ required: true, message: "请输入申购备注", trigger: "blur" }],
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "deptName",
+      label: "申购部门",
+      itemWidth: 25,
+      disabled: true,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "input",
+      prop: "subcribeName",
+      label: "申购人",
+      itemWidth: 25,
+      disabled: true,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "date",
+      prop: "subcribeTime",
+      label: "申购时间",
+      itemWidth: 26,
+      disabled: true,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "select",
+      prop: "receiptWarehouseId",
+      label: "收获仓库",
+      itemWidth: 25,
+      isLoad: {
+        url: "/warehouse/page",
+        req: {
+          pageNum: 1,
+          pageSize: 9999,
+        },
+        labelKey: "name",
+        labelVal: "id",
+        method: "post",
+        resUrl: "rows",
+      },
+    },
+    {
+      type: "date",
+      prop: "planArrivalTime",
+      label: "要求到货时间",
+      itemWidth: 25,
+      format: "YYYY-MM-DD",
+      style: {
+        "margin-left": "10px",
+      },
+    },
+    {
+      type: "input",
+      itemType: "textarea",
+      prop: "subcribeContent",
+      label: "申购说明",
+    },
+    {
+      type: "slot",
+      slotName: "details",
+      label: "申购明细",
+    },
+  ];
+});
+const formDom = ref(null);
+const handleSubmit = async () => {
+  const vaild = await formDom.value.handleSubmit(() => {}); //拿到内部表单是否验证通过
+  if (vaild) {
+    if (formData.data.subscribeDetailList.length > 0) {
+      const list = formData.data.subscribeDetailList;
+      for (let i = 0; i < list.length; i++) {
+        const e = list[i];
+        if (e.count == 0) {
+          ElMessage({
+            message: "申购数量不能为0!",
+            type: "info",
+          });
+          return false;
+        }
+      }
+      return true;
+    }
+    ElMessage({
+      message: "请添加申购明细!",
+      type: "info",
+    });
+    return false;
+  }
+};
+let openProduct = ref(false);
+const handleRemove = (index) => {
+  formData.data.subscribeDetailList.splice(index, 1);
+  return ElMessage({
+    message: "删除成功!",
+    type: "success",
+  });
+};
+const pushGoods = (goods) => {
+  const arr = goods.map((x) => ({
+    goodType: x.goodType,
+    productCode: x.code,
+    productName: x.name,
+    productSpec: x.spec,
+    productUnit: x.unit,
+    count: 0,
+    bussinessId: x.id,
+    remark: "",
+  }));
+  formData.data.subscribeDetailList =
+    formData.data.subscribeDetailList.concat(arr);
+  return ElMessage({
+    message: "添加成功!",
+    type: "success",
+  });
+};
+
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+
+// 获取用户信息并赋默认值
+const userInfo = useUserStore().user;
+onMounted(() => {
+  formData.data.subcribeTime = proxy.parseTime(new Date());
+  formData.data.deptName = userInfo.dept.deptName;
+  formData.data.subcribeName = userInfo.nickName;
+});
+// 向父组件暴露
+defineExpose({
+  submitData: formData.data,
+  handleSubmit,
+});
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 1 - 2
src/components/byForm/index.vue

@@ -89,7 +89,7 @@
           <el-checkbox
             v-for="j in i.data"
             :key="j.id || j.value"
-            ::label="j.id  || j.value"
+            :label="j.id  || j.value"
             name="type"
           >
             {{ j.name || j.label }}
@@ -196,7 +196,6 @@ const formData = computed(() => {
 });
 const formDataReset = ref({ ...proxy.modelValue });
 const commonsEmit = (prop, item) => {
-  console.log(formData);
   if (item.fn) {
     item.fn(prop);
   }

+ 10 - 5
src/components/byTable/index.vue

@@ -28,7 +28,11 @@
           style="margin-right: 10px"
         >
           <div class="by-dropdown-title">
-            {{ i.label }}<i style="margin-left:5px" class="iconfont icon-iconm_xialan1"></i>
+            {{ i.label
+            }}<i
+              style="margin-left: 5px"
+              class="iconfont icon-iconm_xialan1"
+            ></i>
           </div>
           <ul class="by-dropdown-lists">
             <li
@@ -398,11 +402,13 @@ export default defineComponent({
 
     const isSelectable = (row, index, item) => {
       if (item.type === "selection") {
-        if (row[item.attrs.checkAtt]) {
+        if (item.attrs && item.attrs.checkAtt) {
+          if (row[item.attrs.checkAtt]) {
+            return row[item.attrs.checkAtt];
+          }
+        } else {
           return true;
         }
-      } else {
-        return true;
       }
     };
 
@@ -450,7 +456,6 @@ export default defineComponent({
   margin-bottom: 10px;
 }
 .by-dropdown {
-  
   position: relative;
   text-align: left;
   height: 32px;

+ 1 - 0
src/components/process/SendPurchase.vue

@@ -184,6 +184,7 @@ let openProduct = ref(false);
 // 物品相应逻辑
 const handleRemove = (index) => {
   formData.data.purchaseDetailList.splice(index, 1);
+  handleChangeAmount();
   return ElMessage({
     message: "删除成功!",
     type: "success",

+ 3 - 1
src/main.js

@@ -44,7 +44,7 @@ import {
   selectDictLabels
 } from '@/utils/ruoyi'
 
-import { dictDataEcho, moneyFormat, calculationWeek } from '@/utils/util'
+import { dictDataEcho, moneyFormat, calculationWeek,getDict } from '@/utils/util'
 
 // 分页组件
 import Pagination from '@/components/Pagination'
@@ -78,6 +78,8 @@ app.config.globalProperties.selectDictLabels = selectDictLabels
 app.config.globalProperties.dictDataEcho = dictDataEcho
 app.config.globalProperties.moneyFormat = moneyFormat
 app.config.globalProperties.calculationWeek = calculationWeek
+app.config.globalProperties.getDict = getDict
+
 
 
 

+ 11 - 0
src/store/modules/mail.js

@@ -0,0 +1,11 @@
+const useMailStore = defineStore(
+  'mail', {
+    state: () => ({
+      selectMail: {}, //当前选中的邮箱
+      currentMenu: {}, //当前选中的邮箱菜单数据
+      currentId: "", //当前选中的邮箱菜单id
+      mailMenuList: [] //邮箱菜单数据
+    }),
+    actions: {}
+  })
+export default useMailStore

+ 46 - 0
src/utils/util.js

@@ -1,5 +1,11 @@
 import moment from "moment";
 
+import {
+  post,
+  get
+} from '@/utils/request'
+import Cookies from 'js-cookie'
+
 //根据value值回显字典label值
 export function dictDataEcho(value, arr) {
   if (value && arr) {
@@ -13,6 +19,46 @@ export function dictDataEcho(value, arr) {
   return "";
 }
 
+export function getDict(key) {
+  return new Promise((resolve, reject) => {
+    let dictObj = {}
+    let arr = {}
+    let num = 0
+    if(!sessionStorage.getItem('dict')) {
+      sessionStorage.setItem('dict', JSON.stringify(dictObj))
+    }else{
+      dictObj = JSON.parse(sessionStorage.getItem('dict'))
+    }
+    for (let i = 0; i < key.length; i++) {
+      const element = key[i];
+      if(dictObj[element]) {
+        arr[element] = dictObj[element]
+        num++
+        if(num === key.length) {
+          resolve(arr);
+        }
+      }else{
+        post("/dictTenantData/page", {
+          pageNum: 1,
+          pageSize: 999,
+          tenantId: Cookies.get('tenantId'),
+          dictCode: element,
+        }).then(res => {
+          dictObj[element] = res.rows
+          arr[element] = res.rows
+          sessionStorage.setItem('dict', JSON.stringify(dictObj))
+          num++
+          console.log(num)
+          if(num === key.length) {
+            resolve(arr);
+          }
+        })
+      }
+    }
+  })
+  
+}
+
 // 金额千分符
 export function moneyFormat(s, n) {
   if (s) {

+ 10 - 10
src/views/WDLY/basic/product/index.vue

@@ -374,42 +374,39 @@ const config = computed(() => {
     {
       attrs: {
         label: "管理部门",
-        prop: "spec",
+        prop: "deptName",
       },
     },
     {
       attrs: {
         label: "生命周期",
-        prop: "spec",
+        prop: "lifeCycle",
       },
     },
-
     {
       attrs: {
         label: "京东供价",
-        prop: "spec",
+        prop: "jdPurchasePrice",
       },
     },
     {
       attrs: {
         label: "标准售价",
-        prop: "spec",
+        prop: "sellingPrice",
       },
     },
     {
       attrs: {
         label: "标准采购价",
-        prop: "spec",
+        prop: "purchasePrice",
       },
     },
-
     {
       attrs: {
         label: "产品备注",
         prop: "remark",
       },
     },
-
     {
       attrs: {
         label: "操作",
@@ -619,7 +616,11 @@ const getList = async (req) => {
     .post("/productInfo/page", sourceList.value.pagination)
     .then((message) => {
       console.log(message);
-      sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
+      sourceList.value.data = message.rows.map((x) => ({
+        ...x,
+        fileList: [],
+        ...JSON.parse(x.victoriatouristJson),
+      }));
       sourceList.value.pagination.total = message.total;
       setTimeout(() => {
         loading.value = false;
@@ -748,7 +749,6 @@ const getDtl = (row) => {
     res.type = res.type + ""; //type回显
     res.definition = "1"; //产品
     res.victoriatouristJson = JSON.parse(res.victoriatouristJson);
-    console.log(res.victoriatouristJson, "ws");
     res.combination = res.victoriatouristJson.combination + "";
     res.productCombinationList = res.victoriatouristJson.productCombinationList;
     formData.data = res;

+ 623 - 0
src/views/WDLY/basic/supplier/index.vue

@@ -0,0 +1,623 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+          select: select,
+        }"
+        :action-list="[
+          {
+            text: '添加供应商',
+            action: () => openModal('add'),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #address="{ item }">
+          <div>
+            {{ item.countryName }}, {{ item.provinceName }} ,
+            {{ item.cityName }}, {{ item.areaDetail }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加供应商' : '编辑供应商'"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #address>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-form-item prop="countryId">
+                <el-select
+                  v-model="formData.data.countryId"
+                  placeholder="国家"
+                  @change="(val) => getCityData(val, '20', true)"
+                >
+                  <el-option
+                    v-for="item in countryData"
+                    :label="item.chineseName"
+                    :value="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item prop="provinceId">
+                <el-select
+                  v-model="formData.data.provinceId"
+                  placeholder="省/洲"
+                  @change="(val) => getCityData(val, '30', true)"
+                >
+                  <el-option
+                    v-for="item in provinceData"
+                    :label="item.name"
+                    :value="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item prop="cityId">
+                <el-select v-model="formData.data.cityId" placeholder="城市">
+                  <el-option
+                    v-for="item in cityData"
+                    :label="item.name"
+                    :value="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="24">
+              <el-form-item prop="areaDetail">
+                <el-input v-model="formData.data.areaDetail" type="textarea">
+                </el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #contact>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-form-item prop="contactPerson">
+                <el-input
+                  v-model="formData.data.contactPerson"
+                  placeholder="联系人"
+                >
+                </el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="16">
+              <el-form-item prop="contactNumber">
+                <el-input
+                  v-model="formData.data.contactNumber"
+                  placeholder="联系电话"
+                  :formatter="(val) => val.replace(/[^\d\-]/g, '')"
+                  :parser="(val) => val.replace(/[^\d\-]/g, '')"
+                >
+                </el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #fileSlot>
+          <div>
+            <el-upload
+              v-model:fileList="fileList"
+              :show-file-list="false"
+              class="upload-demo"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              :on-preview="handlePreview"
+              :on-remove="handleRemove"
+              :on-success="handleSuccess"
+              :before-upload="handleBeforeUpload"
+            >
+              <el-button type="primary">选择</el-button>
+            </el-upload>
+            <div>
+              <div style="margin-top: 15px">
+                <el-tag
+                  style="margin-right: 10px"
+                  class="ml-2"
+                  type="info"
+                  v-for="(item, index) in fileListCopy"
+                  :key="index"
+                  closable
+                  @close="handleClose(index)"
+                  >{{ item.fileName }}</el-tag
+                >
+              </div>
+            </div>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import FileUpload from "@/components/FileUpload/index";
+import { computed, defineComponent, ref } from "vue";
+import { getToken } from "@/utils/auth";
+
+const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const uploadData = ref({});
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    type: "",
+    keyword: "",
+  },
+});
+let dialogVisible = ref(false);
+let modalType = ref("add");
+let fileList = ref([]);
+let fileListCopy = ref([]);
+
+const checkContactNumber = (rule, val, callback) => {
+  if (val === "") {
+    callback(new Error("请输入联系电话"));
+  } else {
+    val = "aaa";
+  }
+  console.log(rule, val, callback, "213");
+  // @input="(val) => val.replace(/[^\d]/g, '')"
+};
+let rules = ref({
+  name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
+  type: [{ required: true, message: "请选择供应商类型", trigger: "change" }],
+  countryId: [{ required: true, message: "请选择国家", trigger: "change" }],
+  provinceId: [{ required: true, message: "请选择省/洲", trigger: "change" }],
+  cityId: [{ required: true, message: "请选择城市", trigger: "change" }],
+  areaDetail: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
+  contactPerson: [{ required: true, message: "请输入联系人", trigger: "blur" }],
+  // contactNumber: [{ validator: checkContactNumber, trigger: "blur" }],
+  contactNumber: [
+    { required: true, message: "请输入联系电话", trigger: "blur" },
+  ],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "供应商类型",
+    prop: "type",
+    data: [
+      {
+        label: "贸易商",
+        value: "1",
+      },
+      {
+        label: "工厂",
+        value: "2",
+      },
+    ],
+  },
+  {
+    label: "账期",
+    prop: "accountPeriodType",
+    data: [
+      {
+        label: "有",
+        value: "1",
+      },
+      {
+        label: "无",
+        value: "0",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "供应商类型",
+        prop: "type",
+      },
+      render(type) {
+        return type === 1 ? "贸易商" : "工厂";
+      },
+    },
+    {
+      attrs: {
+        label: "供应商编码",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "供应商名称",
+        prop: "name",
+      },
+    },
+    {
+      attrs: {
+        label: "所在城市",
+        prop: "remarks",
+        slot: "address",
+      },
+    },
+    {
+      attrs: {
+        label: "联系人",
+        prop: "contactPerson",
+      },
+    },
+    {
+      attrs: {
+        label: "联系人电话",
+        prop: "contactNumber",
+      },
+    },
+    {
+      attrs: {
+        label: "账期",
+        prop: "accountPeriod",
+      },
+    },
+    {
+      attrs: {
+        label: "备注",
+        prop: "returnPeriod",
+      },
+    },
+    {
+      attrs: {
+        label: "备注",
+        prop: "remark",
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "200",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "修改",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+          {
+            attrs: {
+              label: "删除",
+              type: "danger",
+              text: true,
+            },
+            el: "button",
+            click() {
+              // 弹窗提示是否删除
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
+                // 删除
+                proxy
+                  .post("/supplierInfo/delete", {
+                    id: row.id,
+                  })
+                  .then((res) => {
+                    ElMessage({
+                      message: "删除成功",
+                      type: "success",
+                    });
+                    getList();
+                  });
+              });
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    type: "1",
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "radio",
+      prop: "type",
+      label: "供应商类型",
+      required: true,
+      border: true,
+      data: [
+        { label: "贸易商", value: "1" },
+        { label: "工厂", value: "2" },
+      ],
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "供应商名称",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "address",
+      prop: "countryId",
+      label: "地址",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "contact",
+      prop: "contactPerson",
+      label: "联系信息",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "fileSlot",
+      label: "上传附件",
+    },
+    {
+      type: "input",
+      label: "备注",
+      prop: "remark",
+      itemType: "textarea",
+    },
+    {
+      type: "json",
+      prop: "victoriatouristJson",
+      json: [
+        {
+          type: "input",
+          prop: "accountPeriod",
+          label: "账期",
+          itemWidth: 33,
+          style: {
+            width: "100%",
+            "margin-right": "10px",
+          },
+        },
+        {
+          type: "input",
+          prop: "returnPeriod",
+          label: "退换货期限",
+          itemWidth: 33,
+        },
+        {
+          type: "input",
+          prop: "accountName",
+          label: "账户名称",
+          itemWidth: 100,
+        },
+        {
+          type: "input",
+          prop: "bankOfDeposit",
+          label: "开户银行",
+          itemWidth: 100,
+        },
+        {
+          type: "input",
+          prop: "bankAccount",
+          label: "银行账号",
+          itemWidth: 100,
+        },
+        {
+          type: "input",
+          prop: "interBankNo",
+          label: "联行号",
+          itemWidth: 100,
+        },
+        // {
+        //   type: "date",
+        //   prop: "clearancePeriod",
+        //   label: "库存清空期限",
+        //   itemWidth: 33.33,
+        //   format: "YYYY-MM-DD",
+        // },
+      ],
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/supplierInfo/pageByWdly", sourceList.value.pagination)
+    .then((message) => {
+      console.log(message);
+      sourceList.value.data = message.rows.map((x) => ({
+        ...x,
+        ...JSON.parse(x.victoriatouristJson),
+      }));
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+const openModal = () => {
+  dialogVisible.value = true;
+  modalType.value = "add";
+  formData.data = {
+    type: "1",
+    countryId: "China",
+  };
+  getCityData(formData.data.countryId, "20");
+};
+
+const submitForm = () => {
+  byform.value.handleSubmit((valid) => {
+    formData.data.fileList =
+      fileListCopy.value.map((x) => ({
+        id: x.id,
+        fileName: x.fileName,
+      })) || [];
+    submitLoading.value = true;
+    proxy.post("/supplierInfo/" + modalType.value, formData.data).then(
+      (res) => {
+        ElMessage({
+          message: modalType.value == "add" ? "添加成功" : "编辑成功",
+          type: "success",
+        });
+        fileList.value = [];
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      (err) => {
+        submitLoading.value = false;
+      }
+    );
+  });
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/supplierInfo/detail", { id: row.id }).then((res) => {
+    proxy
+      .post("/fileInfo/getList", { businessIdList: [row.id] })
+      .then((fileObj) => {
+        fileList.value = fileObj[row.id];
+        fileListCopy.value = [...fileList.value];
+        getCityData(res.countryId, "20");
+        getCityData(res.provinceId, "30");
+        res.type = res.type + "";
+        res.victoriatouristJson = JSON.parse(res.victoriatouristJson);
+        formData.data = res;
+        dialogVisible.value = true;
+      });
+  });
+};
+
+const handleBeforeUpload = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  fileListCopy.value.push({
+    id: res.id,
+    fileName: res.fileName,
+    path: res.fileUrl,
+    url: res.fileUrl,
+    uid: file.uid,
+  });
+};
+
+const handleClickFile = (row) => {
+  ElMessage({
+    message: "数据请求中,请稍后!",
+    type: "success",
+  });
+  let id = row.id;
+  proxy.post("/fileInfo/getList", { businessIdList: [id] }).then((res) => {
+    const file = res[id][0];
+    window.open(file.fileUrl, "_blank");
+  });
+};
+
+const handleClose = (index) => {
+  if (fileListCopy.value.length === 1) {
+    return ElMessage({
+      message: "最后一个附件啦!",
+      type: "info",
+    });
+  }
+  fileList.value.splice(index, 1);
+  fileListCopy.value.splice(index, 1);
+};
+
+const countryData = ref([]);
+const provinceData = ref([]);
+const cityData = ref([]);
+
+const getCityData = (id, type, isChange) => {
+  proxy.post("/areaInfo/list", { parentId: id }).then((res) => {
+    if (type === "20") {
+      provinceData.value = res;
+      if (isChange) {
+        formData.data.provinceId = "";
+        formData.data.cityId = "";
+      }
+    } else if (type === "30") {
+      cityData.value = res;
+      if (isChange) {
+        formData.data.cityId = "";
+      }
+    } else {
+      countryData.value = res;
+    }
+  });
+};
+getCityData("0");
+getList();
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 98 - 26
src/views/WDLY/outInBound/abnormal/index.vue

@@ -22,7 +22,7 @@
       </byTable>
     </div>
     <el-dialog
-      :title="modalType == 'add' ? '添加仓库' : '编辑'"
+      title="异常跟进"
       v-model="dialogVisible"
       width="800"
       v-loading="loading"
@@ -47,6 +47,25 @@
         </el-button>
       </template>
     </el-dialog>
+
+    <el-dialog title="跟进记录" v-model="dialogVisibleOne" width="500">
+      <div>
+        <el-timeline :reverse="false">
+          <el-timeline-item
+            placement="top"
+            v-for="(activity, index) in activities"
+            :key="index"
+            :timestamp="activity.handleTime"
+          >
+            <div>
+              跟进人:{{ activity.handleUserName }}
+              <span>({{ activity.status ? "已完成" : "处理中" }})</span>
+            </div>
+            <div style="margin-top: 5px">跟进记录: {{ activity.explain }}</div>
+          </el-timeline-item>
+        </el-timeline>
+      </div>
+    </el-dialog>
   </div>
 </template>
   
@@ -69,13 +88,22 @@ const sourceList = ref({
   },
 });
 let dialogVisible = ref(false);
+let dialogVisibleOne = ref(false);
+
 let roomDialogVisible = ref(false);
 let modalType = ref("add");
 let rules = ref({
-  type: [
-    { required: true, message: "请选择仓库类型", trigger: ["blur", "change"] },
+  status: [
+    { required: true, message: "请选择跟进结果", trigger: ["blur", "change"] },
+  ],
+  handleUser: [{ required: true, message: "请选择跟进人", trigger: "change" }],
+  handleTime: [
+    { required: true, message: "请选择跟进时间", trigger: "change" },
+  ],
+  processing: [
+    { required: true, message: "请选择处理方式", trigger: "change" },
   ],
-  name: [{ required: true, message: "请输入仓库名称", trigger: "blur" }],
+  explain: [{ required: true, message: "请输入处理说明", trigger: "blur" }],
 });
 const { proxy } = getCurrentInstance();
 const selectConfig = reactive([
@@ -166,7 +194,22 @@ const config = computed(() => {
               text: true,
             },
             el: "button",
-            click() {},
+            click() {
+              proxy
+                .post("/abnormalDetails/page", {
+                  abnormalInfoId: row.id,
+                })
+                .then((res) => {
+                  if (res.rows.length > 0) {
+                    activities.value = res.rows;
+                    dialogVisibleOne.value = true;
+                  } else
+                    return ElMessage({
+                      message: "暂无跟进记录!",
+                      type: "info",
+                    });
+                });
+            },
           },
         ];
       },
@@ -188,21 +231,35 @@ const byform = ref(null);
 const treeData = ref([]);
 const formConfig = reactive([
   {
-    type: "select",
-    prop: "type",
-    label: "仓库类型",
+    type: "radio",
+    prop: "status",
+    label: "跟进结果",
     required: true,
-    data: [],
+    border: true,
+    data: [
+      { label: "完成", value: "1" },
+      { label: "跟进中", value: "0" },
+    ],
   },
+
   {
-    type: "input",
-    prop: "name",
-    label: "仓库名称",
+    type: "select",
+    prop: "handleUser",
+    label: "跟进人",
+    isLoad: {
+      url: `/tenantUser/list?pageNum=1&pageSize=9999&tenantId=${
+        useUserStore().user.tenantId
+      }`,
+      labelKey: "nickName",
+      labelVal: "userId",
+      method: "get",
+      resUrl: "rows",
+    },
   },
   {
     type: "select",
-    prop: "keeperId",
-    label: "仓管员",
+    prop: "nextHandleUser",
+    label: "下一跟进人",
     isLoad: {
       url: `/tenantUser/list?pageNum=1&pageSize=9999&tenantId=${
         useUserStore().user.tenantId
@@ -214,10 +271,21 @@ const formConfig = reactive([
     },
   },
   {
+    type: "date",
+    itemType: "datetime",
+    prop: "handleTime",
+    label: "跟进时间",
+  },
+  {
+    type: "select",
+    prop: "processing",
+    label: "处理方式",
+  },
+  {
     type: "input",
     itemType: "textarea",
-    prop: "remark",
-    label: "备注",
+    prop: "explain",
+    label: "处理说明",
   },
 ]);
 const getList = async (req) => {
@@ -228,6 +296,7 @@ const getList = async (req) => {
     .then((message) => {
       console.log(message);
       sourceList.value.data = message.rows;
+      sourceList.value.data = [{}];
       sourceList.value.pagination.total = message.total;
       setTimeout(() => {
         loading.value = false;
@@ -239,12 +308,12 @@ const openModal = () => {
   modalType.value = "add";
   formData.data = {};
 };
-
+const activities = ref([]);
 const submitForm = () => {
   console.log(byform.value);
   byform.value.handleSubmit((valid) => {
     submitLoading.value = true;
-    proxy.post("/warehouse/" + modalType.value, formData.data).then(
+    proxy.post("/abnormalDetails/" + modalType.value, formData.data).then(
       (res) => {
         ElMessage({
           message: modalType.value == "add" ? "添加成功" : "编辑成功",
@@ -260,13 +329,16 @@ const submitForm = () => {
 };
 
 const getDtl = (row) => {
-  modalType.value = "edit";
-  proxy.post("/warehouse/detail", { id: row.id }).then((res) => {
-    res.type = res.type + "";
-    formData.data = res;
-    console.log(formData);
-    dialogVisible.value = true;
-  });
+  modalType.value = "add";
+  formData.data.status = "0";
+  dialogVisible.value = true;
+
+  // proxy.post("/warehouse/detail", { id: row.id }).then((res) => {
+  //   res.type = res.type + "";
+  //   formData.data = res;
+  //   console.log(formData);
+  //   dialogVisible.value = true;
+  // });
 };
 const warehouseType = ref([]);
 const getDict = () => {
@@ -291,7 +363,7 @@ const getDict = () => {
     });
 };
 getList();
-getDict();
+// getDict();
 </script>
   
 <style lang="scss" scoped>

+ 297 - 0
src/views/WDLY/outInBound/waitInBound/index.vue

@@ -0,0 +1,297 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+          select: select,
+        }"
+        :action-list="[]"
+        @get-list="getList"
+      >
+        <template #slotName="{ item }">
+          {{ item.createTime }}
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加仓库' : '编辑'"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import { computed, defineComponent, ref } from "vue";
+import useUserStore from "@/store/modules/user";
+
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+let dialogVisible = ref(false);
+let roomDialogVisible = ref(false);
+let modalType = ref("add");
+let rules = ref({
+  type: [
+    { required: true, message: "请选择仓库类型", trigger: ["blur", "change"] },
+  ],
+  name: [{ required: true, message: "请输入仓库名称", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "异常来源",
+    prop: "type",
+    data: [],
+  },
+  {
+    label: "处理状态",
+    prop: "type",
+    data: [],
+  },
+]);
+
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "类型",
+        prop: "name",
+      },
+      render(type) {
+        return proxy.dictDataEcho(type, warehouseType.value);
+      },
+    },
+    {
+      attrs: {
+        label: "仓库名称",
+        prop: "type",
+      },
+    },
+    {
+      attrs: {
+        label: "单号",
+        prop: "name",
+      },
+    },
+    {
+      attrs: {
+        label: "物流/快递公司",
+        prop: "keeperName",
+      },
+    },
+    {
+      attrs: {
+        label: "物流/快递单号",
+        prop: "remark",
+      },
+    },
+    {
+      attrs: {
+        label: "操作人",
+        prop: "remark",
+      },
+    },
+    {
+      attrs: {
+        label: "操作时间",
+        prop: "remark",
+      },
+    },
+    {
+      attrs: {
+        label: "状态",
+        prop: "name",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "100",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "入库",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {},
+  treeData: [],
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const treeData = ref([]);
+const formConfig = reactive([
+  {
+    type: "select",
+    prop: "type",
+    label: "仓库类型",
+    required: true,
+    data: [],
+  },
+  {
+    type: "input",
+    prop: "name",
+    label: "仓库名称",
+  },
+  {
+    type: "select",
+    prop: "keeperId",
+    label: "仓管员",
+    isLoad: {
+      url: `/tenantUser/list?pageNum=1&pageSize=9999&tenantId=${
+        useUserStore().user.tenantId
+      }`,
+      labelKey: "nickName",
+      labelVal: "userId",
+      method: "get",
+      resUrl: "rows",
+    },
+  },
+  {
+    type: "input",
+    itemType: "textarea",
+    prop: "remark",
+    label: "备注",
+  },
+]);
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/abnormalInfo/page", sourceList.value.pagination)
+    .then((message) => {
+      console.log(message);
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+const openModal = () => {
+  dialogVisible.value = true;
+  modalType.value = "add";
+  formData.data = {};
+};
+
+const submitForm = () => {
+  console.log(byform.value);
+  byform.value.handleSubmit((valid) => {
+    submitLoading.value = true;
+    proxy.post("/warehouse/" + modalType.value, formData.data).then(
+      (res) => {
+        ElMessage({
+          message: modalType.value == "add" ? "添加成功" : "编辑成功",
+          type: "success",
+        });
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      (err) => (submitLoading.value = false)
+    );
+  });
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/warehouse/detail", { id: row.id }).then((res) => {
+    res.type = res.type + "";
+    formData.data = res;
+    console.log(formData);
+    dialogVisible.value = true;
+  });
+};
+const warehouseType = ref([]);
+const getDict = () => {
+  // // 币种数据
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      tenantId: useUserStore().user.tenantId,
+      dictCode: "warehouse_type",
+    })
+    .then((res) => {
+      warehouseType.value = res.rows;
+      selectConfig[0].data = res.rows.map((x) => ({
+        label: x.dictValue,
+        value: x.dictKey,
+      }));
+      formConfig[0].data = res.rows.map((x) => ({
+        label: x.dictValue,
+        value: x.dictKey,
+      }));
+    });
+};
+getList();
+getDict();
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 286 - 0
src/views/WDLY/process/porcessDefinition/index.vue

@@ -0,0 +1,286 @@
+<template>
+	<div class="tenant">
+		<!-- <Banner /> -->
+		<div class="content">
+			<byTable
+				:source="sourceList.data"
+				:pagination="sourceList.pagination"
+				:config="config"
+				:loading="loading"
+				highlight-current-row
+				:selectConfig="selectConfig"
+				:table-events="{
+					//element talbe事件都能传
+					select: select,
+				}"
+				:action-list="[
+					{
+						text: '添加',
+						action: () => openModal('add'),
+					},
+				]"
+				@get-list="getList"
+			>
+				<template #slotName="{ item }">
+					{{ item.createTime }}
+				</template>
+			</byTable>
+		</div>
+		<el-dialog
+			:title="modalType == 'add' ? '新增' : '编辑'"
+			v-model="dialogVisible"
+			width="400"
+			v-loading="loading"
+		>
+			<byForm
+				:formConfig="formConfig"
+				:formOption="formOption"
+				v-model="formData.data"
+				:rules="rules"
+				ref="byform"
+			>
+			</byForm>
+			<template #footer>
+				<el-button @click="dialogVisible = false" size="large"
+					>取 消</el-button
+				>
+				<el-button
+					type="primary"
+					@click="submitForm('byform')"
+					size="large"
+					:loading="submitLoading"
+				>
+					确 定
+				</el-button>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+    
+  <script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from 'element-plus'
+import byTable from '@/components/byTable/index'
+import byForm from '@/components/byForm/index'
+import { computed, defineComponent, ref } from 'vue'
+const loading = ref(false)
+const submitLoading = ref(false)
+const dictCommonModal = ref(false)
+const sourceList = ref({
+	data: [],
+	pagination: {
+		total: 3,
+		pageNum: 1,
+		pageSize: 10,
+	},
+})
+let dialogVisible = ref(false)
+let roomDialogVisible = ref(false)
+let modalType = ref('add')
+let rules = ref({
+	classifyName: [{ required: true, message: '请输入功能模块', trigger: 'blur' }],
+	flowKey: [{ required: true, message: '请输入流程标识', trigger: 'blur' }],
+	flowName: [{ required: true, message: '请输入流程名称', trigger: 'blur' },],
+})
+const { proxy } = getCurrentInstance()
+const selectConfig = computed(() => {
+	return []
+})
+const config = computed(() => {
+	return [
+        {
+			attrs: {
+				label: '功能模块',
+                prop: 'classifyName',
+			},
+		},
+		{
+			attrs: {
+				label: '流程标识',
+				prop: 'flowKey',
+			},
+		},
+        {
+			attrs: {
+				label: '流程名称',
+				prop: 'flowName',
+			},
+		},
+		{
+			attrs: {
+				label: '状态',
+				width: 100,
+				prop: 'status',
+			},
+			render(status) {
+				//1审核中 2审核通过 3审核不通过
+				return status == 0
+					? '禁用'
+					: '启用'
+					
+			},
+		},
+		{
+			attrs: {
+				label: '创建时间',
+				prop: 'createTime',
+			},
+		},
+		{
+			attrs: {
+				label: '操作',
+				width: '200',
+				align: 'right',
+			},
+			// 渲染 el-button,一般用在最后一列。
+			renderHTML(row) {
+				return [
+					{
+					  attrs: {
+					    label: "修改",
+					    type: "primary",
+					    text: true,
+					  },
+					  el: "button",
+					  click() {
+					    getDtl(row);
+					  },
+					},
+					{
+						attrs: {
+							label: row.status == 1 ? '禁用' : '启用',
+							type: 'primary',
+							text: true,
+						},
+						el: 'button',
+						click() {
+							changeStatus(row)
+						},
+					},
+				]
+			},
+		},
+	]
+})
+let dtlData = reactive({
+	data: {},
+})
+let formData = reactive({
+	data: {},
+	treeData: [],
+})
+const formOption = reactive({
+	inline: true,
+	labelWidth: 100,
+	itemWidth: 100,
+	rules: [],
+})
+const byform = ref(null)
+const treeData = ref([])
+const formConfig = computed(() => {
+	return [
+        {
+			type: 'input',
+			prop: 'classifyName',
+			label: '功能模块',
+            
+		},
+		{
+			type: 'input',
+			prop: 'flowKey',
+			label: '流程标识',
+            isHide:modalType.value == 'edit'
+		},
+		{
+			type: 'input',
+			prop: 'flowName',
+			label: '流程名称',
+		},
+	]
+})
+const getList = async (req) => {
+	sourceList.value.pagination = { ...sourceList.value.pagination, ...req }
+	loading.value = true
+	proxy
+		.post('/flowInfo/page', sourceList.value.pagination)
+		.then((message) => {
+			console.log(message)
+			sourceList.value.data = message.rows
+			sourceList.value.pagination.total = message.total
+			setTimeout(() => {
+				loading.value = false
+			}, 200)
+		})
+}
+
+const openModal = () => {
+	dialogVisible.value = true
+	modalType.value = 'add'
+	formData.data = {}
+}
+const selection = ref({
+	data: [],
+})
+const select = (_selection, row) => {
+	selection.value.data = _selection
+	console.log(_selection.length)
+}
+
+const tree = ref(null)
+const submitTree = () => {
+	proxy
+		.post('/tenantInfo/bindingMenu', {
+			tenantId: selection.value.data[0].tenantId,
+			menuIdList: tree.value.getCheckedKeys(),
+		})
+		.then((res) => {
+			ElMessage({
+				message: '保存成功',
+				type: 'success',
+			})
+			roomDialogVisible.value = false
+		})
+}
+
+const submitForm = () => {
+	byform.value.handleSubmit((valid) => {
+		submitLoading.value = true
+		proxy
+			.post('/flowInfo/' + modalType.value, formData.data)
+			.then((res) => {
+				ElMessage({
+					message: modalType.value == 'add' ? '添加成功' : '编辑成功',
+					type: 'success',
+				})
+				dialogVisible.value = false
+				submitLoading.value = false
+				getList()
+			})
+	})
+}
+
+const getDtl = (row) => {
+	formData.data = { ...row }
+	modalType.value = 'edit'
+	dialogVisible.value = true
+}
+
+const changeStatus = (row) => {
+	modalType.value = 'edit'
+	proxy.post('/flowInfo/edit', { ...row,status:(row.status === 0) ? 1 : 0 }).then((res) => {
+		ElMessage({
+            message: '操作成功',
+            type: 'success',
+        })
+        getList()
+	})
+}
+
+getList()
+</script>
+    
+  <style lang="scss" scoped>
+.tenant {
+	padding: 20px;
+}
+</style>

+ 346 - 0
src/views/WDLY/process/processApproval/index.vue

@@ -0,0 +1,346 @@
+<template>
+  <div class="processApproval">
+    <div class="left-card">
+      <div class="top">
+        <div class="commons-title title">流程标题</div>
+        <SendSubscribe
+          ref="makeDom"
+          v-if="flowForm.flowKey == 'subscribe_flow'"
+        ></SendSubscribe>
+        <SendPurchase
+          ref="makeDom"
+          v-else-if="flowForm.flowKey == 'purchase_flow'"
+          :queryData="queryData.data"
+        ></SendPurchase>
+      </div>
+      <div class="bottom">
+        <div class="commons-title title">处理意见</div>
+        <el-form :model="flowForm" :rules="flowRules" ref="flowFormDom">
+          <el-form-item prop="remark" label-width="0px" label="">
+            <el-input
+              type="textarea"
+              placeholder="请输入"
+              v-model="flowForm.remark"
+            >
+            </el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button @click="handleSubmit"> ceshi </el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+    <div class="right-card">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+        <el-tab-pane label="审批记录" name="first">
+          <ul class="flow-chart">
+            <li v-for="item in recordList" :key="item.id">
+              <div class="left-icon">
+                <i class="iconfont icon-iconm_daick"></i>
+                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
+              </div>
+              <div class="right-conetnt">
+                <div class="name">
+                  发起人:{{ item.processedUser }}
+                  <!-- <span>2022-11-11 00:00:00</span> -->
+                </div>
+                <div class="remark">
+                  <div class="label">{{ item.nodeName }}</div>
+                  {{ item.remark }}
+                </div>
+              </div>
+              <div class="line"></div>
+            </li>
+          </ul>
+        </el-tab-pane>
+        <el-tab-pane label="决策辅助" name="second">决策辅助</el-tab-pane>
+      </el-tabs>
+    </div>
+  </div>
+  <el-dialog title="下一处理人" width="400" v-model="dialogVisible">
+    <el-form :model="flowForm">
+      <el-form-item prop="remark" label="处理人">
+        <el-select
+          v-model="flowForm.handleUserId"
+          placeholder="请选择"
+          filterable
+          style="width: 100%"
+        >
+          <el-option
+            v-for="item in nextHandleUser"
+            :label="item.name"
+            :value="item.id"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <div style="width: 100%; text-align: center">
+          <el-button type="primary" @click="handleSelectUser">提交 </el-button>
+        </div>
+      </el-form-item>
+    </el-form>
+  </el-dialog>
+</template>
+
+
+
+<script setup>
+import { useRouter, useRoute } from "vue-router";
+const router = useRouter();
+const route = useRoute();
+//申购发起
+import SendSubscribe from "@/components/WDLY/process/SendSubscribe";
+//采购发起
+import SendPurchase from "@/components/WDLY/process/SendPurchase";
+//请款发起
+import SendFunds from "@/components/WDLY/process/SendFunds";
+//退货
+import ReturnGood from "@/components/WDLY/process/ReturnGood";
+// 消息提示
+import { ElMessage, ElMessageBox } from "element-plus";
+// tab切换逻辑
+const activeName = ref("first");
+const handleClick = (tab, event) => {
+  // console.log(tab, event);
+};
+// 意见表单
+const flowForm = reactive({
+  flowKey: "",
+  handleUserId: "",
+  remark: "",
+  data: {},
+});
+const flowRules = reactive({
+  remark: [{ required: true, message: "请输入处理意见", trigger: "blur" }],
+});
+//组件实例
+const { proxy } = getCurrentInstance();
+const makeDom = ref(null);
+const flowFormDom = ref(null);
+let dialogVisible = ref(false);
+const nextHandleUser = ref([]);
+const handleSelectUser = () => {
+  if (!flowForm.handleUserId) {
+    return ElMessage({
+      message: "请选择下一节点处理人!",
+      type: "info",
+    });
+  }
+  handleSubmit();
+};
+
+const handleResult = (res) => {
+  if (res !== null && res.success) {
+    skipPage();
+  } else {
+    dialogVisible.value = true;
+    nextHandleUser.value = res.userList;
+  }
+};
+// 提交逻辑
+const handleSubmit = async () => {
+  try {
+    // 调用发起组件的提交事件
+    const flag = await makeDom.value.handleSubmit();
+    if (flag) {
+      flowFormDom.value.validate((vaild) => {
+        if (vaild) {
+          const data = { ...makeDom.value.submitData };
+          if (flowForm.flowKey == "subscribe_flow") {
+            data.subscribeDetailList = data.subscribeDetailList.map((x) => ({
+              bussinessId: x.bussinessId,
+              count: x.count,
+              remark: x.remark,
+            }));
+            const victoriatouristJson = {
+              planArrivalTime: data.planArrivalTime,
+              receiptWarehouseId: data.receiptWarehouseId,
+            };
+            data.victoriatouristJson = JSON.stringify(victoriatouristJson);
+          } else if (flowForm.flowKey == "purchase_flow") {
+            data.purchaseDetailList = data.purchaseDetailList.map((x) => ({
+              bussinessId: x.bussinessId,
+              subscribeDetailId: x.id,
+              count: x.count,
+              price: x.price,
+              amount: x.amount,
+            }));
+            const victoriatouristJson = {
+              isAgreement: data.isAgreement,
+              paymentMethod: data.paymentMethod,
+              otherFeeList: data.otherFeeList,
+            };
+            data.victoriatouristJson = JSON.stringify(victoriatouristJson);
+          } else if (flowForm.flowKey == "30") {
+          } else if (flowForm.flowKey == "40") {
+          }
+          proxy
+            .post("/flowProcess/initiate", {
+              ...flowForm,
+              data,
+            })
+            .then((res) => {
+              handleResult(res);
+            });
+        }
+      });
+    }
+  } catch (err) {
+    console.log("数据未填完整!", err);
+  }
+};
+// 页面跳转
+const skipPage = () => {
+  ElMessage({
+    message: "操作成功!",
+    type: "success",
+  });
+  if (flowForm.flowKey == "subscribe_flow") {
+    router.replace({
+      path: "/WDLY/purchaseManage/subscribe_wdly",
+    });
+  } else if (flowForm.flowKey == "purchase_flow") {
+    router.replace({
+      path: "/WDLY/purchaseManage/purchase_wdly",
+    });
+  } else if (flowForm.flowKey == "30") {
+    router.replace({
+      path: "/finance/fundManage/funds",
+    });
+  }
+};
+
+let queryData = reactive({
+  data: {},
+});
+// 记录
+const recordList = ref([]);
+const getRecords = () => {
+  proxy
+    .post("/flowExample/getFlowNode", {
+      flowKey: flowForm.flowKey,
+    })
+    .then((res) => {
+      console.log(res, "ass");
+      recordList.value = res;
+    });
+};
+
+onMounted(() => {
+  queryData.data = { ...route.query };
+  flowForm.flowKey = route.query.flowKey;
+  getRecords();
+});
+</script>
+
+  <style lang="scss" scoped>
+.processApproval {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 20px;
+  padding: 0 20px;
+  height: calc(100vh - 130px);
+  .left-card {
+    background: #fff;
+    border-radius: 4px;
+    padding: 20px;
+    flex: 1;
+    margin-right: 20px;
+    display: flex;
+    flex-direction: column;
+    .top {
+      flex: 1;
+      overflow-y: auto;
+      background: #fff;
+    }
+    .bottom {
+      height: 155px;
+      background: #fff;
+    }
+  }
+  .right-card {
+    background: #fff;
+    border-radius: 4px;
+    padding: 0 20px 20px;
+    width: 400px;
+    box-sizing: border-box;
+    .flow-chart {
+      overflow: auto;
+      padding: 0;
+      margin: 0;
+      li {
+        margin: 0;
+        padding: 0 0 20px;
+        list-style: none;
+        display: flex;
+        justify-content: space-between;
+        position: relative;
+        .right-conetnt {
+          flex: 1;
+          .name {
+            font-size: 12px;
+            color: #333;
+            margin-bottom: 10px;
+            span {
+              color: #999;
+              float: right;
+            }
+          }
+          .remark {
+            padding: 10px;
+            color: #666666;
+            font-size: 12px;
+            background: #f1f1f1;
+            border-radius: 2px;
+            .label {
+              color: #39c55a;
+              margin-bottom: 10px;
+            }
+          }
+        }
+        .left-icon {
+          width: 40px;
+          height: 40px;
+          text-align: center;
+          line-height: 40px;
+          background: #0084ff;
+          border-radius: 10px;
+          color: #fff;
+          font-size: 20px;
+          position: relative;
+          margin-right: 27px;
+          z-index: 2;
+          .right-btm-status {
+            position: absolute;
+            bottom: 0px;
+            right: -10px;
+            height: 20px;
+            width: 20px;
+            line-height: 16px;
+            border-radius: 10px;
+            background: #39c55a;
+            border: 2px solid #fff;
+            font-size: 12px;
+            box-sizing: border-box;
+          }
+        }
+      }
+      li::before {
+        content: "";
+        position: absolute;
+        top: 0;
+        left: 20px;
+        width: 2px;
+        height: 100%;
+        background: #ddd;
+        z-index: 1;
+      }
+      li:last-child::before {
+        display: none;
+      }
+    }
+  }
+}
+</style>
+      

+ 22 - 0
src/views/WDLY/process/processConfig/Sidebar.vue

@@ -0,0 +1,22 @@
+<script setup>
+function onDragStart(event, nodeType) {
+  if (event.dataTransfer) {
+    event.dataTransfer.setData('application/vueflow', nodeType)
+    event.dataTransfer.effectAllowed = 'move'
+  }
+}
+</script>
+
+<template>
+  <aside>
+    <div class="description">You can drag these nodes to the pane.</div>
+
+    <div class="nodes">
+      <div class="vue-flow__node-input" :draggable="true" @dragstart="onDragStart($event, 'input')">Input Node</div>
+
+      <div class="vue-flow__node-default" :draggable="true" @dragstart="onDragStart($event, 'default')">Default Node</div>
+
+      <div class="vue-flow__node-output" :draggable="true" @dragstart="onDragStart($event, 'output')">Output Node</div>
+    </div>
+  </aside>
+</template>

+ 325 - 0
src/views/WDLY/process/processConfig/index.vue

@@ -0,0 +1,325 @@
+<template>
+	<div class="user">
+		<div class="tree">
+			<treeList
+				:data="treeListData"
+				v-model="sourceList.pagination.tenantId"
+				node-key="id"
+				@change="treeChange"
+			>
+			</treeList>
+		</div>
+		<div class="content">
+			<byTable
+				:source="sourceList.data"
+				:pagination="sourceList.pagination"
+				:config="config"
+				:loading="loading"
+				highlight-current-row
+				:selectConfig="selectConfig"
+				:table-events="{
+					//element talbe事件都能传
+					select: select,
+				}"
+				:action-list="[
+					{
+						text: '添加流程',
+						action: () => openModal('add'),
+						disabled: !sourceList.pagination.tenantId,
+					},
+				]"
+				@get-list="getList"
+			>
+				<template #slotName="{ item }">
+					{{ item.createTime }}
+				</template>
+			</byTable>
+		</div>
+		<el-dialog
+			:title="modalType == 'add' ? '新增' : '编辑'"
+			v-model="dialogVisible"
+			width="500"
+			v-loading="loading"
+		>
+			<byForm
+				:formConfig="formConfig"
+				:formOption="formOption"
+				v-model="formData.data"
+				:rules="rules"
+				ref="byform"
+			>
+			</byForm>
+			<template #footer>
+				<el-button @click="dialogVisible = false" size="large"
+					>取 消</el-button
+				>
+				<el-button
+					type="primary"
+					@click="submitForm('byform')"
+					size="large"
+					:loading="submitLoading"
+				>
+					确 定
+				</el-button>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+    
+  <script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from 'element-plus'
+import byTable from '@/components/byTable/index'
+import byForm from '@/components/byForm/index'
+import treeList from '@/components/treeList/index'
+import { computed, defineComponent, ref } from 'vue'
+const loading = ref(false)
+const submitLoading = ref(false)
+const sourceList = ref({
+	data: [],
+	pagination: {
+		total: 3,
+		pageNum: 1,
+		pageSize: 10,
+	},
+})
+let dialogVisible = ref(false)
+let modalType = ref('add')
+let rules = ref({
+	roleKey: [{ required: true, message: '请选择部门', trigger: 'blur' }],
+	nickName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
+	userName: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
+})
+const { proxy } = getCurrentInstance()
+const selectConfig = computed(() => {
+	return []
+})
+const config = computed(() => {
+	return [
+		{
+			attrs: {
+				label: '功能模块',
+				prop: 'classifyName',
+			},
+		},
+		{
+			attrs: {
+				label: '流程标识',
+				prop: 'flowKey',
+			},
+		},
+		{
+			attrs: {
+				label: '流程名称',
+				prop: 'flowName',
+			},
+		},
+
+		{
+			attrs: {
+				label: '当前版本',
+				prop: 'versionNumber',
+			},
+		},
+
+		{
+			attrs: {
+				label: '操作',
+				width: '200',
+				align: 'right',
+			},
+			// 渲染 el-button,一般用在最后一列。
+			renderHTML(row) {
+				return [
+					{
+						attrs: {
+							label: '新建版本',
+							type: 'primary',
+							text: true,
+						},
+						el: 'button',
+						click() {
+							getDtl(row)
+						},
+					},
+					
+				]
+			},
+		},
+	]
+})
+
+let formData = reactive({
+	data: {},
+})
+const formOption = reactive({
+	inline: true,
+	labelWidth: 100,
+	itemWidth: 100,
+	rules: [],
+})
+const byform = ref(null)
+const treeListData = ref([])
+const formConfig = computed(() => {
+	return [
+		
+		{
+			type: 'select',
+			label: '功能模块',
+			prop: 'titleTemplate',
+			isLoad: {
+				url: `/flowInfo/getClassifyList`,
+				labelKey: 'stringArray',
+				labelVal: 'stringArray',
+				method: 'post',
+				resUrl: '',
+			},
+			fn: (data) => {
+				getFlowList(data)
+			},
+		},
+		{
+			type: 'select',
+			label: '流程名称',
+			prop: 'flowInfoId',
+			data:[],
+		},
+	]
+})
+
+
+const getFlowList = (name) => {
+	proxy.post('/flowInfo/page',{
+		pageNum:1,
+		pageSize:1000,
+		classifyName:name
+	}).then((message) => {
+		formConfig.value[1].data = message.rows.map(item => {
+			return {
+				label:item.flowName,
+				value:item.id
+			}
+		})
+		
+	})
+}
+
+const newPassword = () => {
+	formData.data.password = generatePassword()
+}
+const generatePassword = () => {
+	var length = 12,
+		charset =
+			'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
+		password = ''
+	for (var i = 0, n = charset.length; i < length; ++i) {
+		password += charset.charAt(Math.floor(Math.random() * n))
+	}
+	return password
+}
+
+const getTreeList = () => {
+	proxy.post('/tenantInfo/list').then((message) => {
+		message.map((item) => {
+			item.label = item.enterpriseName
+			item.id = item.tenantId
+			item.children = []
+		})
+
+		treeListData.value = message
+		console.log(treeListData.value)
+	})
+}
+const getList = async (req) => {
+	sourceList.value.pagination = { ...sourceList.value.pagination, ...req }
+	loading.value = true
+	proxy
+		.post('/flowDefinition/page', sourceList.value.pagination)
+		.then((message) => {
+			sourceList.value.data = message.rows
+			sourceList.value.pagination.total = message.total
+			setTimeout(() => {
+				loading.value = false
+			}, 200)
+		})
+}
+
+const treeChange = (e) => {
+	console.log(e)
+	sourceList.value.pagination.tenantId = e.id
+	getList({ tenantId: e.id })
+}
+
+const openModal = () => {
+	dialogVisible.value = true
+	modalType.value = 'add'
+	formData.data = {
+		userType: 1,
+	}
+}
+const TreetenantId = ref('')
+const selection = ref({
+	data: [],
+})
+const select = (_selection, row) => {
+	selection.value.data = _selection
+	console.log(_selection.length)
+}
+
+const tree = ref(null)
+const submitForm = () => {
+	byform.value.handleSubmit((valid) => {
+		
+		proxy
+			.post(
+				'/flowDefinition/' + modalType.value,
+				{
+					...formData.data,
+					tenantId: sourceList.value.pagination.tenantId,
+				},
+			)
+			.then((res) => {
+				ElMessage({
+					message: modalType.value == 'add' ? '添加成功' : '编辑成功',
+					type: 'success',
+				})
+				dialogVisible.value = false
+				getList()
+			})
+	})
+}
+
+const getDept = () => {
+	proxy.get('/system/user/deptTree').then((res) => {
+		//formConfig.value[0].data = res.data
+	})
+}
+
+const router = useRouter();
+const getDtl = (row) => {
+	formData.data = { ...row }
+	
+	router.push({
+		path: 'processChart',
+		query: {
+			id: row.id,
+		},
+	})
+}
+getTreeList()
+getList()
+</script>
+    
+<style lang="scss" scoped>
+.user {
+	padding: 20px;
+	display: flex;
+	justify-content: space-between;
+	.tree {
+		width: 300px;
+	}
+	.content {
+		width: calc(100% - 320px);
+	}
+}
+</style>

+ 39 - 0
src/views/WDLY/process/processConfig/processChart.vue

@@ -0,0 +1,39 @@
+<template>
+	<div class="processChart">
+		<div class="from">
+			<div class="commons-title">基础配置</div>
+		</div>
+		<div class="content">
+			<div class="commons-title">基础配置</div>
+			<div class="chart-warp">
+				<vueFlow></vueFlow>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup>
+import { VueFlow } from '@vue-flow/core'
+import vueFlow from '@/views/process/processConfig/vueFlow.vue'
+
+onMounted(() => {
+	
+})
+</script>
+
+<style lang="scss" scoped>
+.processChart {
+	padding: 20px;
+	display: flex;
+	justify-content: space-between;
+	.from {
+		width: 300px;
+	}
+	.content {
+		width: calc(100% - 320px);
+	}
+}
+.chart-warp {
+	height: calc(100vh - 180px);
+}
+</style>

+ 436 - 0
src/views/WDLY/process/processConfig/vueFlow.vue

@@ -0,0 +1,436 @@
+<template lang="">
+	<div class="vueFlow">
+		<div id="container"></div>
+		<div id="stencil"></div>
+		<div id="graph-container"></div>
+
+	</div>
+</template>
+<script lang="ts" setup>
+import {
+	defineComponent,
+	ref,
+	onMounted,
+	onUnmounted,
+	watch,
+	reactive,
+	toRefs,
+	computed,
+	nextTick,
+} from 'vue'
+import { Graph, Shape } from '@antv/x6'
+import { Stencil } from '@antv/x6-plugin-stencil'
+import { Transform } from '@antv/x6-plugin-transform'
+import { Selection } from '@antv/x6-plugin-selection'
+import { Snapline } from '@antv/x6-plugin-snapline'
+import { Keyboard } from '@antv/x6-plugin-keyboard'
+import { Clipboard } from '@antv/x6-plugin-clipboard'
+import { History } from '@antv/x6-plugin-history'
+const aaa = (port: any) => {
+	console.log(port)
+}
+const antvInit = () => {
+	const graph = new Graph({
+		height:700,
+		container: document.getElementById('graph-container')!,
+		grid: true,
+		onPortRendered:aaa,
+		mousewheel: {
+			enabled: true,
+			zoomAtMousePosition: true,
+			modifiers: 'ctrl',
+			minScale: 0.5,
+			maxScale: 3,
+		},
+		connecting: {
+			router: 'manhattan',
+			connector: {
+				name: 'rounded',
+				args: {
+					radius: 8,
+				},
+			},
+			anchor: 'center',
+			connectionPoint: 'anchor',
+			allowBlank: false,
+			snap: {
+				radius: 20,
+			},
+			createEdge() {
+				return new Shape.Edge({
+					attrs: {
+						line: {
+							stroke: '#A2B1C3',
+							strokeWidth: 2,
+							targetMarker: {
+								name: 'block',
+								width: 12,
+								height: 8,
+							},
+						},
+					},
+					zIndex: 0,
+				})
+			},
+			validateConnection({ targetMagnet }) {
+				return !!targetMagnet
+			},
+		},
+		highlighting: {
+			magnetAdsorbed: {
+				name: 'stroke',
+				args: {
+					attrs: {
+						fill: '#5F95FF',
+						stroke: '#5F95FF',
+					},
+				},
+			},
+		},
+	})
+	const stencil = new Stencil({
+		title: '流程图',
+		target: graph,
+		stencilGraphWidth: 200,
+		stencilGraphHeight: 180,
+		collapsable: true,
+		groups: [
+			{
+				title: '基础流程图',
+				name: 'group1',
+			},
+			
+		],
+		layoutOptions: {
+			columns: 2,
+			columnWidth: 80,
+			rowHeight: 55,
+		},
+	})
+	document.getElementById('stencil')!.appendChild(stencil.container)
+	// #region 使用插件
+	graph
+		.use(
+			new Transform({
+				resizing: true,
+				rotating: true,
+			})
+		)
+		.use(
+			new Selection({
+				enabled: true,
+				rubberband: true,
+				showNodeSelectionBox: true,
+			})
+		)
+		.use(
+			new Snapline({
+				enabled: true,
+			})
+		)
+		.use(
+			new Keyboard({
+				enabled: true,
+			})
+		)
+		.use(
+			new Clipboard({
+				enabled: true,
+			})
+		)
+		.use(
+			new History({
+				enabled: true,
+			})
+		)
+
+
+	// 控制连接桩显示/隐藏
+	const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
+		for (let i = 0, len = ports.length; i < len; i += 1) {
+			ports[i].style.visibility = show ? 'visible' : 'hidden'
+		}
+	}
+	graph.on('node:mouseenter', () => {
+		const container = document.getElementById('graph-container')!
+		const ports = container.querySelectorAll(
+			'.x6-port-body'
+		) as NodeListOf<SVGElement>
+		showPorts(ports, true)
+	})
+	graph.on('node:mouseleave', () => {
+		const container = document.getElementById('graph-container')!
+		const ports = container.querySelectorAll(
+			'.x6-port-body'
+		) as NodeListOf<SVGElement>
+		showPorts(ports, false)
+	})
+	// #endregion
+
+	// #region 初始化图形
+	const ports = {
+		groups: {
+			top: {
+				position: 'top',
+				attrs: {
+					circle: {
+						r: 4,
+						magnet: true,
+						stroke: '#5F95FF',
+						strokeWidth: 1,
+						fill: '#fff',
+						style: {
+							visibility: 'hidden',
+						},
+					},
+				},
+			},
+			right: {
+				position: 'right',
+				attrs: {
+					circle: {
+						r: 4,
+						magnet: true,
+						stroke: '#5F95FF',
+						strokeWidth: 1,
+						fill: '#fff',
+						style: {
+							visibility: 'hidden',
+						},
+					},
+				},
+			},
+			bottom: {
+				position: 'bottom',
+				attrs: {
+					circle: {
+						r: 4,
+						magnet: true,
+						stroke: '#5F95FF',
+						strokeWidth: 1,
+						fill: '#fff',
+						style: {
+							visibility: 'hidden',
+						},
+					},
+				},
+			},
+			left: {
+				position: 'left',
+				attrs: {
+					circle: {
+						r: 4,
+						magnet: true,
+						stroke: '#5F95FF',
+						strokeWidth: 1,
+						fill: '#fff',
+						style: {
+							visibility: 'hidden',
+						},
+					},
+				},
+			},
+		},
+		items: [
+			{
+				group: 'top',
+			},
+			{
+				group: 'right',
+			},
+			{
+				group: 'bottom',
+			},
+			{
+				group: 'left',
+			},
+		],
+	}
+	Graph.registerNode(
+		'custom-rect',
+		{
+			inherit: 'rect',
+			width: 66,
+			height: 36,
+			attrs: {
+				body: {
+					strokeWidth: 1,
+					stroke: '#5F95FF',
+					fill: '#EFF4FF',
+				},
+				text: {
+					fontSize: 12,
+					fill: '#262626',
+				},
+			},
+			ports: { ...ports },
+		},
+		true
+	)
+
+	Graph.registerNode(
+		'custom-polygon',
+		{
+			inherit: 'polygon',
+			width: 66,
+			height: 36,
+			attrs: {
+				body: {
+					strokeWidth: 1,
+					stroke: '#5F95FF',
+					fill: '#EFF4FF',
+				},
+				text: {
+					fontSize: 12,
+					fill: '#262626',
+				},
+			},
+			ports: {
+				...ports,
+				items: [
+					{
+						group: 'top',
+					},
+					{
+						group: 'bottom',
+					},
+				],
+			},
+		},
+		true
+	)
+
+	Graph.registerNode(
+		'custom-circle',
+		{
+			inherit: 'circle',
+			width: 45,
+			height: 45,
+			attrs: {
+				body: {
+					strokeWidth: 1,
+					stroke: '#5F95FF',
+					fill: '#EFF4FF',
+				},
+				text: {
+					fontSize: 12,
+					fill: '#262626',
+				},
+			},
+			ports: { ...ports },
+		},
+		true
+	)
+
+	Graph.registerNode(
+		'custom-image',
+		{
+			inherit: 'rect',
+			width: 52,
+			height: 52,
+			markup: [
+				{
+					tagName: 'rect',
+					selector: 'body',
+				},
+				{
+					tagName: 'image',
+				},
+				{
+					tagName: 'text',
+					selector: 'label',
+				},
+			],
+			attrs: {
+				body: {
+					stroke: '#5F95FF',
+					fill: '#5F95FF',
+				},
+				image: {
+					width: 26,
+					height: 26,
+					refX: 13,
+					refY: 16,
+				},
+				label: {
+					refX: 3,
+					refY: 2,
+					textAnchor: 'left',
+					textVerticalAnchor: 'top',
+					fontSize: 12,
+					fill: '#fff',
+				},
+			},
+			ports: { ...ports },
+		},
+		true
+	)
+	const r1 = graph.createNode({
+		shape: 'custom-rect',
+		label: '开始',
+		attrs: {
+			body: {
+				rx: 20,
+				ry: 26,
+			},
+		},
+	})
+	const r2 = graph.createNode({
+		shape: 'custom-rect',
+		label: '办理',
+	})
+	const r3 = graph.createNode({
+		shape: 'custom-rect',
+		attrs: {
+			body: {
+				rx: 6,
+				ry: 6,
+			},
+		},
+		label: '分支',
+	})
+	const r4 = graph.createNode({
+		shape: 'custom-polygon',
+		attrs: {
+			body: {
+				refPoints: '0,10 10,0 20,10 10,20',
+			},
+		},
+		label: '结束',
+	})
+	stencil.load([r1, r2, r3, r4], 'group1')
+
+	
+	
+}
+onMounted(() => {
+	antvInit()
+})
+</script>
+<style lang="scss">
+.vueFlow {
+	position: relative;
+	display: flex;
+	justify-content: space-between;
+	#stencil {
+		position: absolute;
+		top: 0;
+		left: 0;
+		z-index: 100;
+		width: 200px;
+		height: 500px;
+		background: #fff;
+		border-right: 1px solid #e8e8e8;
+	}
+	#container {
+		height: 800px;
+		width: 800px;
+	}
+	#graph-container{
+		width: 100%;
+		position: absolute;
+		right: 0;
+		top: 0;
+	}
+}
+</style>

+ 107 - 0
src/views/WDLY/process/processConfig/vueFlow2.vue

@@ -0,0 +1,107 @@
+<style lang="scss" scoped>
+.container{
+    height: 100%;
+}
+.my-flow {
+	margin: 10px;
+	height: 700px;
+
+	//   :deep(.node-light) {
+	//     background: none;
+	//   }
+	//   :deep(.node-dark) {
+	//     background: #eeeeee;
+	//   }
+}
+</style>
+<template>
+	<div class="container">
+		<el-row class="mb-4">
+			<el-button type="primary" @click="resetTransform">重置</el-button>
+		</el-row>
+
+		<VueFlow
+			fit-view-on-init
+			class="my-flow"
+			v-model="elements"
+		>
+			<Background />
+			<Panel :position="PanelPosition.TopRight">
+                <button type="button" @click="addRandomNode('办理')">办理</button>
+                <button type="button" style="margin-left:10px" @click="addRandomNode('分支')">分支</button>
+                <button type="button" style="margin-left:10px" @click="addRandomNode('结束')">结束</button>
+            </Panel>
+			<!-- <Controls /> -->
+		</VueFlow>
+	</div>
+</template>
+ 
+ 
+<script lang="ts" setup name="DemoBpmn">
+import '@vue-flow/core/dist/style.css'
+/* import the default theme (optional) */
+import '@vue-flow/core/dist/theme-default.css'
+
+import {
+	Background,
+	Panel,
+	PanelPosition,
+	Controls,
+} from '@vue-flow/additional-components'
+import { VueFlow, useVueFlow } from '@vue-flow/core'
+import { ref, watch } from 'vue'
+import { ElMessage } from 'element-plus'
+
+const data = [
+	{ id: '1', type: 'input', label: '开始', position: { x: 250, y: 5 } },
+	
+]
+let elements = ref(data)
+
+const isHidden = ref(false)
+
+let {
+	onPaneReady,
+	onNodeDragStop,
+	onConnect,
+	addEdges,
+	setTransform,
+	toObject,
+	nodes,
+	edges,
+    applyNodeChanges,
+    dimensions,
+    addNodes
+} = useVueFlow()
+
+function addRandomNode(_name) {
+  const nodeId = (nodes.value.length + 1).toString()
+
+  const newNode = {
+    id: nodeId,
+    label: _name,
+    position: { x: 250, y: 100 }
+  }
+
+  addNodes([newNode])
+}
+
+watch(isHidden, () => {
+	nodes.value.forEach((n) => (n.hidden = isHidden.value))
+	edges.value.forEach((e) => (e.hidden = isHidden.value))
+})
+
+onPaneReady(({ fitView }) => {
+	fitView()
+})
+onNodeDragStop((e) => {
+    
+    console.log(e.node)
+})
+onConnect((params) => addEdges([params]))
+
+const resetTransform = () => {
+	elements.value = data
+	setTransform({ x: 0, y: 0, zoom: 1 })
+}
+</script>

+ 497 - 0
src/views/WDLY/purchaseManage/alreadyPurchase/index.vue

@@ -0,0 +1,497 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+        }"
+        :action-list="[]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      title="到货通知"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <el-form
+        :model="formData.data"
+        :rules="rules"
+        ref="formDom"
+        label-position="top"
+      >
+        <div style="margin-bottom: 10px; font-size: 14px">基础信息</div>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="供应商" prop="supplyId">
+              <el-select
+                v-model="formData.data.supplyId"
+                placeholder="请选择"
+                style="width: 100%"
+                disabled
+              >
+                <el-option
+                  v-for="item in supplierData"
+                  :label="item.name"
+                  :value="item.id"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="6">
+            <el-form-item label="采购单号" prop="code">
+              <el-input
+                v-model="formData.data.code"
+                placeholder="请输入"
+                disabled
+              >
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <div style="margin-bottom: 10px; font-size: 14px">到货明细</div>
+        <el-form-item>
+          <el-table :data="formData.data.arrivalDetailList">
+            <el-table-column
+              prop="goodType"
+              label="货品类型"
+              :formatter="(row) => (row.goodType == 1 ? '产品' : '物料')"
+            />
+            <el-table-column prop="productCode" label="货品编码" />
+            <el-table-column prop="productName" label="货品名称" />
+            <el-table-column prop="productSpec" label="规格型号" />
+            <el-table-column prop="productUnit" label="单位" />
+            <el-table-column prop="purchaseCount" label="采购数量" />
+            <el-table-column prop="sumArrivalCount" label="已到货" />
+            <el-table-column prop="count" label="本次到货" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'arrivalDetailList.' + $index + '.count'"
+                  :rules="rules.count"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.count"
+                    :precision="4"
+                    :controls="false"
+                    :min="0"
+                    @change="handleChangeAmount"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+      </el-form>
+
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+let dialogVisible = ref(false);
+let modalType = ref("add");
+let rules = ref({
+  count: [{ required: true, message: "请输入本次到货", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "采购状态",
+    prop: "purchaseStatus",
+    data: [
+      {
+        label: "审批中",
+        value: "10",
+      },
+      {
+        label: "已驳回",
+        value: "20",
+      },
+      {
+        label: "已采购",
+        value: "30",
+      },
+    ],
+  },
+  {
+    label: "到货状态",
+    prop: "arrivalStatus",
+    data: [
+      {
+        label: "未到货",
+        value: "0",
+      },
+      {
+        label: "部分到货",
+        value: "10",
+      },
+      {
+        label: "已到货",
+        value: "20",
+      },
+    ],
+  },
+  {
+    label: "付款状态",
+    prop: "payStatus",
+    data: [
+      {
+        label: "未付款",
+        value: "1",
+      },
+      {
+        label: "部分付款",
+        value: "2",
+      },
+      {
+        label: "已付款",
+        value: "3",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "采购单号",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "供应商",
+        prop: "supplyName",
+      },
+    },
+    {
+      attrs: {
+        label: "收获仓库",
+        prop: "supplyName",
+      },
+    },
+    {
+      attrs: {
+        label: "采购金额",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "采购人",
+        prop: "purchaseName",
+      },
+    },
+    {
+      attrs: {
+        label: "采购时间",
+        prop: "createTime",
+      },
+    },
+    {
+      attrs: {
+        label: "采购状态",
+        prop: "purchaseStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "到货状态",
+        prop: "arrivalStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "付款状态",
+        prop: "payStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "240",
+        align: "right",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "发货通知",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handleArrival(row);
+            },
+          },
+          {
+            attrs: {
+              label: "到货通知",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handleArrival(row);
+            },
+          },
+          {
+            attrs: {
+              label: "作废",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handleEdit(row, 88);
+            },
+          },
+          {
+            attrs: {
+              label: "终止",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handleEdit(row, 99);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    type: "1",
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formDom = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "radio",
+      prop: "name",
+      label: "供应商类型",
+      required: true,
+      border: true,
+      data: [
+        { label: "贸易商", value: "1" },
+        { label: "工厂", value: "2" },
+      ],
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "供应商名称",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "address",
+      label: "地址",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "contact",
+      label: "联系信息",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "fileSlot",
+      label: "上传附件",
+    },
+    {
+      type: "input",
+      label: "备注",
+      prop: "remakes",
+      itemType: "textarea",
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post("/purchase/page", sourceList.value.pagination).then((message) => {
+    console.log(message);
+    sourceList.value.data = message.rows;
+    sourceList.value.pagination.total = message.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+
+const submitForm = async () => {
+  formDom.value.validate((vaild) => {
+    if (vaild) {
+      const list = formData.data.arrivalDetailList;
+      const total = list.reduce((total, x) => (total += Number(x.count)));
+      if (total < 1) {
+        return ElMessage({
+          message: `本次到货不能为0!`,
+          type: "info",
+        });
+      }
+      let sum = 0;
+      for (let i = 0; i < list.length; i++) {
+        const e = list[i];
+        if (
+          Number(e.sumArrivalCount) + Number(e.count) >=
+          Number(e.purchaseCount)
+        ) {
+          sum += 1;
+        }
+      }
+      formData.data.arrivalStatus = sum === list.length ? "20" : "10";
+      proxy.post("/arrival/add", formData.data).then((res) => {
+        ElMessage({
+          message: `操作成功!`,
+          type: "success",
+        });
+        dialogVisible.value = true;
+        getList();
+      });
+    }
+  });
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+
+const handleEdit = (row, status) => {
+  let purchaseStatusName = status == 88 ? "作废" : "终止";
+  const data = { ...row, purchaseStatus: status };
+  // 弹窗提示是否删除
+  ElMessageBox.confirm(
+    `此操作将${purchaseStatusName}该数据, 是否继续?`,
+    "提示",
+    {
+      confirmButtonText: "确定",
+      cancelButtonText: "取消",
+      type: "warning",
+    }
+  ).then(() => {
+    // 删除
+    proxy
+      .post("/purchase/edit", {
+        data,
+      })
+      .then((res) => {
+        ElMessage({
+          message: `${purchaseStatusName}成功`,
+          type: "success",
+        });
+        getList();
+      });
+  });
+};
+
+// 获取供应商数据
+const supplierData = ref([]);
+const getSupplierList = async (req) => {
+  proxy
+    .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      supplierData.value = res.rows;
+    });
+};
+const handleArrival = (row) => {
+  proxy.post("/purchase/detail", { id: row.id }).then((res) => {
+    formData.data = {
+      purchaseId: row.id,
+      code: res.code,
+      supplyId: res.supplyId,
+      arrivalDetailList: res.purchaseDetailList.map((x) => ({
+        ...x,
+        purchaseDetailId: x.id,
+        purchaseCount: x.count,
+        count: 0,
+      })),
+      arrivalStatus: "",
+    };
+    dialogVisible.value = true;
+  });
+};
+
+getList();
+getSupplierList();
+const start = () => {
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      isSubscribe: "20",
+      ids: "",
+    },
+  });
+};
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 478 - 0
src/views/WDLY/purchaseManage/arrival/index.vue

@@ -0,0 +1,478 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+          select: selectRow,
+        }"
+        :action-list="[
+          {
+            text: '质检',
+            disabled: selectData.length === 0,
+            action: () => start(20),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      title="到货质检"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <el-form
+        :model="formData.data"
+        :rules="rules"
+        ref="formDom"
+        label-position="top"
+      >
+        <div style="margin-bottom: 10px; font-size: 14px">基础信息</div>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="供应商" prop="supplyId">
+              <el-select
+                v-model="formData.data.supplyId"
+                placeholder="请选择"
+                style="width: 100%"
+                disabled
+              >
+                <el-option
+                  v-for="item in supplierData"
+                  :label="item.name"
+                  :value="item.id"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="6">
+            <el-form-item label="采购单号" prop="code">
+              <el-input
+                v-model="formData.data.code"
+                placeholder="请输入"
+                disabled
+              >
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <div style="margin-bottom: 10px; font-size: 14px">到货明细</div>
+        <el-form-item>
+          <el-table :data="formData.data.qualityDetailList">
+            <el-table-column
+              prop="productType"
+              label="货品类型"
+              :formatter="(row) => (row.productType == 1 ? '产品' : '物料')"
+            />
+            <el-table-column prop="productCode" label="货品编码" />
+            <el-table-column prop="productName" label="货品名称" />
+            <el-table-column prop="productSpec" label="规格型号" />
+            <el-table-column prop="productUnit" label="单位" />
+            <el-table-column prop="count" label="到货数量" />
+            <el-table-column prop="sumQualityCount" label="已质检" />
+            <el-table-column
+              prop="qualifiedCount"
+              label="质检合格"
+              min-width="150"
+            >
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'qualityDetailList.' + $index + '.qualifiedCount'"
+                  :rules="rules.qualifiedCount"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.qualifiedCount"
+                    :precision="4"
+                    :controls="false"
+                    :min="0"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="noQualifiedCount"
+              label="质检不合格"
+              min-width="150"
+            >
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'qualityDetailList.' + $index + '.noQualifiedCount'"
+                  :rules="rules.noQualifiedCount"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.noQualifiedCount"
+                    :precision="4"
+                    :controls="false"
+                    :min="0"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import FileUpload from "@/components/FileUpload/index";
+import { computed, defineComponent, ref, watch } from "vue";
+import { getToken } from "@/utils/auth";
+
+const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const uploadData = ref({});
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+let dialogVisible = ref(false);
+let modalType = ref("add");
+let fileList = ref([]);
+let rules = ref({
+  name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
+  qualifiedCount: [
+    { required: true, message: "请输入质检合格数量", trigger: "blur" },
+  ],
+  noQualifiedCount: [
+    { required: true, message: "请输入质检不合格数量", trigger: "blur" },
+  ],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "质检状态",
+    prop: "status",
+    data: [
+      {
+        label: "未质检",
+        value: "0",
+      },
+      {
+        label: "部分质检",
+        value: "10",
+      },
+      {
+        label: "已质检",
+        value: "20",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      type: "selection",
+      attrs: {
+        checkAtt: "isCheck",
+      },
+    },
+    {
+      attrs: {
+        label: "到货单号",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "供应商",
+        prop: "supplyName",
+      },
+    },
+    {
+      attrs: {
+        label: "物品类型",
+        prop: "productType",
+      },
+      render(type) {
+        return type == 1 ? "产品" : type == 2 ? "物料" : "";
+      },
+    },
+
+    {
+      attrs: {
+        label: "物品编码",
+        prop: "productCode",
+      },
+    },
+    {
+      attrs: {
+        label: "物品名称",
+        prop: "productName",
+      },
+    },
+    {
+      attrs: {
+        label: "规格型号",
+        prop: "productSpec",
+      },
+    },
+    {
+      attrs: {
+        label: "单位",
+        prop: "productUnit",
+      },
+    },
+    {
+      attrs: {
+        label: "到货数量",
+        prop: "count",
+      },
+    },
+    {
+      attrs: {
+        label: "质检合格",
+        prop: "qualifiedCount",
+      },
+    },
+    {
+      attrs: {
+        label: "质检不合格",
+        prop: "noQualifiedCount",
+      },
+    },
+    {
+      attrs: {
+        label: "质检状态",
+        prop: "status",
+      },
+      render(type) {
+        return type == 0
+          ? "未质检"
+          : type == 10
+          ? "部分质检"
+          : type == 20
+          ? "已质检"
+          : "";
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "100",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "质检",
+              type: "primary",
+              text: true,
+              disabled: row.status == 20,
+            },
+            el: "button",
+            click() {
+              selectDataOne.value = [row];
+              start(10);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {});
+const formDom = ref(null);
+
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/arrivalDetail/page", sourceList.value.pagination)
+    .then((message) => {
+      message.rows.forEach((x) => {
+        if (x.status < 20) {
+          x.isCheck = true;
+        } else {
+          x.isCheck = false;
+        }
+      });
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+
+const submitForm = () => {
+  formDom.value.validate((valid) => {
+    const list = formData.data.qualityDetailList;
+    for (let i = 0; i < list.length; i++) {
+      const e = list[i];
+      if (!(e.qualifiedCount + e.noQualifiedCount > 0)) {
+        return ElMessage({
+          message: "质检数量不能为0!",
+          type: "info",
+        });
+      }
+      if (
+        e.qualifiedCount + e.noQualifiedCount + Number(e.sumQualityCount) >
+        Number(e.count)
+      ) {
+        return ElMessage({
+          message: "质检数量不能大于到货数量!",
+          type: "info",
+        });
+      }
+    }
+    submitLoading.value = true;
+    proxy.post("/quality/" + modalType.value, formData.data).then(
+      (res) => {
+        ElMessage({
+          message: "质检成功",
+          type: "success",
+        });
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      (err) => {
+        submitLoading.value = false;
+      }
+    );
+  });
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  dialogVisible.value = true;
+
+  // proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+  //   fileList.value = [
+  //     {
+  //       id: "",
+  //       fileName: res.fileName,
+  //       path: "",
+  //     },
+  //   ];
+  //   formData.data = res;
+  //   dialogVisible.value = true;
+  // });
+};
+
+getList();
+const selectData = ref([]);
+const selectDataOne = ref([]);
+
+const selectRow = (data) => {
+  selectData.value = data;
+};
+
+const start = (type) => {
+  modalType.value = "add";
+  let ids = [];
+  let row = {};
+  if (type === 10) {
+    row = selectDataOne.value[0];
+    ids = selectDataOne.value.map((x) => x.id);
+  } else if (type === 20) {
+    ids = selectData.value.map((x) => x.id);
+    row = selectData.value[0];
+  }
+  proxy.post("/arrivalDetail/detail", { ids }).then((res) => {
+    formData.data = {
+      arrivalId: row.arrivalId,
+      supplyId: row.supplyId,
+      supplyName: row.supplyName,
+      code: row.code,
+      qualityDetailList: res.map((x) => ({
+        ...x,
+        arrivalDetailId: x.id,
+        qualifiedCount: 0,
+        noQualifiedCount: 0,
+      })),
+    };
+    dialogVisible.value = true;
+  });
+};
+
+watch(selectData, (newVal, oldVal) => {
+  if (newVal.length == 0) {
+    sourceList.value.data.forEach((x) => {
+      if (x.status < 20) {
+        x.isCheck = true;
+      } else {
+        x.isCheck = false;
+      }
+    });
+  } else if (newVal.length == 1) {
+    const current = newVal[0];
+    sourceList.value.data.forEach((x) => {
+      if (x.arrivalId !== current.arrivalId || x.status == 20) {
+        x.isCheck = false;
+      }
+    });
+  }
+});
+
+onMounted(() => {});
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::deep {
+}
+.el-checkbox {
+  display: none;
+}
+</style>

+ 503 - 0
src/views/WDLY/purchaseManage/purchase/index.vue

@@ -0,0 +1,503 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+          select: selectRow,
+          'select-all': selectRow,
+        }"
+        :action-list="[
+          {
+            text: '采购',
+            disabled: selectData.length === 0,
+            action: () => start(),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加供应商' : '编辑供应商'"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #address>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="国家">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="省/洲">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="城市">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="24">
+              <el-input v-model="formData.data.bb" type="textarea"> </el-input>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #contact>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-input v-model="formData.data.aa" placeholder="联系人">
+              </el-input>
+            </el-col>
+            <el-col :span="16">
+              <el-input v-model="formData.data.aa" placeholder="联系电话">
+              </el-input>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #fileSlot>
+          <div>
+            <el-upload
+              v-model:fileList="fileList"
+              class="upload-demo"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :limit="3"
+              :data="uploadData"
+              :on-preview="handlePreview"
+              :on-remove="handleRemove"
+              :on-success="handleSuccess"
+              :before-upload="handleBeforeUpload"
+              accept=".pdf"
+            >
+              <el-button type="primary">选择</el-button>
+              <template #file>
+                <div>
+                  <div style="margin-top: 15px">
+                    <el-tag
+                      class="ml-2"
+                      type="info"
+                      v-for="(item, index) in fileList"
+                      :key="index"
+                      closable
+                      @close="handleClose(index)"
+                      >{{ item.fileName }}</el-tag
+                    >
+                  </div>
+                </div>
+              </template>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import FileUpload from "@/components/FileUpload/index";
+import { computed, defineComponent, ref } from "vue";
+import { getToken } from "@/utils/auth";
+
+const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const uploadData = ref({});
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    status: "15",
+  },
+});
+let dialogVisible = ref(false);
+let modalType = ref("add");
+let fileList = ref([]);
+let rules = ref({
+  name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "状态",
+    prop: "status",
+    data: [
+      {
+        label: "待采购",
+        value: "15",
+      },
+      {
+        label: "部分采购",
+        value: "30",
+      },
+    ],
+  },
+  // {
+  //   label: "收获仓库",
+  //   prop: "status",
+  //   data: [
+  //     {
+  //       label: "待采购",
+  //       value: "15",
+  //     },
+  //     {
+  //       label: "部分采购",
+  //       value: "30",
+  //     },
+  //   ],
+  // },
+]);
+const config = computed(() => {
+  return [
+    {
+      type: "selection",
+    },
+    {
+      attrs: {
+        label: "申购单号",
+        prop: "subscribeCode",
+      },
+    },
+    {
+      attrs: {
+        label: "物品类型",
+        prop: "productType",
+      },
+      render(productType) {
+        return productType == 1 ? "产品" : "物料";
+      },
+    },
+
+    {
+      attrs: {
+        label: "物品编码",
+        prop: "productCode",
+      },
+    },
+    {
+      attrs: {
+        label: "物品名称",
+        prop: "productName",
+      },
+    },
+    {
+      attrs: {
+        label: "规格",
+        prop: "productSpec",
+      },
+    },
+    {
+      attrs: {
+        label: "单位",
+        prop: "productUnit",
+      },
+    },
+    {
+      attrs: {
+        label: "申购数量",
+        prop: "count",
+      },
+    },
+    {
+      attrs: {
+        label: "已采购数量",
+        prop: "purchaseCount",
+      },
+    },
+    {
+      attrs: {
+        label: "收获仓库",
+        prop: "receiptWarehouseName",
+      },
+    },
+    {
+      attrs: {
+        label: "要求到货时间",
+        prop: "planArrivalTime",
+      },
+    },
+    {
+      attrs: {
+        label: "采购状态",
+        prop: "status",
+      },
+      render(status) {
+        return status == 15 ? "待采购" : "部分采购";
+      },
+    },
+    {
+      attrs: {
+        label: "申购人",
+        prop: "subcribeName",
+      },
+    },
+    {
+      attrs: {
+        label: "申购时间",
+        prop: "subcribeTime",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "200",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "采购",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              selectData.value = [row];
+              start();
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    type: "1",
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "radio",
+      prop: "name",
+      label: "供应商类型",
+      required: true,
+      border: true,
+      data: [
+        { label: "贸易商", value: "1" },
+        { label: "工厂", value: "2" },
+      ],
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "供应商名称",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "address",
+      label: "地址",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "contact",
+      label: "联系信息",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "fileSlot",
+      label: "上传附件",
+    },
+    {
+      type: "input",
+      label: "备注",
+      prop: "remakes",
+      itemType: "textarea",
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/subscribeDetail/pageByWdly", sourceList.value.pagination)
+    .then((message) => {
+      console.log(message);
+      sourceList.value.data = message.rows.map((x) => ({
+        ...x,
+        ...JSON.parse(x.victoriatouristJson),
+      }));
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+// const openModal = () => {
+//  proxy.$router.push({
+
+//  })
+// };
+
+const submitForm = () => {
+  if (fileList.value.length > 0) {
+    byform.value.handleSubmit((valid) => {
+      formData.data.fileList = fileList.value;
+      submitLoading.value = true;
+      proxy.post("/productionProcesses/" + modalType.value, formData.data).then(
+        (res) => {
+          ElMessage({
+            message: modalType.value == "add" ? "添加成功" : "编辑成功",
+            type: "success",
+          });
+          fileList.value = [];
+          dialogVisible.value = false;
+          submitLoading.value = false;
+          getList();
+        },
+        (err) => {
+          console.log(err, "aswwwww");
+          submitLoading.value = false;
+        }
+      );
+    });
+  } else {
+    return ElMessage({
+      message: "请上传附件!",
+      type: "info",
+    });
+  }
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+    fileList.value = [
+      {
+        id: "",
+        fileName: res.fileName,
+        path: "",
+      },
+    ];
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+const handleBeforeUpload = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  fileList.value = [
+    {
+      id: res.id,
+      fileName: res.fileName,
+      path: res.fileUrl,
+    },
+  ];
+};
+const handleClickFile = (row) => {
+  ElMessage({
+    message: "数据请求中,请稍后!",
+    type: "success",
+  });
+  let id = row.id;
+  proxy.post("/fileInfo/getList", { businessIdList: [id] }).then((res) => {
+    const file = res[id][0];
+    window.open(file.fileUrl, "_blank");
+  });
+};
+
+const handlePreview = (file) => {
+  console.log(file);
+};
+const handleSuccess = (file) => {
+  console.log(file);
+};
+const handleRemove = (file) => {
+  fileList.value = [];
+};
+const handleClose = (index) => {
+  fileList.value.splice(index, 1);
+};
+getList();
+const selectData = ref([]);
+const selectRow = (data) => {
+  selectData.value = data;
+};
+
+const start = () => {
+  if (selectData.value.length > 0) {
+    let ids = selectData.value.map((x) => x.id).join();
+    proxy.$router.replace({
+      path: "/WDLY/process/processApproval_wdly",
+      query: {
+        flowKey: "purchase_flow",
+        ids,
+      },
+    });
+  } else {
+    return ElMessage({
+      message: "请勾选数据!",
+      type: "info",
+    });
+  }
+};
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 479 - 0
src/views/WDLY/purchaseManage/returnGoods/index.vue

@@ -0,0 +1,479 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+        }"
+        :action-list="[
+          {
+            text: '添加退货',
+            action: () => start(),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      title="到货通知"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <el-form
+        :model="formData.data"
+        :rules="rules"
+        ref="formDom"
+        label-position="top"
+      >
+        <div style="margin-bottom: 10px; font-size: 14px">基础信息</div>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="供应商" prop="supplyId">
+              <el-select
+                v-model="formData.data.supplyId"
+                placeholder="请选择"
+                style="width: 100%"
+                disabled
+              >
+                <el-option
+                  v-for="item in supplierData"
+                  :label="item.name"
+                  :value="item.id"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="6">
+            <el-form-item label="采购单号" prop="code">
+              <el-input
+                v-model="formData.data.code"
+                placeholder="请输入"
+                disabled
+              >
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <div style="margin-bottom: 10px; font-size: 14px">到货明细</div>
+        <el-form-item>
+          <el-table :data="formData.data.arrivalDetailList">
+            <el-table-column
+              prop="goodType"
+              label="货品类型"
+              :formatter="(row) => (row.goodType == 1 ? '产品' : '物料')"
+            />
+            <el-table-column prop="productCode" label="货品编码" />
+            <el-table-column prop="productName" label="货品名称" />
+            <el-table-column prop="productSpec" label="规格型号" />
+            <el-table-column prop="productUnit" label="单位" />
+            <el-table-column prop="purchaseCount" label="采购数量" />
+            <el-table-column prop="sumArrivalCount" label="已到货" />
+            <el-table-column prop="count" label="本次到货" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'arrivalDetailList.' + $index + '.count'"
+                  :rules="rules.count"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.count"
+                    :precision="4"
+                    :controls="false"
+                    :min="0"
+                    @change="handleChangeAmount"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+      </el-form>
+
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+let dialogVisible = ref(false);
+let modalType = ref("add");
+let rules = ref({
+  count: [{ required: true, message: "请输入本次到货", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "退货状态",
+    prop: "status",
+    data: [
+      {
+        label: "审批中",
+        value: "10",
+      },
+      {
+        label: "驳回",
+        value: "20",
+      },
+      {
+        label: "待退货",
+        value: "30",
+      },
+    ],
+  },
+  {
+    label: "到货状态",
+    prop: "arrivalStatus",
+    data: [
+      {
+        label: "未到货",
+        value: "0",
+      },
+      {
+        label: "部分到货",
+        value: "10",
+      },
+      {
+        label: "已到货",
+        value: "20",
+      },
+    ],
+  },
+  {
+    label: "付款状态",
+    prop: "payStatus",
+    data: [
+      {
+        label: "未付款",
+        value: "1",
+      },
+      {
+        label: "部分付款",
+        value: "2",
+      },
+      {
+        label: "已付款",
+        value: "3",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "退货单号",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "供应商",
+        prop: "supplyName",
+      },
+    },
+
+    {
+      attrs: {
+        label: "物品编码",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "物品名称",
+        prop: "purchaseName",
+      },
+    },
+    {
+      attrs: {
+        label: "单位",
+        prop: "createTime",
+      },
+    },
+    {
+      attrs: {
+        label: "退货数量",
+        prop: "purchaseStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "退货状态",
+        prop: "arrivalStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "退款状态",
+        prop: "payStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "操作人",
+        prop: "payStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "操作时间",
+        prop: "payStatus",
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "100",
+        align: "right",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "结束",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handleEdit(row, 99);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    type: "1",
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formDom = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "radio",
+      prop: "name",
+      label: "供应商类型",
+      required: true,
+      border: true,
+      data: [
+        { label: "贸易商", value: "1" },
+        { label: "工厂", value: "2" },
+      ],
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "供应商名称",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "address",
+      label: "地址",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "contact",
+      label: "联系信息",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "fileSlot",
+      label: "上传附件",
+    },
+    {
+      type: "input",
+      label: "备注",
+      prop: "remakes",
+      itemType: "textarea",
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/salesReturnDetail/page", sourceList.value.pagination)
+    .then((message) => {
+      console.log(message);
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+
+const submitForm = async () => {
+  formDom.value.validate((vaild) => {
+    if (vaild) {
+      const list = formData.data.arrivalDetailList;
+      const total = list.reduce((total, x) => (total += Number(x.count)));
+      if (total < 1) {
+        return ElMessage({
+          message: `本次到货不能为0!`,
+          type: "info",
+        });
+      }
+      let sum = 0;
+      for (let i = 0; i < list.length; i++) {
+        const e = list[i];
+        if (
+          Number(e.sumArrivalCount) + Number(e.count) >=
+          Number(e.purchaseCount)
+        ) {
+          sum += 1;
+        }
+      }
+      formData.data.arrivalStatus = sum === list.length ? "20" : "10";
+      proxy.post("/arrival/add", formData.data).then((res) => {
+        ElMessage({
+          message: `操作成功!`,
+          type: "success",
+        });
+        dialogVisible.value = true;
+        getList();
+      });
+    }
+  });
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+
+const handleEdit = (row, status) => {
+  let purchaseStatusName = status == 88 ? "作废" : "终止";
+  const data = { ...row, purchaseStatus: status };
+  // 弹窗提示是否删除
+  ElMessageBox.confirm(
+    `此操作将${purchaseStatusName}该数据, 是否继续?`,
+    "提示",
+    {
+      confirmButtonText: "确定",
+      cancelButtonText: "取消",
+      type: "warning",
+    }
+  ).then(() => {
+    // 删除
+    proxy
+      .post("/purchase/edit", {
+        data,
+      })
+      .then((res) => {
+        ElMessage({
+          message: `${purchaseStatusName}成功`,
+          type: "success",
+        });
+        getList();
+      });
+  });
+};
+
+// 获取供应商数据
+const supplierData = ref([]);
+const getSupplierList = async (req) => {
+  proxy
+    .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      supplierData.value = res.rows;
+    });
+};
+const handleArrival = (row) => {
+  proxy.post("/purchase/detail", { id: row.id }).then((res) => {
+    formData.data = {
+      purchaseId: row.id,
+      code: res.code,
+      supplyId: res.supplyId,
+      arrivalDetailList: res.purchaseDetailList.map((x) => ({
+        ...x,
+        purchaseDetailId: x.id,
+        purchaseCount: x.count,
+        count: 0,
+      })),
+      arrivalStatus: "",
+    };
+    dialogVisible.value = true;
+  });
+};
+
+getList();
+getSupplierList();
+const start = () => {
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      isSubscribe: "40",
+      ids: "",
+    },
+  });
+};
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 521 - 0
src/views/WDLY/purchaseManage/subscribe/index.vue

@@ -0,0 +1,521 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+          select: select,
+        }"
+        :action-list="[
+          {
+            text: '发起申购',
+            action: () => openModal(),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加供应商' : '编辑供应商'"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #address>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="国家">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="省/洲">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="城市">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="24">
+              <el-input v-model="formData.data.bb" type="textarea"> </el-input>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #contact>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-input v-model="formData.data.aa" placeholder="联系人">
+              </el-input>
+            </el-col>
+            <el-col :span="16">
+              <el-input v-model="formData.data.aa" placeholder="联系电话">
+              </el-input>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #fileSlot>
+          <div>
+            <el-upload
+              v-model:fileList="fileList"
+              class="upload-demo"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :limit="3"
+              :data="uploadData"
+              :on-preview="handlePreview"
+              :on-remove="handleRemove"
+              :on-success="handleSuccess"
+              :before-upload="handleBeforeUpload"
+              accept=".pdf"
+            >
+              <el-button type="primary">选择</el-button>
+              <template #file>
+                <div>
+                  <div style="margin-top: 15px">
+                    <el-tag
+                      class="ml-2"
+                      type="info"
+                      v-for="(item, index) in fileList"
+                      :key="index"
+                      closable
+                      @close="handleClose(index)"
+                      >{{ item.fileName }}</el-tag
+                    >
+                  </div>
+                </div>
+              </template>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import FileUpload from "@/components/FileUpload/index";
+import { computed, defineComponent, ref } from "vue";
+import { getToken } from "@/utils/auth";
+
+const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const uploadData = ref({});
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    status: "",
+  },
+});
+let dialogVisible = ref(false);
+let modalType = ref("add");
+let fileList = ref([]);
+let rules = ref({
+  name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "货品类型",
+    prop: "productType",
+    data: [
+      {
+        label: "产品",
+        value: "1",
+      },
+      {
+        label: "物料",
+        value: "2",
+      },
+    ],
+  },
+  {
+    label: "状态",
+    prop: "status",
+    data: [],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "申购单号",
+        prop: "subscribeCode",
+      },
+    },
+    {
+      attrs: {
+        label: "货品类型",
+        prop: "productType",
+      },
+      render(productType) {
+        return productType == 1 ? "产品" : "物料";
+      },
+    },
+    {
+      attrs: {
+        label: "所属分类",
+        prop: "productCategory",
+      },
+    },
+    {
+      attrs: {
+        label: "货品编码",
+        prop: "productCode",
+      },
+    },
+    {
+      attrs: {
+        label: "货品名称",
+        prop: "productName",
+      },
+    },
+    {
+      attrs: {
+        label: "单位",
+        prop: "productUnit",
+      },
+    },
+
+    {
+      attrs: {
+        label: "申购数量",
+        prop: "count",
+      },
+    },
+    {
+      attrs: {
+        label: "收货仓库",
+        prop: "receiptWarehouseId",
+      },
+    },
+    {
+      attrs: {
+        label: "要求到货时间",
+        prop: "planArrivalTime",
+      },
+    },
+    {
+      attrs: {
+        label: "申购时间",
+        prop: "createTime",
+      },
+    },
+    {
+      attrs: {
+        label: "状态",
+        prop: "status",
+      },
+      render(status) {
+        return statusData.value.find((x) => x.value == status).label;
+      },
+    },
+    {
+      attrs: {
+        label: "申购原因",
+        prop: "subscribeContent",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "200",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          // {
+          //   attrs: {
+          //     label: "修改",
+          //     type: "primary",
+          //     text: true,
+          //   },
+          //   el: "button",
+          //   click() {
+          //     getDtl(row);
+          //   },
+          // },
+          {
+            attrs: {
+              label: "作废",
+              type: "danger",
+              text: true,
+            },
+            el: "button",
+            click() {
+              // 弹窗提示是否删除
+              ElMessageBox.confirm(
+                "此操作将永久作废该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
+                // 删除
+                proxy
+                  .post("/subscribeDetail/edit", {
+                    ...row,
+                    status: 99,
+                  })
+                  .then((res) => {
+                    ElMessage({
+                      message: "作废成功",
+                      type: "success",
+                    });
+                    getList();
+                  });
+              });
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    type: "1",
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "radio",
+      prop: "name",
+      label: "供应商类型",
+      required: true,
+      border: true,
+      data: [
+        { label: "贸易商", value: "1" },
+        { label: "工厂", value: "2" },
+      ],
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "供应商名称",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "address",
+      label: "地址",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "contact",
+      label: "联系信息",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "fileSlot",
+      label: "上传附件",
+    },
+    {
+      type: "input",
+      label: "备注",
+      prop: "remakes",
+      itemType: "textarea",
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/subscribeDetail/page", sourceList.value.pagination)
+    .then((message) => {
+      console.log(message);
+      sourceList.value.data = message.rows.map((x) => ({
+        ...x,
+        ...JSON.parse(x.victoriatouristJson),
+      }));
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+
+const openModal = () => {
+  proxy.$router.replace({
+    path: "/WDLY/process/processApproval_wdly",
+    query: {
+      flowKey: "subscribe_flow",
+    },
+  });
+};
+
+const submitForm = () => {
+  if (fileList.value.length > 0) {
+    byform.value.handleSubmit((valid) => {
+      formData.data.fileList = fileList.value;
+      submitLoading.value = true;
+      proxy.post("/productionProcesses/" + modalType.value, formData.data).then(
+        (res) => {
+          ElMessage({
+            message: modalType.value == "add" ? "添加成功" : "编辑成功",
+            type: "success",
+          });
+          fileList.value = [];
+          dialogVisible.value = false;
+          submitLoading.value = false;
+          getList();
+        },
+        (err) => {
+          console.log(err, "aswwwww");
+          submitLoading.value = false;
+        }
+      );
+    });
+  } else {
+    return ElMessage({
+      message: "请上传附件!",
+      type: "info",
+    });
+  }
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+    fileList.value = [
+      {
+        id: "",
+        fileName: res.fileName,
+        path: "",
+      },
+    ];
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+const handleBeforeUpload = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  fileList.value = [
+    {
+      id: res.id,
+      fileName: res.fileName,
+      path: res.fileUrl,
+    },
+  ];
+};
+const handleClickFile = (row) => {
+  ElMessage({
+    message: "数据请求中,请稍后!",
+    type: "success",
+  });
+  let id = row.id;
+  proxy.post("/fileInfo/getList", { businessIdList: [id] }).then((res) => {
+    const file = res[id][0];
+    window.open(file.fileUrl, "_blank");
+  });
+};
+
+const handlePreview = (file) => {
+  console.log(file);
+};
+const handleSuccess = (file) => {
+  console.log(file);
+};
+const handleRemove = (file) => {
+  fileList.value = [];
+};
+const handleClose = (index) => {
+  fileList.value.splice(index, 1);
+};
+const statusData = ref([
+  {
+    label: "审批中",
+    value: "10",
+  },
+  {
+    label: "待采购",
+    value: "15",
+  },
+  {
+    label: "部分采购",
+    value: "30",
+  },
+  {
+    label: "已采购",
+    value: "20",
+  },
+  {
+    label: "已作废",
+    value: "99",
+  },
+]);
+selectConfig[1].data = statusData.value;
+getList();
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 288 - 0
src/views/WDLY/stockManage/query/index.vue

@@ -0,0 +1,288 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+
+    <div style="background: #fff">
+      <el-tabs
+        v-model="activeName"
+        type="card"
+        class="demo-tabs"
+        @tab-change="handleChange"
+      >
+        <el-tab-pane label="按仓库" name="first"></el-tab-pane>
+        <el-tab-pane label="按产品" name="second"></el-tab-pane>
+      </el-tabs>
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+          select: select,
+        }"
+        :action-list="[]"
+        @get-list="getList"
+      >
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '良品转次品' : '次品转良品'"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import { computed, defineComponent, ref } from "vue";
+import useUserStore from "@/store/modules/user";
+import SelectProduct from "@/components/product/SelectProduct";
+
+const loading = ref(false);
+let activeName = ref("first");
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+let dialogVisible = ref(false);
+let openProduct = ref(false);
+
+let roomDialogVisible = ref(false);
+let modalType = ref("add");
+let rules = ref({
+  qualified: [{ required: true, message: "请输入数量", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  // {
+  //   label: "spu类型",
+  //   prop: "type",
+  //   data: [],
+  // },
+]);
+
+const config = reactive([
+  {
+    attrs: {
+      label: "仓库名称",
+      prop: "warehouseName",
+    },
+  },
+  {
+    attrs: {
+      label: "产品编码",
+      prop: "code",
+    },
+  },
+  {
+    attrs: {
+      label: "产品名称",
+      prop: "productName",
+    },
+  },
+  {
+    attrs: {
+      label: "规格",
+      prop: "spec",
+    },
+  },
+  {
+    attrs: {
+      label: "单位",
+      prop: "unit",
+    },
+  },
+  {
+    attrs: {
+      label: "可用库存",
+      prop: "quantity",
+    },
+  },
+  {
+    attrs: {
+      label: "冻结库存",
+      prop: "frozenQuantity",
+    },
+  },
+  {
+    attrs: {
+      label: "次品",
+      prop: "defectiveQuantity",
+    },
+  },
+  {
+    attrs: {
+      label: "操作",
+      width: "200",
+      align: "right",
+    },
+    // 渲染 el-button,一般用在最后一列。
+    renderHTML(row) {
+      return [
+        {
+          attrs: {
+            label: "良转次",
+            type: "primary",
+            text: true,
+          },
+          el: "button",
+          click() {
+            getDtl(row, "add");
+          },
+        },
+        {
+          attrs: {
+            label: "次转良",
+            type: "primary",
+            text: true,
+          },
+          el: "button",
+          click() {
+            getDtl(row, "edit");
+          },
+        },
+      ];
+    },
+  },
+]);
+
+let formData = reactive({
+  data: {},
+  treeData: [],
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+
+const formConfig = reactive([
+  {
+    type: "input",
+    prop: "canSum",
+    label: "可转数量",
+    disabled: true,
+  },
+  {
+    type: "input",
+    prop: "qualified",
+    label: "数量",
+  },
+]);
+const byform = ref(null);
+
+let requestUrl = "/stock/pageByWarehouse";
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post(requestUrl, sourceList.value.pagination).then((message) => {
+    console.log(message);
+    sourceList.value.data = message.rows.map((x) => ({
+      ...x,
+      ...JSON.parse(x.victoriatouristJson),
+    }));
+    sourceList.value.pagination.total = message.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+
+const submitForm = () => {
+  let submitAddress =
+    modalType.value === "add"
+      ? "/stock/defectiveToQualified"
+      : "/stock/qualifiedToDefective";
+  byform.value.handleSubmit((valid) => {
+    if (Number(formData.data.qualified) > Number(formData.data.canSum)) {
+      return ElMessage({
+        message: "不可大于可转数量!",
+        type: "info",
+      });
+    }
+    submitLoading.value = true;
+    proxy.post(submitAddress, formData.data).then(
+      (res) => {
+        ElMessage({
+          message: "操作成功",
+          type: "success",
+        });
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      (err) => (submitLoading.value = false)
+    );
+  });
+};
+
+const getDtl = (row, type) => {
+  modalType.value = type;
+  let canSum = type === "add" ? row.quantity : row.defectiveQuantity;
+  formData.data = {
+    id: row.id,
+    canSum,
+    qualified: "",
+  };
+  dialogVisible.value = true;
+};
+
+getList();
+
+const handleChange = () => {
+  sourceList.value.pagination.pageNum = 1;
+  if (activeName.value === "first") {
+    requestUrl = "/stock/pageByWarehouse";
+    config.unshift({
+      attrs: {
+        label: "仓库名称",
+        prop: "warehouseName",
+      },
+    });
+  } else {
+    requestUrl = "/stock/pageByProduct";
+    config.shift();
+  }
+  getList();
+};
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 167 - 0
src/views/connect/E-mail/mail/com/left.vue

@@ -0,0 +1,167 @@
+<template>
+  <div class="left">
+    <div class="top">
+      <el-dropdown>
+        <span class="mail">
+          {{ selectMail.mailUser }}
+          <el-icon class="el-icon--right">
+            <arrow-down />
+          </el-icon>
+        </span>
+        <template #dropdown>
+          <el-dropdown-menu>
+            <el-dropdown-item
+              v-for="item in mailList"
+              :key="item.id"
+              @click="handleClickMail(item)"
+              >{{ item.mailUser }}</el-dropdown-item
+            >
+          </el-dropdown-menu>
+        </template>
+      </el-dropdown>
+      <el-tabs v-model="activeName" class="demo-tabs" stretch>
+        <el-tab-pane label="邮箱" name="first">
+          <template #label>
+            <span>邮箱</span>
+          </template>
+        </el-tab-pane>
+        <el-tab-pane label="联系人" name="second">
+          <template #label>
+            <span>联系人</span>
+          </template>
+        </el-tab-pane>
+        <el-tab-pane label="客户" name="third">
+          <template #label>
+            <span>客户</span>
+          </template>
+        </el-tab-pane>
+      </el-tabs>
+      <div>
+        <el-button type="primary" style="width: 100%" @click="handleGoWrite"
+          >写信</el-button
+        >
+      </div>
+    </div>
+    <div class="body">
+      <div v-if="activeName === 'first'">
+        <ul class="mail-menu">
+          <li
+            class="menu-item"
+            v-bind:class="{ 'select-menu': item.id === selectFloderId }"
+            v-for="item in selectMail.mailFolderInfoList"
+            :key="item.id"
+            @click="handleOpenMenu(item)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+      </div>
+      <div v-if="activeName === 'second'">b</div>
+      <div v-if="activeName === 'third'">c</div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import useMailStore from "@/store/modules/mail";
+const mailStore = useMailStore();
+const { proxy } = getCurrentInstance();
+let selectMail = ref({});
+let activeName = ref("first");
+let selectFloderId = ref("");
+const mailList = ref([]);
+const getMialList = () => {
+  proxy.get("/mailService/getUserEmailList").then((res) => {
+    mailList.value = res.data;
+    if (mailList.value.length) {
+      selectMail.value = mailList.value[0];
+      mailStore.selectMail = mailList.value[0];
+      if (selectMail.value.mailFolderInfoList.length > 0) {
+        handleOpenMenu(selectMail.value.mailFolderInfoList[0]);
+      }
+    }
+  });
+};
+
+const handleClickMail = (item) => {
+  selectMail.value = item;
+  mailStore.selectMail = item;
+};
+
+const handleOpenMenu = (item) => {
+  selectFloderId.value = item.id;
+  const menu = {
+    title: item.name,
+    type: selectMail.value.type,
+    folderId: item.id,
+    id: "floder" + "," + item.id,
+  };
+  const menuItem = mailStore.mailMenuList.find((x) => x.id === menu.id);
+  if (menuItem === undefined) {
+    mailStore.mailMenuList.push(menu);
+  }
+  mailStore.currentMenu = menu;
+  mailStore.currentId = menu.id;
+};
+
+const handleGoWrite = () => {
+  const menu = {
+    title: "写信",
+    type: selectMail.value.type,
+    id: "write",
+  };
+  const menuItem = mailStore.mailMenuList.find((x) => x.id === menu.id);
+  if (menuItem === undefined) {
+    mailStore.mailMenuList.push(menu);
+  }
+  mailStore.currentMenu = menu;
+  mailStore.currentId = menu.id;
+};
+
+onMounted(() => {
+  getMialList();
+});
+</script>
+
+<style lang="scss" scoped>
+.left {
+  font-size: 14px;
+  .top {
+    padding: 10px;
+    text-align: center;
+    border-bottom: 1px solid #ddd;
+    .mail {
+      color: black;
+      font-weight: 700;
+      font-size: 14px;
+    }
+  }
+  .body {
+    padding: 10px;
+    .mail-menu {
+      list-style: none;
+      margin-block-start: 0;
+      margin-block-end: 0;
+      padding: 0px;
+      .menu-item {
+        font-weight: 700;
+        padding-left: 10px;
+        font-size: 12px;
+        width: 100%;
+        height: 40px;
+        line-height: 40px;
+        border-radius: 3px;
+        color: #696969;
+        cursor: pointer;
+        &:hover {
+          background: #ddedfe;
+        }
+      }
+    }
+  }
+}
+.select-menu {
+  background: #ddedfe;
+  color: #169bd5 !important;
+}
+</style>

+ 149 - 0
src/views/connect/E-mail/mail/com/mailDetail.vue

@@ -0,0 +1,149 @@
+<template>
+  <div v-loading="loading" class="box">
+    <div class="top">
+      <div class="top-row">
+        <div class="label">发 件 人:</div>
+        <div class="value">
+          <span
+            v-for="item in replyTo"
+            :key="item.id"
+            style="margin-right: 10px"
+          >
+            {{ item.personalName }}</span
+          >
+        </div>
+      </div>
+      <div class="top-row">
+        <div class="label">收 件 人:</div>
+        <div class="value">
+          <span v-for="item in to" :key="item.id" style="margin-right: 10px">{{
+            item.personalName
+          }}</span>
+        </div>
+      </div>
+      <div class="top-row" v-if="cc.length > 0">
+        <div class="label">抄 送 人:</div>
+        <div class="value">
+          <span v-for="item in cc" :key="item.id" style="margin-right: 10px">
+            {{ item.personalName }}</span
+          >
+        </div>
+      </div>
+      <div class="top-row" v-if="bcc.length > 0">
+        <div class="label">密 送 人:</div>
+        <div class="value">
+          <span v-for="item in bcc" :key="item.id" style="margin-right: 10px">
+            {{ item.personalName }}</span
+          >
+        </div>
+      </div>
+      <div class="top-row">
+        <div class="label">时 间:</div>
+        <div class="value">{{ time }}</div>
+      </div>
+    </div>
+    <div class="body">
+      <iframe
+        frameborder="0"
+        allowTransparency="true"
+        style="
+          width: 99% !important;
+          overflow-x: scroll;
+          padding-top: 10px;
+          height: 600px;
+        "
+        :srcdoc="showBodyText(detailsData.data.content)"
+        :ref="'iframeText_' + mailStore.currentId"
+        :id="'iframeText_' + mailStore.currentId"
+      >
+      </iframe>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import byTable from "@/components/byTable/index";
+import useMailStore from "@/store/modules/mail";
+const { proxy } = getCurrentInstance();
+const mailStore = useMailStore();
+let loading = ref(false);
+const detailsData = reactive({
+  data: {},
+});
+const to = ref([]);
+const cc = ref([]);
+const bcc = ref([]);
+const replyTo = ref([]);
+const requestData = ref({});
+const getDetails = () => {
+  loading.value = true;
+  proxy
+    .post("/mailService/getMessageDetail", {
+      ...mailStore.currentMenu,
+    })
+    .then((res) => {
+      detailsData.data = res;
+      to.value = res.messageAddressList.filter((x) => x.type === 1);
+      cc.value = res.messageAddressList.filter((x) => x.type === 2);
+      bcc.value = res.messageAddressList.filter((x) => x.type === 3);
+      replyTo.value = res.messageAddressList.filter((x) => x.type === 4);
+      loading.value = false;
+    });
+};
+
+const showBodyText = (text) => {
+  if (text) {
+    let val = JSON.parse(JSON.stringify(text));
+    val = val.replace("body {", "tbody {");
+    val = val.replace(
+      "td, p, li, th {",
+      "tbody td, tbody p, tbody li, tbody th {"
+    );
+    val = val.replace(
+      /<p>/g,
+      '<p style="margin-block-start: 0; margin-block-end: 0;">'
+    );
+    return val;
+  } else {
+    return text;
+  }
+};
+
+const init = () => {
+  getDetails();
+};
+
+onMounted(() => {
+  // init();
+});
+
+defineExpose({
+  initFn: init,
+});
+</script>
+
+<style lang="scss" scoped>
+.box {
+  padding: 0 10px;
+  font-size: 12px;
+  .top {
+    padding: 10px;
+    background: #f1f1f1;
+    .top-row {
+      display: flex;
+      margin-bottom: 10px;
+      .label {
+        min-width: 60px;
+        color: #999999;
+        text-align: right;
+      }
+      .value {
+        flex: 1;
+        color: #333333;
+        font-weight: 700;
+        margin-right: 10px;
+      }
+    }
+  }
+}
+</style>

+ 121 - 0
src/views/connect/E-mail/mail/com/mailList.vue

@@ -0,0 +1,121 @@
+<template>
+  <div>
+    <div style="padding-left: 20px">
+      <el-icon @click="handleRefresh" style="cursor: pointer">
+        <Refresh />
+      </el-icon>
+    </div>
+    <byTable
+      :source="tableData.data"
+      :pagination="tableData.pagination"
+      :config="config"
+      :loading="loading"
+      :hideSearch="true"
+      highlight-current-row
+      :action-list="[]"
+      :table-events="{
+        //element talbe事件都能传
+        'row-click': handleRowClick,
+      }"
+      @get-list="getList"
+    >
+    </byTable>
+  </div>
+</template>
+
+<script setup>
+import byTable from "@/components/byTable/index";
+import useMailStore from "@/store/modules/mail";
+const { proxy } = getCurrentInstance();
+const mailStore = useMailStore();
+let loading = ref(false);
+const tableData = reactive({
+  data: [],
+  pagination: {
+    pageNum: 1,
+    pageSize: 10,
+    total: 0,
+  },
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "发件人",
+        prop: "fromPersonalName",
+      },
+    },
+    {
+      attrs: {
+        label: "发件人地址",
+        prop: "fromEmail",
+      },
+    },
+    {
+      attrs: {
+        label: "主题",
+        prop: "subject",
+      },
+    },
+    {
+      attrs: {
+        label: "时间",
+        prop: "sendDate",
+      },
+    },
+  ];
+});
+
+const getList = (req = {}) => {
+  tableData.pagination = { ...tableData.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/mailService/getMessagePage", {
+      ...mailStore.currentMenu,
+      ...tableData.pagination,
+      ...req,
+    })
+    .then((res) => {
+      tableData.data = res.rows;
+      tableData.pagination.total = res.total;
+      loading.value = false;
+    });
+};
+
+const handleRefresh = () => {
+  tableData.pagination = {
+    pageNum: 1,
+    pageSize: 10,
+  };
+  getList();
+};
+
+const handleRowClick = (row) => {
+  const menu = {
+    title: row.subject.slice(0, 4) + "...",
+    type: mailStore.selectMail.type,
+    messageId: row.id,
+    id: "detail" + "," + row.id,
+  };
+  const menuItem = mailStore.mailMenuList.find((x) => x.id === menu.id);
+  if (menuItem === undefined) {
+    mailStore.mailMenuList.push(menu);
+  }
+  mailStore.currentMenu = menu;
+  mailStore.currentId = menu.id;
+};
+onMounted(() => {
+  // getList();
+});
+
+const init = () => {
+  getList();
+};
+
+defineExpose({
+  initFn: init,
+});
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 78 - 0
src/views/connect/E-mail/mail/com/mailWrite.vue

@@ -0,0 +1,78 @@
+<template>
+  <div v-loading="loading" style="padding: 10px">
+    <div style="margin-bottom: 10px; padding-left: 65px">
+      <el-button type="primary" @click="handleSend">发送</el-button>
+    </div>
+    <div style="width: 70%">
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="submit"
+      >
+        <template #contentSlot> 内容插槽 </template>
+      </byForm>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import byForm from "@/components/byForm/index";
+import { ElMessage, ElMessageBox } from "element-plus";
+let loading = ref(false);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 65,
+  itemWidth: 100,
+  labelPosition: "left",
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "aa",
+      label: "收件人",
+      required: true,
+      itemWidth: 100,
+      itemType: "text",
+    },
+    {
+      type: "input",
+      prop: "bb",
+      label: "主题",
+      required: true,
+      itemWidth: 100,
+      itemType: "text",
+    },
+    {
+      type: "slot",
+      slotName: "contentSlot",
+      label: " ",
+    },
+    {
+      type: "input",
+      prop: "cc",
+      label: "发件人",
+      required: true,
+      itemWidth: 100,
+      itemType: "text",
+    },
+  ];
+});
+const rules = ref({
+  aa: [{ required: true, message: "请输入收件人", trigger: "blur" }],
+  bb: [{ required: true, message: "请输入主题", trigger: "blur" }],
+  cc: [{ required: true, message: "请输入发件人", trigger: "blur" }],
+});
+const formData = reactive({
+  data: {},
+});
+const submit = ref(null);
+const handleSend = () => {
+  submit.value.handleSubmit(() => {});
+};
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 120 - 0
src/views/connect/E-mail/mail/com/main.vue

@@ -0,0 +1,120 @@
+<template>
+  <div class="container">
+    <el-tabs
+      v-model="activeMenu"
+      closable
+      :stretch="false"
+      type="card"
+      @tab-remove="handleTabRemove"
+      @tab-change="handleTabChange"
+    >
+      <el-tab-pane
+        v-for="(item, index) in menuList"
+        :key="index"
+        :label="item.title"
+        :name="item.id"
+      >
+        <div class="main">
+          <mailList
+            v-if="item.id.includes('floder')"
+            :ref="'floder' + index"
+          ></mailList>
+          <mailDetail
+            v-if="item.id.includes('detail')"
+            :ref="'detail' + index"
+          ></mailDetail>
+          <mailWrite v-if="item.id.includes('write')"></mailWrite>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script setup>
+import mailList from "./mailList.vue";
+import mailDetail from "./mailDetail.vue";
+import mailWrite from "./mailWrite.vue";
+
+import useMailStore from "@/store/modules/mail";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { nextTick } from "vue";
+
+const mailStore = useMailStore();
+const { proxy } = getCurrentInstance();
+const menuList = ref([]);
+let activeMenu = ref("");
+
+mailStore.$subscribe((mutations, state) => {
+  activeMenu.value = state.currentId;
+  menuList.value = state.mailMenuList;
+  // 判断是文件夹还是邮件详情
+  const currentMenu = state.currentMenu;
+  let type = "";
+  if (currentMenu.id.includes("floder")) {
+    type = "floder";
+  } else if (currentMenu.id.includes("detail")) {
+    type = "detail";
+  } else {
+    type = "write";
+  }
+  checkType(currentMenu, type);
+});
+
+const handleTabRemove = (id) => {
+  const clickIndex = menuList.value.findIndex((x) => x.id === id);
+  let currentMenu = {};
+  if (menuList.value.length > 1) {
+    // 如果删除的是当前菜单
+    if (activeMenu.value === id) {
+      if (menuList.value.length > clickIndex + 1) {
+        currentMenu = menuList.value[clickIndex + 1];
+      } else {
+        currentMenu = menuList.value[clickIndex - 1];
+      }
+      // 更新store值
+      mailStore.currentMenu = currentMenu;
+      mailStore.currentId = currentMenu.id;
+    }
+    menuList.value.splice(clickIndex, 1);
+  } else {
+    return ElMessage({
+      message: "最后一个标签页啦!",
+      type: "info",
+    });
+  }
+};
+
+const checkType = (menu, type) => {
+  if (type == "write") return;
+  const index = menuList.value.findIndex((x) => x.id === activeMenu.value);
+  const dom = type + index.toString();
+  nextTick(() => {
+    console.log(dom, "wss");
+    proxy.$refs[dom][0].initFn();
+  });
+};
+
+// const handleTabChange = () => {
+//   // 判断是文件夹还是邮件详情
+//   let type = "";
+//   if (activeMenu.value.id.includes("floder")) {
+//     type = "floder";
+//   } else if (activeMenu.value.id.includes("detail")) {
+//     type = "detail";
+//   } else {
+//     type = "write";
+//   }
+//   checkType(currentMenu, type);
+// };
+
+onMounted(() => {});
+</script>
+
+<style lang="scss" scoped>
+.container {
+  .main {
+    height: calc(100vh - 180px);
+    overflow: auto;
+  }
+}
+</style>

+ 34 - 0
src/views/connect/E-mail/mail/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <div class="box">
+    <div class="left">
+      <mailLeft></mailLeft>
+    </div>
+    <div class="right">
+      <mailMain></mailMain>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import mailLeft from "./com/left.vue";
+import mailMain from "./com/main.vue";
+</script>
+
+<style lang="scss" scoped>
+.box {
+  height: calc(100vh - 50px - 50px);
+  padding: 10px;
+  display: flex;
+  .left,
+  .right {
+    background: #fff;
+  }
+  .left {
+    width: 300px;
+    margin-right: 10px;
+  }
+  .right {
+    flex: 1;
+  }
+}
+</style>

+ 509 - 0
src/views/finance/fundManage/accountPayment/index.vue

@@ -0,0 +1,509 @@
+<template>
+	<div class="user">
+		<div class="content">
+			<byTable
+				:source="sourceList.data"
+				:pagination="sourceList.pagination"
+				:config="config"
+				:loading="loading"
+				highlight-current-row
+				:selectConfig="selectConfig"
+				:table-events="{
+					//element talbe事件都能传
+					select: select,
+				}"
+				:action-list="[
+					{
+						text: 'Excel导入',
+						action: () => openExcel(),
+						disabled: false,
+					},
+					{
+						text: '添加物料',
+						action: () => openModal('add'),
+						disabled: false,
+					},
+				]"
+				@get-list="getList"
+			>
+				<template #pic="{ item }">
+					<div v-if="item.fileList.length > 0">
+						<img
+							:src="item.fileList[0].fileUrl"
+							class="pic"
+							@click="handleClickFile(item.fileList[0])"
+						/>
+					</div>
+					<div v-else></div>
+				</template>
+			</byTable>
+		</div>
+		<el-dialog
+			:title="modalType == 'add' ? '添加' : '编辑'"
+			v-model="dialogVisible"
+			width="500"
+			v-loading="loading"
+		>
+			<byForm
+				:formConfig="formConfig"
+				:formOption="formOption"
+				v-model="formData.data"
+				:rules="rules"
+				ref="byform"
+			>
+				<template #productPic>
+					<div>
+						<el-upload
+							v-model:fileList="fileList"
+							action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+							:data="uploadData"
+							list-type="picture-card"
+							:on-remove="handleRemove"
+							:on-success="handleSuccess"
+							:before-upload="handleBeforeUpload"
+						>
+							<el-icon><Plus /></el-icon>
+						</el-upload>
+					</div>
+				</template>
+			</byForm>
+			<template #footer>
+				<el-button @click="dialogVisible = false" size="large"
+					>取 消</el-button
+				>
+				<el-button
+					type="primary"
+					@click="submitForm('byform')"
+					size="large"
+					:loading="submitLoading"
+				>
+					确 定
+				</el-button>
+			</template>
+		</el-dialog>
+		<el-dialog
+			title="Excel导入"
+			v-model="openExcelDialog"
+			width="400"
+			v-loading="loading"
+		>
+			<template #footer>
+				<el-button @click="openExcelDialog = false" size="large"
+					>取 消</el-button
+				>
+				<el-button
+					type="primary"
+					@click="submitExcel()"
+					size="large"
+					:loading="submitLoading"
+				>
+					确 定
+				</el-button>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from 'element-plus'
+import byTable from '@/components/byTable/index'
+import byForm from '@/components/byForm/index'
+
+import { computed, defineComponent, ref } from 'vue'
+const loading = ref(false)
+const submitLoading = ref(false)
+const sourceList = ref({
+	data: [],
+	pagination: {
+		total: 3,
+		pageNum: 1,
+		pageSize: 10,
+		type: '',
+		productClassifyId: '',
+		keyword: '',
+		definition: '2',
+	},
+})
+let dialogVisible = ref(false)
+let openExcelDialog = ref(false)
+
+let modalType = ref('add')
+let rules = ref({
+	productClassifyId: [
+		{ required: true, message: '请选择物料分类', trigger: 'change' },
+	],
+	type: [{ required: true, message: '请选择物料类型', trigger: 'change' }],
+	name: [{ required: true, message: '请输入物料名称', trigger: 'blur' }],
+	unit: [{ required: true, message: '请选择单位', trigger: 'change' }],
+})
+const { proxy } = getCurrentInstance()
+const selectConfig = computed(() => {
+	return [
+		{
+			label: '打款状态',
+			prop: 'paymentStatus',
+			data: [],
+		},
+	]
+})
+const config = computed(() => {
+	return [
+		{
+			attrs: {
+				label: '归属公司',
+				prop: 'corporationName',
+			},
+		},
+		{
+			attrs: {
+				label: '归属部门',
+				prop: 'deptName',
+			},
+		},
+		{
+			attrs: {
+				label: '付款类型',
+				prop: 'type',
+                render(type) {
+                    return proxy.dictDataEcho(type, fundsType.value);
+                },
+			},
+		},
+		{
+			attrs: {
+				label: '申请人',
+				prop: 'userName',
+			},
+		},
+		{
+			attrs: {
+				label: '申请时间',
+				prop: 'createTime',
+			},
+		},
+		{
+			attrs: {
+				label: '用款时间',
+				prop: 'paymentTime',
+			},
+		},
+		{
+			attrs: {
+				label: '金额',
+				prop: 'total',
+			},
+		},
+		{
+			attrs: {
+				label: '款项说明',
+				prop: 'paymentRemarks',
+			},
+		},
+		{
+			attrs: {
+				label: '打款状态',
+				prop: 'status',
+			},
+		},
+		{
+			attrs: {
+				label: '操作',
+				width: '200',
+				align: 'right',
+			},
+			// 渲染 el-button,一般用在最后一列。
+			renderHTML(row) {
+				return [
+					{
+						attrs: {
+							label: '修改',
+							type: 'primary',
+							text: true,
+						},
+						el: 'button',
+						click() {
+							getDtl(row)
+						},
+					},
+					{
+						attrs: {
+							label: '删除',
+							type: 'danger',
+							text: true,
+						},
+						el: 'button',
+						click() {
+							// 弹窗提示是否删除
+							ElMessageBox.confirm(
+								'此操作将永久删除该数据, 是否继续?',
+								'提示',
+								{
+									confirmButtonText: '确定',
+									cancelButtonText: '取消',
+									type: 'warning',
+								}
+							).then(() => {
+								// 删除
+								proxy
+									.post('/productInfo/delete', {
+										id: row.id,
+									})
+									.then((res) => {
+										ElMessage({
+											message: '删除成功',
+											type: 'success',
+										})
+										getList()
+									})
+							})
+						},
+					},
+				]
+			},
+		},
+	]
+})
+
+let formData = reactive({
+	data: {},
+})
+const formOption = reactive({
+	inline: true,
+	labelWidth: 100,
+	itemWidth: 100,
+	rules: [],
+})
+const byform = ref(null)
+const treeListData = ref([])
+const formConfig = computed(() => {
+	return [
+		{
+			type: 'treeSelect',
+			prop: 'productClassifyId',
+			label: '物料分类',
+			data: [],
+		},
+		{
+			type: 'select',
+			prop: 'type',
+			label: '物料类型',
+			required: true,
+			data: [
+				{
+					label: '原料',
+					id: '1',
+				},
+				{
+					label: '辅料',
+					id: '2',
+				},
+				{
+					label: '配件',
+					id: '3',
+				},
+				{
+					label: '包材',
+					id: '4',
+				},
+				{
+					label: '其他',
+					id: '5',
+				},
+			],
+		},
+		{
+			type: 'input',
+			prop: 'name',
+			label: '物料名称',
+		},
+		{
+			type: 'input',
+			prop: 'spec',
+			label: '规格型号',
+		},
+		{
+			type: 'select',
+			prop: 'unit',
+			label: '单位',
+			required: true,
+			data: [
+				{
+					label: '个',
+					id: '个',
+				},
+				{
+					label: '双',
+					id: '双',
+				},
+			],
+		},
+		{
+			type: 'slot',
+			slotName: 'productPic',
+			prop: 'fileList',
+			label: '产品图片',
+		},
+
+		{
+			type: 'input',
+			prop: 'remark',
+			label: '备注',
+			itemType: 'textarea',
+		},
+	]
+})
+const newPassword = () => {
+	formData.data.password = generatePassword()
+}
+const generatePassword = () => {
+	var length = 12,
+		charset =
+			'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
+		password = ''
+	for (var i = 0, n = charset.length; i < length; ++i) {
+		password += charset.charAt(Math.floor(Math.random() * n))
+	}
+	return password
+}
+
+const getList = async (req) => {
+	sourceList.value.pagination = { ...sourceList.value.pagination, ...req }
+	loading.value = true
+	proxy
+		.post('/accountPayment/page', sourceList.value.pagination)
+		.then((message) => {
+			console.log(message)
+			sourceList.value.data = message.rows
+			sourceList.value.pagination.total = message.total
+			setTimeout(() => {
+				loading.value = false
+			}, 200)
+		})
+}
+const uploadData = ref({})
+const fileList = ref([])
+const fileListCopy = ref([])
+proxy.getDict(['payment_status','funds_type','funds_payment_method']).then((res) => {
+	console.log(res)
+})
+const openModal = () => {
+	dialogVisible.value = true
+	modalType.value = 'add'
+	formData.data = {
+		definition: '2',
+		fileList: [],
+		type: '1',
+	}
+	fileList.value = []
+	fileListCopy.value = []
+}
+
+const openExcel = () => {
+	openExcelDialog.value = true
+}
+const submitExcel = () => {
+	openExcelDialog.value = false
+}
+const selection = ref({
+	data: [],
+})
+const select = (_selection, row) => {
+	selection.value.data = _selection
+	console.log(_selection.length)
+}
+
+const submitForm = () => {
+	console.log(byform.value)
+	byform.value.handleSubmit((valid) => {
+		formData.data.fileList = fileListCopy.value.map((x) => ({
+			id: x.id,
+			fileName: x.fileName,
+		}))
+		submitLoading.value = true
+		proxy.post('/productInfo/' + modalType.value, formData.data).then(
+			(res) => {
+				ElMessage({
+					message: modalType.value == 'add' ? '添加成功' : '编辑成功',
+					type: 'success',
+				})
+				dialogVisible.value = false
+				submitLoading.value = false
+				getList()
+			},
+			(err) => {
+				submitLoading.value = false
+			}
+		)
+	})
+}
+
+const getTreeList = () => {
+	proxy
+		.post('/productClassify/tree', {
+			parentId: '',
+			name: '',
+			definition: '2',
+		})
+		.then((message) => {
+			treeListData.value = message
+			formConfig.value[0].data = message
+		})
+}
+
+const getDtl = (row) => {
+	modalType.value = 'edit'
+	proxy.post('/productInfo/detail', { id: row.id }).then((res) => {
+		fileList.value = row.fileList.map((x) => ({ ...x, url: x.fileUrl }))
+		fileListCopy.value = [...fileList.value]
+		res.type = res.type + ''
+		res.definition = '2'
+		formData.data = res
+		dialogVisible.value = true
+	})
+}
+getTreeList()
+getList()
+const handleBeforeUpload = async (file) => {
+	const res = await proxy.post('/fileInfo/getSing', { fileName: file.name })
+	uploadData.value = res.uploadBody
+	fileListCopy.value.push({
+		id: res.id,
+		fileName: res.fileName,
+		path: res.fileUrl,
+		url: res.fileUrl,
+		uid: file.uid,
+	})
+}
+
+const handleSuccess = (res, file, files) => {
+	// 查当前file的index值去赋值对应的copy变量的值
+	// let uid = file.uid;
+	// const index = fileList.value.findIndex((x) => x.uid === uid);
+	// fileListCopy.value[index].uid = uid;
+}
+
+const handleRemove = (file) => {
+	const index = fileListCopy.value.findIndex(
+		(x) => x.uid === file.uid || x.id === file.id
+	)
+	fileListCopy.value.splice(index, 1)
+}
+
+const handleClickFile = (file) => {
+	window.open(file.fileUrl, '_blank')
+}
+</script>
+  
+<style lang="scss" scoped>
+.user {
+	padding: 20px;
+}
+.pic {
+	object-fit: contain;
+	width: 50px;
+	height: 50px;
+	cursor: pointer;
+	vertical-align: middle;
+}
+</style>

+ 355 - 0
src/views/process/flowExample/index.vue

@@ -0,0 +1,355 @@
+<template>
+	<div class="tenant">
+		<!-- <Banner /> -->
+		<div class="content">
+			<byTable
+				:source="sourceList.data"
+				:pagination="sourceList.pagination"
+				:config="config"
+				:loading="loading"
+				highlight-current-row
+				:selectConfig="selectConfig"
+				:table-events="{
+					//element talbe事件都能传
+					select: select,
+				}"
+				@get-list="getList"
+			>
+				<template #slotName="{ item }">
+					{{ item.createTime }}
+				</template>
+			</byTable>
+		</div>
+		<el-dialog
+			:title="modalType == 'add' ? '新增' : '编辑'"
+			v-model="dialogVisible"
+			width="400"
+			v-loading="loading"
+		>
+			<byForm
+				:formConfig="formConfig"
+				:formOption="formOption"
+				v-model="formData.data"
+				:rules="rules"
+				ref="byform"
+			>
+			</byForm>
+			<template #footer>
+				<el-button @click="dialogVisible = false" size="large"
+					>取 消</el-button
+				>
+				<el-button
+					type="primary"
+					@click="submitForm('byform')"
+					size="large"
+					:loading="submitLoading"
+				>
+					确 定
+				</el-button>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+    
+  <script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from 'element-plus'
+import byTable from '@/components/byTable/index'
+import byForm from '@/components/byForm/index'
+import { computed, defineComponent, ref } from 'vue'
+const loading = ref(false)
+const submitLoading = ref(false)
+const dictCommonModal = ref(false)
+const sourceList = ref({
+	data: [],
+	pagination: {
+		total: 3,
+		pageNum: 1,
+		pageSize: 10,
+	},
+})
+let dialogVisible = ref(false)
+let roomDialogVisible = ref(false)
+let modalType = ref('add')
+let rules = ref({
+	classifyName: [
+		{ required: true, message: '请输入功能模块', trigger: 'blur' },
+	],
+	flowKey: [{ required: true, message: '请输入流程标识', trigger: 'blur' }],
+	flowName: [{ required: true, message: '请输入流程名称', trigger: 'blur' }],
+})
+const { proxy } = getCurrentInstance()
+const selectConfig = computed(() => {
+	return [
+        {
+			label: '流程类型',
+			prop: 'flowInfoId',
+			data: [],
+		},
+		{
+			label: '流程状态',
+			prop: 'status',
+
+			data: [
+				{
+					label: '进行中',
+					value: '1',
+				},
+				{
+					label: '已结束',
+					value: '2',
+				},
+			],
+		},
+	]
+})
+const config = computed(() => {
+	return [
+		{
+			attrs: {
+				label: '流程类型',
+				prop: 'title',
+			},
+		},
+		{
+			attrs: {
+				label: '流程标题',
+				prop: 'title',
+			},
+		},
+
+		{
+			attrs: {
+				label: '流程状态',
+				width: 100,
+				prop: 'status',
+			},
+			render(status) {
+				//1审核中 2审核通过 3审核不通过
+				return status == 0 || status == 1 ? '待处理' : '已结束'
+			},
+		},
+		{
+			attrs: {
+				label: '发起人',
+				prop: 'createUserName',
+			},
+		},
+		{
+			attrs: {
+				label: '发起时间',
+				prop: 'createTime',
+			},
+		},
+		{
+			attrs: {
+				label: '操作',
+				width: '200',
+				align: 'right',
+			},
+			// 渲染 el-button,一般用在最后一列。
+			renderHTML(row) {
+				return [
+					row.status != 1
+						? {
+								attrs: {
+									label: '重新审批',
+									type: 'primary',
+									text: true,
+									bg: true,
+									disabled: false,
+								},
+								el: 'button',
+								click() {
+									flowJump(row)
+								},
+						  }: {},
+                    row.status == 1?   
+						{
+								attrs: {
+									label: '退回上一步',
+									text: true,
+									bg: true,
+									type: 'primary',
+									disabled: false,
+									style: {
+										color: '#e6a23c',
+									},
+								},
+								el: 'button',
+								click() {
+									flowJump(row,3)
+								},
+						  }:{},
+                    row.status == 1?      
+                          {
+								attrs: {
+									label: '向下流转',
+									text: true,
+									bg: true,
+									type: 'primary',
+									disabled: false,
+									style: {
+										color: '#e6a23c',
+									},
+								},
+								el: 'button',
+								click() {
+									flowJump(row,1)
+								},
+						  }:{},
+				]
+			},
+		},
+	]
+})
+let dtlData = reactive({
+	data: {},
+})
+let formData = reactive({
+	data: {},
+	treeData: [],
+})
+const formOption = reactive({
+	inline: true,
+	labelWidth: 100,
+	itemWidth: 100,
+	rules: [],
+})
+const byform = ref(null)
+const treeData = ref([])
+const formConfig = computed(() => {
+	return [
+		{
+			type: 'input',
+			prop: 'classifyName',
+			label: '功能模块',
+		},
+		{
+			type: 'input',
+			prop: 'flowKey',
+			label: '流程标识',
+			isHide: modalType.value == 'edit',
+		},
+		{
+			type: 'input',
+			prop: 'flowName',
+			label: '流程名称',
+		},
+	]
+})
+
+const flowJump = (row,type) => {
+    proxy.post('/flowProcess/jump', {flowId:row.id,handleType:type,version:row.version,data:{}}).then((message) => {
+        console.log(message)
+        if(message){
+            ElMessage.success('操作成功')
+            getList()
+        }
+    })
+}
+
+const getFlowType = () => {
+    proxy
+        .post('/flowExample/getFlowType')
+            .then((message) => {
+                console.log(message)
+                selectConfig.value[0].data = message.map((item) => {
+                    return {
+                        label: item.flowName,
+                        value: item.id,
+                    }
+                })
+            })
+        
+}
+getFlowType()
+
+const getList = async (req) => {
+	sourceList.value.pagination = { ...sourceList.value.pagination, ...req }
+	loading.value = true
+	proxy
+		.post('/flowExample/page', sourceList.value.pagination)
+		.then((message) => {
+			console.log(message)
+			sourceList.value.data = message.rows
+			sourceList.value.pagination.total = message.total
+			setTimeout(() => {
+				loading.value = false
+			}, 200)
+		})
+}
+
+const openModal = () => {
+	dialogVisible.value = true
+	modalType.value = 'add'
+	formData.data = {}
+}
+const selection = ref({
+	data: [],
+})
+const select = (_selection, row) => {
+	selection.value.data = _selection
+	console.log(_selection.length)
+}
+
+const tree = ref(null)
+const submitTree = () => {
+	proxy
+		.post('/tenantInfo/bindingMenu', {
+			tenantId: selection.value.data[0].tenantId,
+			menuIdList: tree.value.getCheckedKeys(),
+		})
+		.then((res) => {
+			ElMessage({
+				message: '保存成功',
+				type: 'success',
+			})
+			roomDialogVisible.value = false
+		})
+}
+
+const submitForm = () => {
+	byform.value.handleSubmit((valid) => {
+		submitLoading.value = true
+		proxy
+			.post('/flowInfo/' + modalType.value, formData.data)
+			.then((res) => {
+				ElMessage({
+					message: modalType.value == 'add' ? '添加成功' : '编辑成功',
+					type: 'success',
+				})
+				dialogVisible.value = false
+				submitLoading.value = false
+				getList()
+			})
+	})
+}
+
+const getDtl = (row) => {
+	formData.data = { ...row }
+	modalType.value = 'edit'
+	dialogVisible.value = true
+}
+
+const changeStatus = (row) => {
+	modalType.value = 'edit'
+	proxy
+		.post('/flowInfo/edit', { ...row, status: row.status === 0 ? 1 : 0 })
+		.then((res) => {
+			ElMessage({
+				message: '操作成功',
+				type: 'success',
+			})
+			getList()
+		})
+}
+
+getList()
+</script>
+    
+  <style lang="scss" scoped>
+.tenant {
+	padding: 20px;
+}
+</style>

+ 38 - 121
src/views/process/processApproval/index.vue

@@ -5,21 +5,21 @@
         <div class="commons-title title">流程标题</div>
         <SendSubscribe
           ref="makeDom"
-          v-if="queryData.data.isSubscribe == '10'"
+          v-if="flowForm.flowKey == 'subscribe_flow'"
         ></SendSubscribe>
         <SendPurchase
           ref="makeDom"
-          v-else-if="queryData.data.isSubscribe == '20'"
+          v-else-if="flowForm.flowKey == 'purchase_flow'"
           :queryData="queryData.data"
         ></SendPurchase>
         <SendFunds
           ref="makeDom"
-          v-else-if="queryData.data.isSubscribe == '30'"
+          v-else-if="flowForm.flowKey == '30'"
           :queryData="queryData.data"
         ></SendFunds>
         <ReturnGood
           ref="makeDom"
-          v-else-if="queryData.data.isSubscribe == '40'"
+          v-else-if="flowForm.flowKey == '40'"
           :queryData="queryData.data"
         ></ReturnGood>
       </div>
@@ -44,104 +44,19 @@
       <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
         <el-tab-pane label="审批记录" name="first">
           <ul class="flow-chart">
-            <li>
+            <li v-for="item in recordList" :key="item.id">
               <div class="left-icon">
                 <i class="iconfont icon-iconm_daick"></i>
                 <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
               </div>
               <div class="right-conetnt">
                 <div class="name">
-                  发起人:张三
-                  <span>2022-11-11 00:00:00</span>
+                  发起人:{{ item.processedUser }}
+                  <!-- <span>2022-11-11 00:00:00</span> -->
                 </div>
-
                 <div class="remark">
-                  <div class="label">发起审批</div>
-                  1231231231231321231
-                </div>
-              </div>
-              <div class="line"></div>
-            </li>
-            <li>
-              <div class="left-icon">
-                <i class="iconfont icon-iconm_daick"></i>
-                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
-              </div>
-              <div class="right-conetnt">
-                <div class="name">
-                  发起人:张三
-                  <span>2022-11-11 00:00:00</span>
-                </div>
-
-                <div class="remark">
-                  <div class="label">发起审批</div>
-
-                  <div>
-                    啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间
-                  </div>
-                </div>
-              </div>
-              <div class="line"></div>
-            </li>
-            <li>
-              <div class="left-icon">
-                <i class="iconfont icon-iconm_daick"></i>
-                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
-              </div>
-              <div class="right-conetnt">
-                <div class="name">
-                  发起人:张三
-                  <span>2022-11-11 00:00:00</span>
-                </div>
-
-                <div class="remark">
-                  <div class="label">发起审批</div>
-
-                  <div>
-                    啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间
-                  </div>
-                </div>
-              </div>
-              <div class="line"></div>
-            </li>
-            <li>
-              <div class="left-icon">
-                <i class="iconfont icon-iconm_daick"></i>
-                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
-              </div>
-              <div class="right-conetnt">
-                <div class="name">
-                  发起人:张三
-                  <span>2022-11-11 00:00:00</span>
-                </div>
-
-                <div class="remark">
-                  <div class="label">发起审批</div>
-
-                  <div>
-                    啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间
-                  </div>
-                </div>
-              </div>
-              <div class="line"></div>
-            </li>
-            <li>
-              <div class="left-icon">
-                <i class="iconfont icon-iconm_daick"></i>
-                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
-              </div>
-              <div class="right-conetnt">
-                <div class="name">
-                  发起人:张三
-                  <span>2022-11-11 00:00:00</span>
-                </div>
-
-                <div class="remark">
-                  <div class="label">发起审批</div>
-
-                  <div>
-                    啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间
-                  </div>
+                  <div class="label">{{ item.nodeName }}</div>
+                  {{ item.remark }}
                 </div>
               </div>
               <div class="line"></div>
@@ -226,7 +141,7 @@ const handleSelectUser = () => {
 };
 
 const handleResult = (res) => {
-  if (res !== null && res.success === 1) {
+  if (res !== null && res.success) {
     skipPage();
   } else {
     dialogVisible.value = true;
@@ -242,16 +157,13 @@ const handleSubmit = async () => {
       flowFormDom.value.validate((vaild) => {
         if (vaild) {
           const data = { ...makeDom.value.submitData };
-          if (queryData.data.isSubscribe == "10") {
+          if (flowForm.flowKey == "subscribe_flow") {
             data.subscribeDetailList = data.subscribeDetailList.map((x) => ({
               bussinessId: x.bussinessId,
               count: x.count,
               remark: x.remark,
             }));
-            proxy.post("/subscribe/add", data).then((res) => {
-              handleResult(res);
-            });
-          } else if (queryData.data.isSubscribe == "20") {
+          } else if (flowForm.flowKey == "purchase_flow") {
             data.purchaseDetailList = data.purchaseDetailList.map((x) => ({
               bussinessId: x.bussinessId,
               subscribeDetailId: x.id,
@@ -259,26 +171,17 @@ const handleSubmit = async () => {
               price: x.price,
               amount: x.amount,
             }));
-            proxy.post("/purchase/add", data).then((res) => {
-              handleResult(res);
-            });
-          } else if (queryData.data.isSubscribe == "30") {
-            proxy
-              .post("/flowProcess/initiate", {
-                ...flowForm,
-                flowKey: "account_request_funds_flow",
-                data,
-              })
-              .then((res) => {
-                console.log(res, "awss");
-                handleResult(res);
-              });
-          } else if (queryData.data.isSubscribe == "40") {
-            console.log(data, "wssaa");
-            proxy.post("/flowProcess/initiate", data).then((res) => {
+          } else if (flowForm.flowKey == "30") {
+          } else if (flowForm.flowKey == "40") {
+          }
+          proxy
+            .post("/flowProcess/initiate", {
+              ...flowForm,
+              data,
+            })
+            .then((res) => {
               handleResult(res);
             });
-          }
         }
       });
     }
@@ -292,15 +195,15 @@ const skipPage = () => {
     message: "操作成功!",
     type: "success",
   });
-  if (queryData.data.isSubscribe == "10") {
+  if (flowForm.flowKey == "subscribe_flow") {
     router.replace({
       path: "/purchaseManage/purchaseManage/subscribe",
     });
-  } else if (queryData.data.isSubscribe == "20") {
+  } else if (flowForm.flowKey == "purchase_flow") {
     router.replace({
       path: "/purchaseManage/purchaseManage/purchase",
     });
-  } else if (queryData.data.isSubscribe == "30") {
+  } else if (flowForm.flowKey == "30") {
     router.replace({
       path: "/finance/fundManage/funds",
     });
@@ -310,9 +213,23 @@ const skipPage = () => {
 let queryData = reactive({
   data: {},
 });
+// 记录
+const recordList = ref([]);
+const getRecords = () => {
+  proxy
+    .post("/flowExample/getFlowNode", {
+      flowKey: flowForm.flowKey,
+    })
+    .then((res) => {
+      console.log(res, "ass");
+      recordList.value = res;
+    });
+};
 
 onMounted(() => {
   queryData.data = { ...route.query };
+  flowForm.flowKey = route.query.flowKey;
+  getRecords();
 });
 </script>
 

+ 2 - 1
src/views/process/processConfig/index.vue

@@ -302,7 +302,8 @@ const getDtl = (row) => {
 	router.push({
 		path: 'processChart',
 		query: {
-			id: row.id,
+			id: row.flowInfoId,
+			tenantId:row.tenantId
 		},
 	})
 }

+ 18 - 4
src/views/process/processConfig/processChart.vue

@@ -2,11 +2,19 @@
 	<div class="processChart">
 		<div class="from">
 			<div class="commons-title">基础配置</div>
+			<div>
+				<el-form labelPosition='top'>
+					<el-form-item label="流程标题" label-width="80px">
+						<el-input v-model="title" placeholder="请输入流程标题"></el-input>
+						
+					</el-form-item>
+				</el-form>
+			</div>
 		</div>
 		<div class="content">
-			<div class="commons-title">基础配置</div>
+			<div class="commons-title">流程节点配置</div>
 			<div class="chart-warp">
-				<vueFlow></vueFlow>
+				<vueFlow :title='title'></vueFlow>
 			</div>
 		</div>
 	</div>
@@ -15,7 +23,7 @@
 <script setup>
 import { VueFlow } from '@vue-flow/core'
 import vueFlow from '@/views/process/processConfig/vueFlow.vue'
-
+const title = ref('')
 onMounted(() => {
 	
 })
@@ -28,12 +36,18 @@ onMounted(() => {
 	justify-content: space-between;
 	.from {
 		width: 300px;
+		background: #fff;
+		border-radius: 5px;
+		padding: 20px;
 	}
 	.content {
 		width: calc(100% - 320px);
+		border-radius: 5px;
+		padding: 20px;
+		background: #fff;
 	}
 }
 .chart-warp {
-	height: calc(100vh - 180px);
+	height: calc(100vh - 280px);
 }
 </style>

+ 474 - 14
src/views/process/processConfig/vueFlow.vue

@@ -3,8 +3,44 @@
 		<div id="container"></div>
 		<div id="stencil"></div>
 		<div id="graph-container"></div>
-
 	</div>
+	<el-button @click="submitAll" type="primary">保存</el-button>
+	<el-dialog
+		:title="modalType == 'add' ? '新增' : '编辑'"
+		v-model="dialogVisible"
+		width="500"
+		v-loading="loading"
+	>
+		<byForm
+			:formConfig="formConfig"
+			:formOption="formOption"
+			v-model="formData.data"
+			:rules="rules"
+			ref="byform"
+		>
+		</byForm>
+		<template #footer>
+			<el-button @click="dialogVisible = false" size="large"
+				>取 消</el-button
+			>
+			<el-button
+				type="danger"
+				@click="deleteFlowDefinitionNodeObj()"
+				size="large"
+				:loading="submitLoading"
+			>
+				删 除
+			</el-button>
+			<el-button
+				type="primary"
+				@click="submitForm('byform')"
+				size="large"
+				:loading="submitLoading"
+			>
+				确 定
+			</el-button>
+		</template>
+	</el-dialog>
 </template>
 <script lang="ts" setup>
 import {
@@ -17,7 +53,9 @@ import {
 	toRefs,
 	computed,
 	nextTick,
+	getCurrentInstance,
 } from 'vue'
+import byForm from '@/components/byForm/index'
 import { Graph, Shape } from '@antv/x6'
 import { Stencil } from '@antv/x6-plugin-stencil'
 import { Transform } from '@antv/x6-plugin-transform'
@@ -26,15 +64,398 @@ import { Snapline } from '@antv/x6-plugin-snapline'
 import { Keyboard } from '@antv/x6-plugin-keyboard'
 import { Clipboard } from '@antv/x6-plugin-clipboard'
 import { History } from '@antv/x6-plugin-history'
-const aaa = (port: any) => {
+import Cookies from 'js-cookie'
+import { ElMessage, ElMessageBox } from "element-plus";
+defineProps({
+  title: {
+    type: Object,
+    default: '',
+  },
+  
+});
+const { proxy } = getCurrentInstance()
+const internalInstance = getCurrentInstance()
+const dialogVisible = ref(false)
+const modalType = ref('add')
+const loading = ref(false)
+const submitLoading = ref(false)
+const formData = reactive({
+	data: {
+		userName: '',
+		password: '',
+	},
+})
+const byform = ref(null)
+const flowDefinitionNodeObj = ref({})
+const rules = reactive({
+	nodeName: [
+		{
+			required: true,
+			message: '请输入节点名称',
+			trigger: 'blur',
+		},
+	],
+	handleObjectType: [
+		{
+			required: true,
+			message: '办理人类型不能为空',
+			trigger: 'blur',
+		},
+	],
+	handleObjectId: [
+		{
+			required: true,
+			message: '办理人不能为空',
+			trigger: 'blur',
+		},
+	],
+})
+const formConfig = computed(() => {
+	return [
+		{
+			type: 'input',
+			prop: 'nodeName',
+			label: '节点名称',
+			required: true,
+			itemType: 'text',
+		},
+
+		{
+			type: 'select',
+			prop: 'handleObjectType',
+			label: '办理人',
+			placeholder: '请选择办理人类型',
+			required: true,
+			itemWidth: 30,
+			fn: (e) => {
+				console.log(e)
+				gethandleObjectList(e)
+			},
+			//1用户 2部门负责人 3部门总监 4岗位 5角色
+			data: [
+				{
+					label: '用户',
+					value: 1,
+				},
+				{
+					label: '部门负责人',
+					value: 2,
+				},
+				{
+					label: '部门总监',
+					value: 3,
+				},
+				{
+					label: '岗位',
+					value: 4,
+				},
+				{
+					label: '角色',
+					value: 5,
+				},
+			],
+		},
+		// {
+		// 	type: "treeSelect",
+		// 	prop: "handleObjectId",
+		// 	label: "请选择办理人",
+		// 	itemWidth: 30,
+		// 	data: [],
+		// },
+		{
+			type: 'select',
+
+			label: '  ',
+			itemWidth: 30,
+			prop: 'handleObjectId',
+			placeholder: '请选择办理人',
+			data: [],
+		}, 
+		{
+			type: 'input',
+			prop: 'handlingMethod',
+			label: '节点后置执行方法',
+			required: true,
+			itemType: 'text',
+		},
+		{
+			type: 'input',
+			prop: 'jumpCondition',
+			label: '条件表达式',
+			required: true,
+			itemType: 'text',
+		},
+		{
+			type: 'checkbox',
+			prop: 'nodeButtonSet',
+			label: '节点按钮',
+			//1通过 2驳回 3返回上一步 4退回到发起人
+			data: [
+				{
+					label: '通过',
+					value: 1,
+				},
+				{
+					label: '驳回',
+					value: 2,
+				},
+				{
+					label: '返回上一步',
+					value: 3,
+				},
+				{
+					label: '退回到发起人',
+					value: 4,
+				},
+			],
+		},
+		{
+			type: 'radio',
+			prop: 'jobNumber11',
+			label: '审批意见必填',
+			data: [
+				{
+					label: '是',
+					value: 1,
+				},
+				{
+					label: '否',
+					value: 0,
+				},
+			],
+		},
+	]
+})
+const formOption = reactive({
+	inline: true,
+	labelWidth: 100,
+	itemWidth: 100,
+})
+let graph
+const submitForm = () => {
+	byform.value.handleSubmit((valid) => {
+		flowDefinitionNodeObj.value[formData.data.id] = formData.data
+		console.log(flowDefinitionNodeObj.value)
+	})
+}
+
+const submitFormData = {
+	flowInfoId:null,
+	titleTemplate:null,
+	tenantId:Cookies.get('tenantId'),
+	nodeObject:'',
+	lineObject:'',
+	flowDefinitionNodeList:[],
+}
+const submitAll = () => {
+	if(proxy.title == '') {
+		ElMessage({
+			message: '请输入流程标题',
+			type: 'warning',
+		})
+		return
+	}
+	submitFormData.titleTemplate = proxy.title
+	const nodeList = graph.toJSON().cells
+	console.log(nodeList)
+	const isStart = false
+	for (let i = 0; i < nodeList.length; i++) {
+		const element = nodeList[i];
+		//是办理节点
+		if(element.id != 1 && element.shape != "edge") {
+			console.log(element)
+			if(!flowDefinitionNodeObj.value[element.id]) {
+				ElMessage({
+					message: '有节点未配置,请检查节点123123123',
+					type: 'warning',
+				})
+				return
+			}
+			submitFormData.flowDefinitionNodeList.push({...flowDefinitionNodeObj.value[element.id],nodeType:2})
+		}
+		if(element.id == "1") {
+			submitFormData.flowDefinitionNodeList.push({
+				nodeName:'开始',
+				nodeType:1,
+				id:1,
+				nodeButtonSet:'',
+				parentId:0,
+			})
+		}
+		//说明是线
+		if(element.shape == "edge") {
+			console.log(flowDefinitionNodeObj)
+			if(!flowDefinitionNodeObj.value[element.target.cell]) {
+				ElMessage({
+					message: '有节点未配置,请检查节点',
+					type: 'warning',
+				})
+				return
+			}
+			flowDefinitionNodeObj.value[element.target.cell].id = element.target.cell
+			flowDefinitionNodeObj.value[element.target.cell].parentId = element.source.cell
+			submitFormData.flowDefinitionNodeList = []
+		}		
+	}
+	addVersion()
+	console.log(flowDefinitionNodeObj.value)
+}
+
+//选取一个随机不重复的正整数id
+const randomId = () => {
+	const id = Math.floor(Math.random() * 100000000000000000)
+	if(flowDefinitionNodeObj.value[id]) {
+		randomId()
+	} else {
+		return id
+	}
+}
+
+
+const addVersion = () => {
+	const idObg = {}
+	for (let i = 0; i < submitFormData.flowDefinitionNodeList.length; i++) {
+		const element = submitFormData.flowDefinitionNodeList[i];
+		if(element.parentId == null && element.nodeName == '结束') {
+			ElMessage({
+				message: '有结束节点未连线,请配置',
+				type: 'warning',
+			})
+			return
+		}
+		if(isNaN(element.id)) {
+			if(idObg[element.id]) {
+				element.id = idObg[element.id]
+			} else {
+				const id = randomId()
+				idObg[element.id] = id
+				element.id = id
+			}
+		}
+		if(isNaN(element.parentId) && element.nodeName != '开始') {
+			if(idObg[element.parentId]) {
+				element.parentId = idObg[element.parentId]
+			} else {
+				const id = randomId()
+				idObg[element.parentId] = id
+				element.parentId = id
+			}
+		}
+		//nodeButtonSet转成字符串类型,用逗号隔开
+		if(element.nodeButtonSet) {
+			element.nodeButtonSet = element.nodeButtonSet.join(',')
+		}
+	}
+	console.log(submitFormData)
+	
+	proxy.post('/flowDefinition/addVersion',submitFormData)
+		.then((res) => {
+			console.log(res)
+			ElMessage({
+				message: '保存成功',
+				type: 'success',
+			})
+		})
+}
+
+//将组数里的id和parentId转换成整正整数类型
+const changeId = (arr) => {
+	for (let i = 0; i < arr.length; i++) {
+		const element = arr[i];
+		element.id = parseInt(element.id)
+		element.parentId = parseInt(element.parentId)
+	}
+}
+
+
+
+
+const deleteFlowDefinitionNodeObj = (id) => {
+	graph.removeNode(formData.data.id)
+	delete flowDefinitionNodeObj.value[id]
+	dialogVisible.value = false
+}
+
+const gethandleObjectList = (e) => {
+	formData.data.handleObjectId = ''
+	if(e === 1) {
+		proxy.get('/tenantUser/list?pageNum=1&pageSize=1000&tenantId=' + submitFormData.tenantId,{})
+			.then((res) => {
+				formConfig.value[2].data = res.rows.map((item) => {
+					return {
+						label: item.nickName,
+						value: item.userId,
+					}
+				})
+			})
+	}
+	if(e === 3 || e === 2) {
+		proxy.get('/tenantDept/list?pageNum=1&pageSize=1000&tenantId=' + submitFormData.tenantId,{})
+			.then((res) => {
+				formConfig.value[2].data =res.data.map(item=> {
+					return {
+						label: item.deptName,
+						value: item.deptId,
+					}
+				})
+			})
+	}
+	if(e === 4) {
+		
+	}
+	if(e === 5) {
+		proxy.get('/tenantRole/list?pageNum=1&pageSize=1000&tenantId=' + submitFormData.tenantId,{})
+			.then((res) => {
+				formConfig.value[2].data = res.rows.map((item) => {
+					return {
+						label: item.roleName,
+						value: item.roleId,
+					}
+				})
+			})
+	}
+	
+	
+}
+
+const getTenantDept = () => {
+	
+}
+getTenantDept()
+
+const recursive = (data) => {
+  data.map((item) => {
+    item.label = item.deptName;
+    item.id = item.deptId;
+    if (item.children) {
+      recursive(item.children);
+    } else {
+      item.children = [];
+    }
+  });
+};
+
+const pushRoom = (port: any) => {
 	console.log(port)
+	if(port.node.label == '结束') {
+		flowDefinitionNodeObj.value[port.node.id] = {
+			nodeName:'结束',
+			nodeType:99,
+			id:port.id,
+			nodeButtonSet:'',
+			parentId:null,
+		}
+	}
+	console.log(flowDefinitionNodeObj.value)
 }
+//用于存储流程定义节点数据
+
 const antvInit = () => {
-	const graph = new Graph({
-		height:700,
+	graph = new Graph({
+		height: 600,
 		container: document.getElementById('graph-container')!,
 		grid: true,
-		onPortRendered:aaa,
+		onPortRendered: pushRoom,
 		mousewheel: {
 			enabled: true,
 			zoomAtMousePosition: true,
@@ -99,7 +520,6 @@ const antvInit = () => {
 				title: '基础流程图',
 				name: 'group1',
 			},
-			
 		],
 		layoutOptions: {
 			columns: 2,
@@ -144,7 +564,6 @@ const antvInit = () => {
 			})
 		)
 
-
 	// 控制连接桩显示/隐藏
 	const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
 		for (let i = 0, len = ports.length; i < len; i += 1) {
@@ -166,7 +585,22 @@ const antvInit = () => {
 		showPorts(ports, false)
 	})
 	// #endregion
+	graph.on('cell:click', ({ e, x, y, cell, view }) => {
+		console.log(cell)
+		if (cell.label === '开始' || cell.label === '结束' || cell.shape === 'edge') {
+			return
+		}
+		if (flowDefinitionNodeObj.value[cell.id]) {
+			formData.data = flowDefinitionNodeObj.value[cell.id]
+		} else {
+			formData.data = {
+				id: cell.id,
+				cell: cell,
+			}
+		}
 
+		dialogVisible.value = true
+	})
 	// #region 初始化图形
 	const ports = {
 		groups: {
@@ -365,15 +799,27 @@ const antvInit = () => {
 		},
 		true
 	)
+	let firstLi = document.createElement('li')
+	firstLi.innerText = '指标详情'
+	console.log(firstLi)
 	const r1 = graph.createNode({
 		shape: 'custom-rect',
 		label: '开始',
+		zIndex: 100,
 		attrs: {
 			body: {
 				rx: 20,
 				ry: 26,
 			},
 		},
+		tools: [
+			{
+				name: 'button',
+				args: {
+					firstLi,
+				},
+			},
+		],
 	})
 	const r2 = graph.createNode({
 		shape: 'custom-rect',
@@ -398,20 +844,36 @@ const antvInit = () => {
 		},
 		label: '结束',
 	})
-	stencil.load([r1, r2, r3, r4], 'group1')
-
-	
-	
+	stencil.load([ r2,  r4], 'group1')
+	graph.addNode({
+		shape: 'custom-rect',
+		label: '开始',
+		id: 1,
+		x: 500,
+		y: 100,
+	})
 }
 onMounted(() => {
 	antvInit()
+	//获取url router参数
+	const router = useRouter();
+	submitFormData.flowInfoId = router.currentRoute.value.query.id
+	submitFormData.tenantId = router.currentRoute.value.query.tenantId
 })
 </script>
 <style lang="scss">
+.x6-widget-stencil-title {
+	display: none;
+}
+.x6-widget-stencil-content {
+	top: 0 !important;
+}
 .vueFlow {
 	position: relative;
 	display: flex;
 	justify-content: space-between;
+	overflow: hidden;
+	height: 600px;
 	#stencil {
 		position: absolute;
 		top: 0;
@@ -423,10 +885,8 @@ onMounted(() => {
 		border-right: 1px solid #e8e8e8;
 	}
 	#container {
-		height: 800px;
-		width: 800px;
 	}
-	#graph-container{
+	#graph-container {
 		width: 100%;
 		position: absolute;
 		right: 0;

+ 13 - 4
src/views/purchaseManage/purchaseManage/purchase/index.vue

@@ -156,7 +156,7 @@ const sourceList = ref({
     total: 3,
     pageNum: 1,
     pageSize: 10,
-    status: "15,30",
+    status: "15",
   },
 });
 let dialogVisible = ref(false);
@@ -169,7 +169,7 @@ const { proxy } = getCurrentInstance();
 const selectConfig = reactive([
   {
     label: "状态",
-    prop: "type",
+    prop: "status",
     data: [
       {
         label: "待采购",
@@ -235,9 +235,18 @@ const config = computed(() => {
     },
     {
       attrs: {
-        label: "申购状态",
+        label: "已采购数量",
+        prop: "purchaseCount",
+      },
+    },
+    {
+      attrs: {
+        label: "采购状态",
         prop: "status",
       },
+      render(status) {
+        return status == 15 ? "待采购" : "部分采购";
+      },
     },
     {
       attrs: {
@@ -445,7 +454,7 @@ const start = () => {
     proxy.$router.replace({
       path: "/platform_manage/process/processApproval",
       query: {
-        isSubscribe: "20",
+        flowKey: "purchase_flow",
         ids,
       },
     });

+ 33 - 27
src/views/purchaseManage/purchaseManage/subscribe/index.vue

@@ -182,28 +182,7 @@ const selectConfig = reactive([
   {
     label: "状态",
     prop: "status",
-    data: [
-      {
-        label: "审批中",
-        value: "10",
-      },
-      {
-        label: "待采购",
-        value: "15",
-      },
-      {
-        label: "部分采购",
-        value: "30",
-      },
-      {
-        label: "已采购",
-        value: "20",
-      },
-      {
-        label: "已作废",
-        value: "99",
-      },
-    ],
+    data: [],
   },
 ]);
 const config = computed(() => {
@@ -258,6 +237,9 @@ const config = computed(() => {
         label: "状态",
         prop: "status",
       },
+      render(status) {
+        return statusData.value.find((x) => x.value == status).label;
+      },
     },
     {
       attrs: {
@@ -295,7 +277,7 @@ const config = computed(() => {
             click() {
               // 弹窗提示是否删除
               ElMessageBox.confirm(
-                "此操作将永久删除该数据, 是否继续?",
+                "此操作将永久作废该数据, 是否继续?",
                 "提示",
                 {
                   confirmButtonText: "确定",
@@ -305,12 +287,13 @@ const config = computed(() => {
               ).then(() => {
                 // 删除
                 proxy
-                  .post("/productionProcesses/delete", {
-                    id: row.id,
+                  .post("/subscribeDetail/edit", {
+                    ...row,
+                    status: 99,
                   })
                   .then((res) => {
                     ElMessage({
-                      message: "删除成功",
+                      message: "作废成功",
                       type: "success",
                     });
                     getList();
@@ -399,7 +382,7 @@ const openModal = () => {
   proxy.$router.replace({
     path: "/platform_manage/process/processApproval",
     query: {
-      isSubscribe: "10",
+      flowKey: "subscribe_flow",
     },
   });
 };
@@ -483,6 +466,29 @@ const handleRemove = (file) => {
 const handleClose = (index) => {
   fileList.value.splice(index, 1);
 };
+const statusData = ref([
+  {
+    label: "审批中",
+    value: "10",
+  },
+  {
+    label: "待采购",
+    value: "15",
+  },
+  {
+    label: "部分采购",
+    value: "30",
+  },
+  {
+    label: "已采购",
+    value: "20",
+  },
+  {
+    label: "已作废",
+    value: "99",
+  },
+]);
+selectConfig[1].data = statusData.value;
 getList();
 </script>