cz vor 2 Jahren
Ursprung
Commit
d0c01fcb5d

+ 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>

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

@@ -0,0 +1,325 @@
+<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="8">
+          <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-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)"
+                >删除</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: [],
+  },
+});
+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" }],
+});
+
+let openProduct = ref(false);
+// 物品相应逻辑
+const handleRemove = (index) => {
+  formData.data.purchaseDetailList.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,
+    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: 0,
+      price: null,
+      amount: null,
+    }));
+  });
+};
+// 获取供应商数据
+const supplierData = ref([]);
+const getSupplierList = async (req) => {
+  proxy
+    .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      supplierData.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;
+  }
+  formData.data.amount = sum;
+};
+// 向父组件暴露
+defineExpose({
+  submitData: formData.data,
+  handleSubmit,
+});
+</script>
+
+
+<style lang="scss" scoped>
+._t {
+  margin-bottom: 5px;
+  font-size: 14px;
+}
+</style>

+ 227 - 0
src/components/WDLY/process/SendSubscribe.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>

+ 1 - 2
src/views/WDLY/basic/product/index.vue

@@ -619,7 +619,7 @@ const getList = async (req) => {
       sourceList.value.data = message.rows.map((x) => ({
         ...x,
         fileList: [],
-        victoriatouristJson: JSON.parse(x.victoriatouristJson),
+        ...JSON.parse(x.victoriatouristJson),
       }));
       sourceList.value.pagination.total = message.total;
       setTimeout(() => {
@@ -749,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;

+ 88 - 5
src/views/WDLY/basic/supplier/index.vue

@@ -43,7 +43,7 @@
         ref="byform"
       >
         <template #address>
-          <el-row :gutter="10" style="width: 100%; margin-left: -15px">
+          <el-row :gutter="10" style="width: 100%">
             <el-col :span="8">
               <el-form-item prop="countryId">
                 <el-select
@@ -89,7 +89,7 @@
               </el-form-item>
             </el-col>
           </el-row>
-          <el-row style="margin-top: 20px; width: 100%; margin-left: -10px">
+          <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">
@@ -100,7 +100,7 @@
         </template>
 
         <template #contact>
-          <el-row :gutter="10" style="width: 100%; margin-left: -15px">
+          <el-row :gutter="10" style="width: 100%">
             <el-col :span="8">
               <el-form-item prop="contactPerson">
                 <el-input
@@ -238,6 +238,20 @@ const selectConfig = reactive([
       },
     ],
   },
+  {
+    label: "账期",
+    prop: "accountPeriodType",
+    data: [
+      {
+        label: "有",
+        value: "1",
+      },
+      {
+        label: "无",
+        value: "0",
+      },
+    ],
+  },
 ]);
 const config = computed(() => {
   return [
@@ -283,6 +297,18 @@ const config = computed(() => {
     },
     {
       attrs: {
+        label: "账期",
+        prop: "accountPeriod",
+      },
+    },
+    {
+      attrs: {
+        label: "备注",
+        prop: "returnPeriod",
+      },
+    },
+    {
+      attrs: {
         label: "备注",
         prop: "remark",
       },
@@ -403,16 +429,72 @@ const formConfig = computed(() => {
       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/page", sourceList.value.pagination)
+    .post("/supplierInfo/pageByWdly", sourceList.value.pagination)
     .then((message) => {
       console.log(message);
-      sourceList.value.data = message.rows;
+      sourceList.value.data = message.rows.map((x) => ({
+        ...x,
+        ...JSON.parse(x.victoriatouristJson),
+      }));
       sourceList.value.pagination.total = message.total;
       setTimeout(() => {
         loading.value = false;
@@ -466,6 +548,7 @@ const getDtl = (row) => {
         getCityData(res.countryId, "20");
         getCityData(res.provinceId, "30");
         res.type = res.type + "";
+        res.victoriatouristJson = JSON.parse(res.victoriatouristJson);
         formData.data = res;
         dialogVisible.value = true;
       });

+ 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>

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

@@ -0,0 +1,345 @@
+<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>
+        <SendFunds
+          ref="makeDom"
+          v-else-if="flowForm.flowKey == '30'"
+          :queryData="queryData.data"
+        ></SendFunds>
+        <ReturnGood
+          ref="makeDom"
+          v-else-if="flowForm.flowKey == '40'"
+          :queryData="queryData.data"
+        ></ReturnGood>
+      </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/process/SendSubscribe";
+//采购发起
+import SendPurchase from "@/components/process/SendPurchase";
+//请款发起
+import SendFunds from "@/components/process/SendFunds";
+//退货
+import ReturnGood from "@/components/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,
+            }));
+          } 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,
+            }));
+          } 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: "/purchaseManage/purchaseManage/subscribe",
+    });
+  } else if (flowForm.flowKey == "purchase_flow") {
+    router.replace({
+      path: "/purchaseManage/purchaseManage/purchase",
+    });
+  } 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>

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

@@ -0,0 +1,487 @@
+<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: "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: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "采购人",
+        prop: "purchaseName",
+      },
+    },
+    {
+      attrs: {
+        label: "采购时间",
+        prop: "createTime",
+      },
+    },
+    {
+      attrs: {
+        label: "采购状态",
+        prop: "purchaseStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "到货状态",
+        prop: "arrivalStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "付款状态",
+        prop: "payStatus",
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "200",
+        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() {
+              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>

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

@@ -0,0 +1,465 @@
+<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",
+      },
+    ],
+  },
+]);
+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: "status",
+      },
+    },
+    {
+      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/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 = () => {
+//  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: "/platform_manage/process/processApproval",
+      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>

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

@@ -0,0 +1,512 @@
+<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: [
+      {
+        label: "审批中",
+        value: "10",
+      },
+      {
+        label: "待采购",
+        value: "15",
+      },
+      {
+        label: "部分采购",
+        value: "30",
+      },
+      {
+        label: "已采购",
+        value: "20",
+      },
+      {
+        label: "已作废",
+        value: "99",
+      },
+    ],
+  },
+]);
+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",
+      },
+    },
+    {
+      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("/productionProcesses/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: "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;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+
+const openModal = () => {
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    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);
+};
+getList();
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 18 - 90
src/views/process/processApproval/index.vue

@@ -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>
@@ -298,10 +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>