Browse Source

7-7号 测试合并开发

asd26269546 1 năm trước cách đây
mục cha
commit
9d14667602
43 tập tin đã thay đổi với 7965 bổ sung1500 xóa
  1. 9 0
      src/assets/css/index.scss
  2. 111 108
      src/components/common-list.vue
  3. 92 9
      src/components/testForm/index.vue
  4. 916 900
      src/lang/cn.js
  5. 105 0
      src/lang/cnCZ.js
  6. 334 0
      src/lang/cnLXF.js
  7. 29 27
      src/main.js
  8. 41 0
      src/router/jxskRouter.js
  9. 80 0
      src/router/routerLXF.js
  10. 3 0
      src/store/index.js
  11. 36 5
      src/utils/util.js
  12. 1 1
      src/views/customer/highseas/index.vue
  13. 105 106
      src/views/fund/flow-of-funds/index.vue
  14. 14 21
      src/views/fund/funds/index.vue
  15. 1 3
      src/views/login.vue
  16. 6 1
      src/views/main.vue
  17. 888 0
      src/views/processApproval/components/Contract.vue
  18. 773 0
      src/views/processApproval/components/PriceSheet.vue
  19. 521 0
      src/views/processApproval/components/SendFunds.vue
  20. 433 0
      src/views/processApproval/components/SendPurchase.vue
  21. 574 0
      src/views/processApproval/components/SendPurchasePayment.vue
  22. 366 4
      src/views/processApproval/components/SendSubscribe.vue
  23. 17 13
      src/views/processApproval/index.vue
  24. 226 184
      src/views/processApproval/processDtl.vue
  25. 185 0
      src/views/procurementManagement/arrival/add.vue
  26. 120 0
      src/views/procurementManagement/arrival/index.vue
  27. 149 0
      src/views/procurementManagement/payment/index.vue
  28. 118 114
      src/views/procurementManagement/procureList/index.vue
  29. 160 0
      src/views/procurementManagement/receipt/index.vue
  30. 1 1
      src/views/procurementManagement/subscribe/index.vue
  31. 1 1
      src/views/product-material/product-library/index.vue
  32. 205 0
      src/views/product-material/standard-product-library/add.vue
  33. 122 0
      src/views/product-material/standard-product-library/index.vue
  34. 194 0
      src/views/purchase-payment/invoice/add.vue
  35. 112 0
      src/views/purchase-payment/invoice/index.vue
  36. 212 0
      src/views/purchase-sales/inventory-management/Inventory/add.vue
  37. 110 0
      src/views/purchase-sales/inventory-management/Inventory/index.vue
  38. 1 1
      src/views/purchase-sales/inventory-management/outInList/index.vue
  39. 230 0
      src/views/salesContract/claim/add.vue
  40. 124 0
      src/views/salesContract/claim/index.vue
  41. 102 0
      src/views/salesContract/contract/index.vue
  42. 136 0
      src/views/salesContract/priceSheet/index.vue
  43. 2 1
      src/views/working/iframWinfaster.vue

+ 9 - 0
src/assets/css/index.scss

@@ -116,6 +116,8 @@ li {
     border-collapse: collapse;
     border-spacing: 0;
     overflow-x: auto;
+    padding: 0 12px;
+    box-sizing: border-box;
     table {
         width: 100%;
         border-collapse: collapse;
@@ -245,4 +247,11 @@ li {
     width: 100%;
     height: 50px;
     background: #fff;
+    border-radius: 8px;
 }
+
+.common-process-card{
+    margin: 16px 12px;
+    background: #fff;
+
+}

+ 111 - 108
src/components/common-list.vue

@@ -1,120 +1,123 @@
 <template>
-	<div class="common-list">
-		<ul>
-			<li v-for="i in listData" :key="i.id">
-				<div
-					class="left-box"
-					style="margin-right: 20px"
-					v-if="isCheckbox"
-				>
-					<van-checkbox
-						v-model="i.checked"
-						icon-size="15px"
-						shape="square"
-						@change='listCheck'
-						:disabled="optionalValue ? (optionalValue != i[optionalKey]) : false"
-					></van-checkbox>
-				</div>
-				<div
-					class="center-content"
-					style="line-height: 24px"
-					@click="listCk(i)"
-				>
-					<div v-for="j in config" :key="j.prop">
-						<span>{{ j.label }}:</span>{{ i[j.prop] }}
-					</div>
-				</div>
-				<div class="more-box" v-if="showMore" @click="listCk(i)">
-					<van-icon name="arrow" />
-				</div>
-			</li>
-		</ul>
-	</div>
+  <div class="common-list">
+    <ul>
+      <li v-for="i in listData" :key="i.id">
+        <div class="left-box" style="margin-right: 20px" v-if="isCheckbox">
+          <van-checkbox
+            v-model="i.checked"
+            icon-size="15px"
+            shape="square"
+            @change="listCheck"
+            :disabled="optionalValue ? optionalValue != i[optionalKey] : false"
+          ></van-checkbox>
+        </div>
+        <div
+          class="center-content"
+          style="line-height: 24px"
+          @click="listCk(i)"
+        >
+          <div v-for="j in config" :key="j.prop" style="display: flex">
+            <span>{{ j.label }}:</span>
+            <span v-if="j.type && j.type === 'slot'">
+              <slot :name="j.slotName" :row="i">
+                {{ j.slotName }}插槽占位符
+              </slot>
+            </span>
+            <span v-else>
+              {{ i[j.prop] }}
+            </span>
+          </div>
+        </div>
+        <div class="more-box" v-if="showMore" @click="listCk(i)">
+          <van-icon name="arrow" />
+        </div>
+      </li>
+    </ul>
+  </div>
 </template>
 <script setup>
-import { ref, getCurrentInstance, onMounted, defineProps, watch } from 'vue'
-const proxy = getCurrentInstance().proxy
+import { ref, getCurrentInstance, onMounted, defineProps, watch } from "vue";
+const proxy = getCurrentInstance().proxy;
 defineProps({
-	data: {
-		type: Array,
-		default: [],
-	},
-	config: {
-		type: Object,
-		default: [],
-	},
-	showMore: {
-		type: Boolean,
-		default: true,
-	},
-	isCheckbox: {
-		type: Boolean,
-		default: false,
-	},
-	optionalKey: {
-		type: String,
-		default: null,
-	},
-})
-let listData = ref([])
-let checkList = []
+  data: {
+    type: Array,
+    default: [],
+  },
+  config: {
+    type: Object,
+    default: [],
+  },
+  showMore: {
+    type: Boolean,
+    default: true,
+  },
+  isCheckbox: {
+    type: Boolean,
+    default: false,
+  },
+  optionalKey: {
+    type: String,
+    default: null,
+  },
+});
+let listData = ref([]);
+let checkList = [];
 watch(
-	() => proxy.data,
-	(newVal) => {
-		listData.value = newVal.map((i) => {
-			//判断是否有选中的
-			if (checkList.length > 0) {
-				checkList.map((j) => {
-					if (i.id == j.id) {
-						i.checked = true
-					}
-				})
-			}
-			return i
-		})
-	}
-)
-const optionalValue = ref(null)
+  () => proxy.data,
+  (newVal) => {
+    listData.value = newVal.map((i) => {
+      //判断是否有选中的
+      if (checkList.length > 0) {
+        checkList.map((j) => {
+          if (i.id == j.id) {
+            i.checked = true;
+          }
+        });
+      }
+      return i;
+    });
+  }
+);
+const optionalValue = ref(null);
 const listCheck = () => {
-	checkList = []
-	listData.value.map((i) => {
-		if (i.checked) {
-			checkList.push(i)
-			if(!optionalValue.value) {
-				optionalValue.value = i[proxy.optionalKey]
-			}
-		}
-	})
-	if(checkList.length == 0) {
-		optionalValue.value = null
-	}
-	proxy.$emit('onCheck', checkList)
-}
+  checkList = [];
+  listData.value.map((i) => {
+    if (i.checked) {
+      checkList.push(i);
+      if (!optionalValue.value) {
+        optionalValue.value = i[proxy.optionalKey];
+      }
+    }
+  });
+  if (checkList.length == 0) {
+    optionalValue.value = null;
+  }
+  proxy.$emit("onCheck", checkList);
+};
 const listCk = (item) => {
-	
-	proxy.$emit('onClick', item)
-}
+  proxy.$emit("onClick", item);
+};
 </script>
 <style lang="scss">
 .common-list {
-	ul {
-		margin-top: 10px;
-		li {
-			list-style: none;
-			position: relative;
-			display: flex;
-			box-sizing: border-box;
-			align-items: center;
-			justify-content: space-between;
-			padding: 12px 16px;
-			background: #fff;
-			border-bottom: 1px solid #f1f1f1;
-			.center-content {
-				flex: 1;
-			}
-			.left-box {
-			}
-		}
-	}
+  ul {
+    margin-top: 10px;
+    li {
+      list-style: none;
+      position: relative;
+      display: flex;
+      box-sizing: border-box;
+      align-items: center;
+      justify-content: space-between;
+      padding: 12px 16px;
+      background: #fff;
+      border-bottom: 1px solid #f1f1f1;
+      .center-content {
+        flex: 1;
+      }
+      .left-box {
+      }
+    }
+  }
 }
 </style>

+ 92 - 9
src/components/testForm/index.vue

@@ -30,7 +30,12 @@
             :required="getRequired(i.prop)"
             :right-icon="i.isNeedRightBtn ? i.rightIcon : ''"
             @click-right-icon="i.isNeedRightBtn ? i.rightIconClick() : () => {}"
-            @blur="i.isNeedBlurMethon ? i.blurMethon(formData[i.prop]) : () => {}">
+            @blur="i.isNeedBlurMethon ? i.blurMethon(formData[i.prop]) : () => {}"
+            @input="
+              () => {
+                return i.inputFn ? i.inputFn(formData[i.prop]) : () => {};
+              }
+            ">
           </van-field>
           <!-- switch -->
           <van-field v-if="i.type == 'switch'" :label="i.label" :name="i.prop" :required="getRequired(i.prop)">
@@ -120,6 +125,26 @@
               :max-date="i.maxDate"
               :columns-type="i.columnsType" />
           </van-popup>
+          <!-- 时间选择器 带时分秒 -->
+
+          <van-field
+            v-if="i.type == 'picker' && i.itemType == 'datePickerTime'"
+            :label="i.label"
+            :name="i.prop"
+            v-model="formData[i.prop]"
+            is-link
+            :readonly="true"
+            :placeholder="i.placeholder ? i.placeholder : '请选择'"
+            @click="() => (!formOption.readonly ?i.needDefault? defaultTimeFn(i, index) :i.showPicker=true: '')"
+            :rules="getRules(i.prop)"
+            :required="getRequired(i.prop)">
+          </van-field>
+          <van-popup v-model:show="i.showPicker" round position="bottom" v-if="i.type == 'picker' && i.itemType == 'datePickerTime'">
+            <van-picker-group :tabs="['日期', '时间']" @confirm="() => datePickerTimeConfirm(i, index)" @cancel="i.showPicker = false">
+              <van-date-picker v-model="datePickerDateArr" :columns-type="i.columnsType" />
+              <van-time-picker v-model="datePickerTimeArr" :columns-type="['hour', 'minute', 'second']" />
+            </van-picker-group>
+          </van-popup>
           <!-- 级联 城市 -->
           <van-field
             v-if="i.type == 'cascader' && i.itemType == 'city'"
@@ -186,7 +211,7 @@
           <van-button
             plain
             type="primary"
-            @click="handleRemove(index, item)"
+            @click="handleRemove(index, btnConfigCopy)"
             size="mini"
             style="border: none; background: #ecebeb"
             v-if="formOption.btnConfig !== undefined && formOption.btnConfig.isNeed"
@@ -257,7 +282,10 @@
             :columns="item.data"
             :columns-field-names="item.fieldNames ? item.fieldNames : onePickerFieldNames"
             @cancel="item.showPicker = false"
-            @confirm="(option) => onConfirmListPicker(option, item)" />
+            @confirm="
+              (option) => (item.changeFn ? item.changeFn(option, item, currentIndex, currentSonIndex, btnConfigCopy.prop) : onConfirmListPicker(option, item))
+            " />
+          <!-- @confirm="(option) => onConfirmListPicker(option, item)"  -->
         </van-popup>
         <van-popup v-model:show="item.showPicker" round position="bottom" v-if="item.type == 'picker' && item.itemType == 'datePicker'">
           <van-date-picker
@@ -299,8 +327,9 @@
 
 <script setup>
 import { showLoadingToast, closeToast, showNotify } from "vant";
-import { ref, getCurrentInstance, onMounted, reactive, computed, toRefs, watch } from "vue";
+import { formatDate } from "@/utils/auth";
 
+const submitBtn = ref(null);
 const props = defineProps({
   modelValue: {
     type: Object,
@@ -437,6 +466,18 @@ const formDataListShowLabel = () => {
     }
   }
 };
+const formDataListShowLabelOne = () => {
+  for (let i = 0; i < formData.value[btnConfigCopy.prop].length; i++) {
+    for (let j = 0; j < btnConfigCopy.listConfig.length; j++) {
+      const jele = btnConfigCopy.listConfig[j];
+      if (jele.type === "picker" && jele.itemType !== "datePicker") {
+        if (jele.data && jele.data.length > 0) {
+          formData.value[btnConfigCopy.prop][i][jele.prop + "Name"] = selectDataEcho(jele, formData.value[btnConfigCopy.prop][i][jele.prop]);
+        }
+      }
+    }
+  }
+};
 // 循环 label值回显
 const formDataShowLabel = () => {
   for (let i = 0; i < formConfig.value.length; i++) {
@@ -469,6 +510,21 @@ const formDataShowLabel = () => {
   }
 };
 
+const formDataShowLabelOne = () => {
+  for (let i = 0; i < formConfig.value.length; i++) {
+    const element = formConfig.value[i];
+    if (element.type === "picker" && element.itemType !== "datePicker") {
+      if (element.data && element.data.length > 0) {
+        formData.value[element.prop + "Name"] = selectDataEcho(element, formData.value[element.prop]);
+      }
+    } else if (element.type === "cascader" && element.itemType === "common") {
+      if (element.data && element.data.length > 0) {
+        formData.value[element.prop + "Name"] = selectDataEcho(element, formData.value[element.prop]);
+      }
+    }
+  }
+};
+
 const formDataInit = () => {
   var map = {
     input: "",
@@ -488,9 +544,11 @@ const formDataInit = () => {
     }
   }
   // 初始化默认值
+  let cityStatus = true;
   for (let i = 0; i < formConfig.value.length; i++) {
     const element = formConfig.value[i];
-    if (element.type === "cascader" && element.itemType === "city") {
+    if (element.type === "cascader" && element.itemType === "city" && cityStatus) {
+      cityStatus = false;
       cityOptionInit();
       // formData.value[element.prop] = map[element.type];
       // formData.value[element.prop + "Name"] = map[element.type];
@@ -571,9 +629,8 @@ const handlePush = () => {
 };
 // remove
 const handleRemove = (index, item) => {
-  console.log(item);
   if (item.deleteFn) {
-    item.deleteFn(index, item);
+    item.deleteFn(index);
   } else {
     formData.value[btnConfigCopy.prop].splice(index, 1);
   }
@@ -750,14 +807,40 @@ const changeCheckboxGroup = (form, label, data, fieldNames) => {
   }
   form[label + "Name"] = text;
 };
+const datePickerDateArr = ref([]);
+const datePickerTimeArr = ref([]);
+const datePickerTimeConfirm = (item, index) => {
+  formData.value[item.prop] = datePickerDateArr.value.join("-") + " " + datePickerTimeArr.value.join(":");
+  formConfig.value[index].showPicker = false;
+};
+const defaultTimeFn = (item, index) => {
+  datePickerDateArr.value = formatDate(new Date(formData.value[item.prop]), "yyyy-MM-dd").split("-");
+  datePickerTimeArr.value = formatDate(new Date(formData.value[item.prop]), "hh:mm:ss").split(":");
+  formConfig.value[index].showPicker = true;
+};
+const validateForm = async () => {
+  try {
+    const flag = await testForm.value.validate();
+    return flag
+  } catch (err) {
+    return true;
+  }
+};
+defineExpose({
+  formDataShowLabelOne,
+  formDataListShowLabelOne,
+  btnConfigCopy,
+  validateForm,
+});
 // onMounted(() => {});
 </script>
 
 <style lang="scss" scoped>
 .btn-box {
-  margin-top: 10px;
   width: 100%;
   text-align: center;
+  background: #f2f2f2;
+  padding: 10px 0;
 }
 .row {
   color: #999999;
@@ -782,7 +865,7 @@ const changeCheckboxGroup = (form, label, data, fieldNames) => {
     }
   }
   .van-form {
-    margin-top: 0px !important; 
+    margin-top: 0px !important;
   }
 }
 </style>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 916 - 900
src/lang/cn.js


+ 105 - 0
src/lang/cnCZ.js

@@ -0,0 +1,105 @@
+export function cnCZ() {
+  const cnCZ = {
+    claim: {
+      name: "到账认领",
+      accountName: "账户名称",
+      accountAmount: "到账金额",
+      accountTime: "到账时间",
+      oppositeAccount: "对方账户",
+      claimStatus: "认领状态",
+      accountInfo: "到账信息",
+      relatedContract: "关联合同",
+      contractCode: "合同编码",
+      relatedAmount: "关联金额",
+      contractCanNotBeEmpty: "合同不能为空",
+      relatedAmountCanNotBeEmpty: "关联金额不能为空",
+      addDetails: "请添加明细",
+      relatedAmountMustBeGreaterThanZero: "关联金额需大于零",
+      relatedAmountTotalNotBeGreaterThanAccountAmount: "关联金额总合不能大于到账金额",
+      cancelClaim: "取消认领",
+    },
+    arrivalQuality: {
+      name: "到货质检",
+      supplyName: "供应商",
+      productName: "物品名称",
+      productSpec: "规格型号",
+      arrivalNumber: "到货数量",
+      qualitySituation: "质检情况",
+      arrivalCode: "到货单号",
+      alreadyQualityNumber: "已质检数量",
+      qualityQualified: "质检合格",
+      qualityUnQualified: "质检不合格",
+      qualityQualifiedCanNotBeEmpty: "质检合格不能为空",
+      qualityUnQualifiedCanNotBeEmpty: "质检不合格不能为空",
+      qualityInspectionQuantityCannotBeZero: "质检数量不能为零",
+      qualityInspectionQuantityNotBeGreaterThanArrivalNumber: "质检数量加已质检数量不可大于到货数量",
+    },
+    inventoryCount: {
+      name: "库存盘点",
+      inventoryTime: "盘点时间",
+      inventoryPerson: "盘点人",
+      inventoryResult: "盘点结果",
+      inventoryWarehouse: "盘点仓库",
+      goodsName: "物品名称",
+      stockNumber: "库存数量",
+      inventoryNumber: "盘点数量",
+      inventoryWarehouseCanNotBeEmpty: '盘点仓库不能为空',
+      goodsNameCanNotBeEmpty: "物品名称不能为空",
+      inventoryNumberCanNotBeEmpty: "盘点数量不能为空",
+    },
+    purchasePayment: {
+      name: "采购付款",
+      sendPayment: "发起付款",
+      supplyName: "供应商",
+      applicationsTime: "申请时间",
+      applicationsAmount: "申请金额",
+      approvalStatus: "审批状态",
+      paymentStatus: "付款状态",
+      supplyName: "供应商",
+      paymentTerm: "付款期限",
+      paymentType: "付款类型",
+      prepaymentCode: "预付款单号",
+      paymentDescription: "付款说明",
+      documentNumber: "单据数量",
+      invoiceType: "发票类型",
+      taxRate: "税率",
+      totalPaymentAmount: "付款总金额",
+      paymentMethon: "付款方式",
+      paymentAccount: "付款账户",
+      accountName: "户名",
+      bankAccount: "银行账号",
+      bankOfDeposit: "开户银行",
+      interbankNumber: "联行号",
+      paymentDetails: "付款明细",
+      purchaseContract: "采购合同",
+      contractAmount: "合同金额",
+      paidAmount: "已付款金额",
+      paymentDescription: "款项说明",
+      paymentAmount: "付款金额",
+      supplyNameCanNotBeEmpty: '供应商不能为空',
+      paymentTypeCanNotBeEmpty: "付款类型不能为空",
+      prepaymentCodeCanNotBeEmpty: "预付款单号不能为空",
+      descriptionCanNotBeEmpty: "说明不能为空",
+      invoiceTypeCanNotBeEmpty: "发票类型不能为空",
+      taxRateCanNotBeEmpty: "税率不能为空",
+      purchaseContractCanNotBeEmpty: "采购合同不能为空",
+      paymentAmountCanNotBeEmpty: "付款金额不能为空",
+      paymentMethonCanNotBeEmpty: "付款方式不能为空",
+      paymentAccountCanNotBeEmpty: "付款账户不能为空",
+      accountNameCanNotBeEmpty: "户名不能为空",
+      pleaseAddPaymentDetails: "请添加付款明细",
+
+    },
+    receipt: {
+      name: "交接单",
+      mergePurchase: "合并采购",
+      belongToCompany: "归属公司",
+      contractCode: "合同编码",
+      orderTime: "下单时间",
+      productName: "产品名称",
+      pendingProcessing: "待处理",
+    }
+  };
+
+  return cnCZ;
+}

+ 334 - 0
src/lang/cnLXF.js

@@ -0,0 +1,334 @@
+export function cnLXF() {
+  const cnLXF = {
+    flowFunds: {
+      name: "资金流水",
+      company: "归属公司",
+      account: "资金账户",
+      amount: "交易金额",
+      amountMsg: "请输入交易金额",
+      tradingHour: "交易时间",
+      tradingHourMsg: "请选择交易时间",
+      digest: "摘要",
+      add: "添加流水",
+      edit: "编辑流水",
+      tradeInformation: "交易信息",
+      selectAccount: "选择账户",
+      selectAccountMsg: "请选择账户",
+      tradeType: "交易类型",
+      tradeTypeMsg: "请选择交易类型",
+      income: "收入",
+      disburse: "支出",
+      currency: "币种",
+      currencyMsg: "请选择币种",
+      contractArrival: "合同到账",
+      contractArrivalMsg: "请选择合同到账",
+      yes: "是",
+      no: "否",
+      peerInformation: "对方信息",
+      accountName: "账户名称",
+      bankDeposit: "开户银行",
+      bankAccountNumber: "银行账号",
+      otherInformation: "其他信息",
+      remark: "备注",
+    },
+    account: {
+      name: "资金账户",
+      company: "归属公司",
+      companyMsg: "请选择归属公司",
+      add: "添加账户",
+      edit: "编辑账户",
+      alias: "账户别名",
+      aliasMsg: "请输入账户别名",
+      openingBank: "开户银行",
+      openingBankMsg: "请输入开户银行",
+      accountName: "账户名",
+      accountNameMsg: "请输入账户名",
+      accountOpening: "银行账号",
+      accountOpeningMsg: "请输入银行账号",
+      interbankNumber: "联行号",
+      foreignExchange: "外汇信息",
+      beneficiaryName: "Beneficiary Name",
+      beneficiaryBank: "Beneficiary Bank",
+      beneficiaryBankAddress: "Beneficiary Bank Address",
+      beneficiaryAccountNumber: "Beneficiary Account Number",
+      swiftCode: "Swift Code",
+      beneficiaryAddress: "Beneficiary Address",
+      currency: "币种",
+      currencyMsg: "请选择币种",
+      remainder: "余额",
+      remainderMsg: "请输入余额",
+      accountBalance: "账户余额",
+      submitMsgOne: "请添加至少一条账户余额",
+      submitMsgTwo: "请勿重复添加货币余额",
+    },
+    customerFile: {
+      name: "客户档案",
+      customerName: "客户名称",
+      customerNameMsg: "请输入名称",
+      cityText: "所在城市",
+      customerStatus: "客户类型",
+      add: "添加客户",
+      address: "详细地址",
+      code: "客户代码",
+      source: "客户来源",
+      sourceMsg: "请选择客户来源",
+      status: "客户类型",
+      statusMsg: "请选择客户类型",
+      userId: "业务员",
+      tag: "客户标签",
+      cityMsg: "请选择城市",
+      emailMsg: "请输入邮箱",
+      submitMsg: "请添加联系人",
+      customerContact: "客户联系人",
+      contact: "联系人",
+      email: "电子邮箱",
+      detail: "客户详情",
+      followUpRecord: "添加跟进记录",
+      date: "跟进时间",
+      dateMsg: "请选择跟进时间",
+      customerName: "跟进人",
+      content: "跟进记录",
+      contentTwo: "跟进内容",
+      contentTwoMsg: "请输入跟进内容",
+      highseasName: "公海客户",
+      privateseaName: "私海客户",
+    },
+    accountPayment: {
+      name: "打款",
+      corporationName: "归属公司",
+      createTime: "请款时间",
+      currencyAmount: "请款金额",
+      paymentRemark: "请款说明",
+      statusText: "打款状态",
+      requestInformation: "请款信息",
+      businessManagementName: "付款账户",
+      paymentMethodText: "付款方式",
+      collectionName: "收款户名",
+      accountOpening: "银行账号",
+      openingBank: "开户银行",
+      interbankNumber: "联行号",
+      paymentInformation: "打款信息",
+      accountManagementId: "打款账户",
+      accountManagementIdMsg: "请选择打款账户",
+      currency: "打款币种",
+      currencyMsg: "请选择打款币种",
+      amount: "打款金额",
+      amountMsg: "请选择打款金额",
+      expensesTime: "打款时间",
+      expensesTimeMsg: "请选择打款时间",
+      remark: "摘要",
+    },
+    funds: {
+      name: "请款",
+      createTime: "请款时间",
+      currencyTotal: "请款金额",
+      paymentRemarks: "用款说明",
+      fundsText: "放款状态",
+      basicInformation: "基础信息",
+      claimDetails: "请款明细",
+      receiptPaymentInformation: "收付款信息",
+      corporationId: "归属公司",
+      corporationIdMsg: "请选择归属公司",
+      departmentId: "归属部门",
+      departmentIdMsg: "请选择归属部门",
+      type: "请款类型",
+      typeMsg: "请选择请款类型",
+      advanceId: "预支单",
+      advanceIdMsg: "请选择预支单",
+      currency: "币种",
+      currencyMsg: "请选择币种",
+      costType: "费用类型",
+      costTypeMsg: "请选择费用类型",
+      contractId: "关联合同",
+      contractIdMsg: "请选择关联合同",
+      amount: "请款金额",
+      amountMsg: "请选择请款金额",
+      remarks: "款项说明",
+      remarksMsg: "请选择款项说明",
+      total: "请款总额",
+      quantity: "单据张数",
+      quantityMsg: "请选择单据张数",
+      paymentMethod: "付款方式",
+      paymentMethodMsg: "请选择付款方式",
+      accountManagementId: "付款账户",
+      accountManagementIdMsg: "请选择付款账户",
+      username: "户名",
+      accountOpening: "银行账号",
+      openingBank: "开户银行",
+      interbankNumber: "联行号 / SWIFT Code",
+    },
+    contract: {
+      name: "销售合同",
+      sellCorporation: "归属公司",
+      contractType: "合同类型",
+      contractTypeMsg: "请选择合同类型",
+      code: "合同编码",
+      buyCorporation: "客户名称",
+      amount: "合同金额",
+      transactionInformation: "交易信息",
+      commodityInformation: "商品信息",
+      otherCharges: "其他收费",
+      deliveryInformation: "交付信息",
+      shipmentPlan: "出货计划",
+      contractTemplateId: "合同模板",
+      contractTemplateIdMsg: "请选择合同模板",
+      sellerInformation: "卖方信息",
+      buyerInformation: "买方信息",
+      sellCorporationId: "卖方公司",
+      sellCorporationIdMsg: "请选择卖方公司",
+      buyCorporationId: "买方公司",
+      buyCorporationIdMsg: "请选择买方公司",
+      cityText: "所在城市",
+      cityMsg: "请选择所在城市",
+      address: "详细地址",
+      addressMsg: "请输入详细地址",
+      contactName: "联系人",
+      contactNameMsg: "请输入联系人",
+      contactNumber: "联系电话",
+      contactNumberMsg: "请输入联系电话",
+      postalCode: "邮编",
+      postalCodeMsg: "请输入邮编",
+      productId: "商品名称",
+      productIdMsg: "请选择商品",
+      productName: "商品英文名",
+      productNameMsg: "请输入商品英文名",
+      productModel: "规格型号",
+      productModelMsg: "请输入规格型号",
+      quantity: "数量",
+      quantityMsg: "请输入数量",
+      price: "单价",
+      priceMsg: "请输入单价",
+      chargeItem: "收费项目",
+      chargeItemMsg: "请输入收费项目",
+      amount: "金额",
+      amountMsg: "请输入金额",
+      remark: "备注",
+      amountProduct: "合计金额",
+      amountProductPlaceholder: "根据报价明细自动统计",
+      amountProject: "合计金额",
+      amountProjectPlaceholder: "根据收费项目自动统计",
+      collectionInformation: "收款信息",
+      currency: "币种",
+      currencyMsg: "请选择币种",
+      amountAll: "报价总金额",
+      amountAllPlaceholder: "根据报价明细、收费项目自动统计",
+      paymentMethod: "付款方式",
+      paymentMethodMsg: "请选择付款方式",
+      advanceRatio: "预付款比例 (%)",
+      advanceRatioMsg: "请输入预付款比例",
+      shroffAccountId: "收款账号",
+      shroffAccountIdMsg: "请选择收款账号",
+      tradeMethods: "贸易方式",
+      tradeMethodsMsg: "请选择贸易方式",
+      transportMethod: "运输方式",
+      transportMethodMsg: "请选择运输方式",
+      transportRemark: "运输说明",
+      transportRemarkMsg: "请输入运输说明",
+      remarks: "付款条件",
+      remarksMsg: "请输入付款条件",
+      warranty: "质保期 (天)",
+      deliveryTime: "交货期限 (天)",
+      commodity: "商品",
+      productNamePlaceholder: "根据商品信息自动回填",
+      shipmentTime: "出货日期",
+      shipmentTimeMsg: "请选择出货日期",
+      quantityShipment: "出货数量",
+      productRepeat: "商品选择重复",
+      pleaseAddProduct: "请添加商品",
+    },
+    priceSheet: {
+      name: "报价单",
+      sellCorporation: "归属公司",
+      code: "报价单号",
+      buyCorporation: "客户名称",
+      amount: "报价金额",
+      status: "审批状态",
+      transactionInformation: "交易信息",
+      quotationDetails: "报价明细",
+      commodityInformation: "商品信息",
+      otherCharges: "其他收费",
+      otherInformation: "其他信息",
+      contractTemplateId: "合同模板",
+      contractTemplateIdMsg: "请选择合同模板",
+      sellerInformation: "卖方信息",
+      buyerInformation: "买方信息",
+      sellCorporationId: "卖方公司",
+      sellCorporationIdMsg: "请选择卖方公司",
+      buyCorporationId: "买方公司",
+      buyCorporationIdMsg: "请选择买方公司",
+      cityText: "所在城市",
+      cityMsg: "请选择所在城市",
+      address: "详细地址",
+      addressMsg: "请输入详细地址",
+      contactName: "联系人",
+      contactNameMsg: "请输入联系人",
+      contactNumber: "联系电话",
+      contactNumberMsg: "请输入联系电话",
+      postalCode: "邮编",
+      postalCodeMsg: "请输入邮编",
+      productId: "商品名称",
+      productIdMsg: "请选择商品",
+      productName: "商品英文名",
+      productNameMsg: "请输入商品英文名",
+      productModel: "规格型号",
+      productModelMsg: "请输入规格型号",
+      quantity: "数量",
+      quantityMsg: "请输入数量",
+      price: "单价",
+      priceMsg: "请输入单价",
+      chargeItem: "收费项目",
+      chargeItemMsg: "请输入收费项目",
+      amount: "金额",
+      amountMsg: "请输入金额",
+      remark: "备注",
+      productRepeat: "商品选择重复",
+      pleaseAddProduct: "请添加商品",
+      amountProduct: "合计金额",
+      amountProductPlaceholder: "根据报价明细自动统计",
+      amountProject: "合计金额",
+      amountProjectPlaceholder: "根据收费项目自动统计",
+      quotedAmount: "报价金额",
+      currency: "币种",
+      currencyMsg: "请选择币种",
+      amountAll: "报价总金额",
+      amountAllPlaceholder: "根据报价明细、收费项目自动统计",
+      effective: "报价有效期 (天)",
+      effectiveMsg: "请输入报价有效期",
+      paymentMethod: "付款方式",
+      paymentMethodMsg: "请选择付款方式",
+      advanceRatio: "预付款比例 (%)",
+      advanceRatioMsg: "请输入预付款比例",
+      deliveryInformation: "交付信息",
+      tradeMethods: "贸易方式",
+      tradeMethodsMsg: "请选择贸易方式",
+      transportMethod: "运输方式",
+      transportMethodMsg: "请选择运输方式",
+      transportRemark: "运输说明",
+      transportRemarkMsg: "请输入运输说明",
+      remarks: "付款条件",
+      remarksMsg: "请输入付款条件",
+      warranty: "质保期 (天)",
+    },
+    invoice: {
+      name: "发票管理",
+      supplyName: "供应商",
+      supplyNameMsg: " 请选择供应商",
+      type: "发票类型",
+      typeMsg: "请选择发票类型",
+      money: "发票金额",
+      add: "添加发票",
+      edit: "编辑发票",
+      invoiceAmount: "开票金额",
+      invoiceAmountMsg: "请输入开票金额",
+      purchaseContract: "采购合同",
+      contractCode: "合同编号",
+      contractMoney: "合同金额",
+      receivedInvoice: "已收发票",
+      relatedAmount: "关联金额",
+      relatedAmountMsg: "请输入关联金额",
+      supplierNoContract: "该供应商暂无关联合同",
+      unequalAmounts: "开票金额不等于关联金额",
+    },
+  };
+  return cnLXF;
+}

+ 29 - 27
src/main.js

@@ -1,32 +1,34 @@
-import {
-  createApp
-} from 'vue'
-import App from './App.vue'
-import router from './router'
-import i18n from '@/lang/'
-import {
-  moneyFormat,
-  getDictOne,
-  compareTime
-} from '@/utils/util'
-const app = createApp(App)
-app.use(router)
-app.use(i18n).mount('#app')
-import { uploadDdRightBtn } from '@/utils/ddAdapter'
-import {
-  post,
-  get
-} from '@/utils/axios'
+import { createApp } from "vue";
+import App from "./App.vue";
+import router from "./router";
+import i18n from "@/lang/";
+import { moneyFormat, getDictOne, compareTime, dictValueLabel, formChange, formChangeTwo } from "@/utils/util";
+const app = createApp(App);
+app.use(router);
+app.use(i18n).mount("#app");
+import { uploadDdRightBtn } from "@/utils/ddAdapter";
+import { post, get } from "@/utils/axios";
 
-app.config.globalProperties.get = get
-app.config.globalProperties.post = post
+import store from './store'
+
+app.config.globalProperties.get = get;
+app.config.globalProperties.post = post;
 // 金额千分符
-app.config.globalProperties.moneyFormat = moneyFormat
+app.config.globalProperties.moneyFormat = moneyFormat;
 // 获取字典
-app.config.globalProperties.getDictOne = getDictOne
+app.config.globalProperties.getDictOne = getDictOne;
+// 字典回显
+app.config.globalProperties.dictValueLabel = dictValueLabel;
 // 比较时间大小
-app.config.globalProperties.compareTime = compareTime
-app.config.globalProperties.uploadDdRightBtn = uploadDdRightBtn
+app.config.globalProperties.compareTime = compareTime;
+app.config.globalProperties.uploadDdRightBtn = uploadDdRightBtn;
+// form组件 select change事件回填
+app.config.globalProperties.formChange = formChange;
+app.config.globalProperties.formChangeTwo = formChangeTwo;
+//pinia
+app.use(store);
+
+
 //中英文全局挂载
-app.config.globalProperties.t = i18n.global.t
-export default app
+app.config.globalProperties.t = i18n.global.t;
+export default app;

+ 41 - 0
src/router/jxskRouter.js

@@ -69,6 +69,47 @@ export function jxskRouter() {
       name: "jxsk_查看库位",
       component: () => import("../views/JXSK/inventoryQuery/kuwei.vue"),
     },
+    // 以下为基本菜单
+    {
+      path: "claim",
+      name: "到账认领",
+      component: () => import("../views/salesContract/claim/index.vue"),
+    },
+    {
+      path: "claimAdd",
+      name: "到账认领添加",
+      component: () => import("../views/salesContract/claim/add.vue"),
+    },
+    {
+      path: "arrival",
+      name: "到货质检",
+      component: () => import("../views/procurementManagement/arrival/index.vue"),
+    },
+    {
+      path: "arrivalAdd",
+      name: "到货质检添加",
+      component: () => import("../views/procurementManagement/arrival/add.vue"),
+    },
+    {
+      path: 'inventoryCount',
+      name: '库存盘点',
+      component: () => import('../views/purchase-sales/inventory-management/Inventory/index.vue')
+    },
+    {
+      path: 'inventoryCountAdd',
+      name: '库存盘点添加',
+      component: () => import('../views/purchase-sales/inventory-management/Inventory/add.vue')
+    },
+    {
+      path: 'purchasePayment',
+      name: '采购付款',
+      component: () => import('../views/procurementManagement/payment/index.vue')
+    },
+    {
+      path: 'receipt',
+      name: '交接单',
+      component: () => import('../views/procurementManagement/receipt/index.vue')
+    },
 
   ];
   return jxskRouter;

+ 80 - 0
src/router/routerLXF.js

@@ -135,6 +135,86 @@ export function routesLXF() {
       name: "请款",
       component: () => import("../views/fund/funds/index.vue"),
     },
+    {
+      path: "priceSheet",
+      name: "报价单",
+      component: () => import("../views/salesContract/priceSheet/index.vue"),
+    },
+    {
+      path: "contract",
+      name: "销售合同",
+      component: () => import("../views/salesContract/contract/index.vue"),
+    },
+    {
+      path: "invoice",
+      name: "发票管理",
+      component: () => import("../views/purchase-payment/invoice/index.vue"),
+    },
+    {
+      path: "invoiceAdd",
+      name: "添加发票",
+      component: () => import("../views/purchase-payment/invoice/add.vue"),
+    },
+    {
+      path: "account",
+      name: "资金账户",
+      component: () => import("../views/fund/account/index.vue"),
+    },
+    {
+      path: "accountAdd",
+      name: "添加账户",
+      component: () => import("../views/fund/account/add.vue"),
+    },
+    {
+      path: "customerFile",
+      name: "客户档案",
+      component: () => import("../views/customer/file/index.vue"),
+    },
+    {
+      path: "customerFileAdd",
+      name: "添加客户",
+      component: () => import("../views/customer/file/add.vue"),
+    },
+    {
+      path: "customerFileDetail",
+      name: "客户详情",
+      component: () => import("../views/customer/file/detail.vue"),
+    },
+    {
+      path: "customerFileRecords",
+      name: "添加跟进记录",
+      component: () => import("../views/customer/file/addRecords.vue"),
+    },
+    {
+      path: "highseas",
+      name: "公海客户",
+      component: () => import("../views/customer/highseas/index.vue"),
+    },
+    {
+      path: "privatesea",
+      name: "私海客户",
+      component: () => import("../views/customer/privatesea/index.vue"),
+    },
+    {
+      path: "accountPayment",
+      name: "打款",
+      component: () => import("../views/fund/account-payment/index.vue"),
+    },
+    {
+      path: "accountPaymentAdd",
+      name: "添加打款",
+      component: () => import("../views/fund/account-payment/add.vue"),
+    },
+    {
+      path: "accountPaymentDetail",
+      name: "打款详情",
+      component: () => import("../views/fund/account-payment/detail.vue"),
+    },
+    {
+      path: "funds",
+      name: "请款",
+      component: () => import("../views/fund/funds/index.vue"),
+    },
   ];
   return routesLXF;
 }

+ 3 - 0
src/store/index.js

@@ -0,0 +1,3 @@
+import { createPinia } from "pinia";
+const store = createPinia();
+export default store;

+ 36 - 5
src/utils/util.js

@@ -1,7 +1,4 @@
-import {
-  post,
-  get
-} from '@/utils/axios'
+import { post, get } from "@/utils/axios";
 export function getDictOne(key) {
   return new Promise((resolve, reject) => {
     let dictObj = {};
@@ -67,4 +64,38 @@ export function compareTime(date1, date2) {
   } else {
     return false; //第二个大
   }
-}
+}
+
+//根据value值回显字典label值
+export function dictValueLabel(value, arr) {
+  if ((value || value === 0) && arr) {
+    const current = arr.filter((x) => x.value == value);
+    if (current && current.length > 0) {
+      return current[0].label;
+    }
+    return "";
+  }
+  return "";
+}
+
+// form组件 formConfig select change事件回填
+export function formChange(val, data, formData) {
+  formData.data[data.prop] = val.selectedValues[0];
+  let list = data.data.filter((item) => item[data.fieldNames.value] == val.selectedValues[0]);
+  if (list && list.length > 0) {
+    formData.data[data.prop + "Name"] = list[0][data.fieldNames.text];
+  } else {
+    formData.data[data.prop + "Name"] = "";
+  }
+}
+
+// form组件 formOption select change事件回填
+export function formChangeTwo(val, data, index, indexTwo, propName, formData) {
+  formData.data[propName][index][data.prop] = val.selectedValues[0];
+  let list = data.data.filter((item) => item[data.fieldNames.value] == val.selectedValues[0]);
+  if (list && list.length > 0) {
+    formData.data[propName][index][data.prop + "Name"] = list[0][data.fieldNames.text];
+  } else {
+    formData.data[propName][index][data.prop + "Name"] = "";
+  }
+}

+ 1 - 1
src/views/customer/highseas/index.vue

@@ -28,7 +28,7 @@ const onClickRight = () => {
 const req = ref({
   pageNum: 1,
   keyword: null,
-  type: 0
+  type: 0,
 });
 const finished = ref(false);
 const onRefresh = () => {

+ 105 - 106
src/views/fund/flow-of-funds/index.vue

@@ -1,110 +1,109 @@
 <template>
-    <van-nav-bar :title="$t('flowFunds.name')" left-text="" left-arrow @click-left="onClickLeft" @click-right="onClickRight">
-      <template #right>{{ $t("common.add") }}</template>
-    </van-nav-bar>
-    <van-search v-model="req.keyword" :placeholder="$t('common.pleaseEnterKeywords')" @search="onRefresh" />
-    <van-pull-refresh v-model="loading" @refresh="onRefresh">
-      <div class="list">
-        <van-list v-model:loading="loading" :finished="finished" :finished-text="$t('common.noMore')" @load="getList" style="margin-bottom: 60px">
-          <commonList :data="listData" @onClick="toDtl" :config="listConfig"></commonList>
-        </van-list>
-      </div>
-    </van-pull-refresh>
-  </template>
-  <script setup>
-  import { ref, getCurrentInstance } from "vue";
-  import commonList from "@/components/common-list.vue";
-  
-  const proxy = getCurrentInstance().proxy;
-  const onClickLeft = () => proxy.$router.push("/main/working");
-  const onClickRight = () => {
-    proxy.$router.push({
-      path: "flowOfFundsAdd",
-      query: {
-        type: "add",
-      },
-    });
-  };
-  const req = ref({
-    pageNum: 1,
-    keyword: null,
+  <van-nav-bar :title="$t('flowFunds.name')" left-text="" left-arrow @click-left="onClickLeft" @click-right="onClickRight">
+    <template #right>{{ $t("common.add") }}</template>
+  </van-nav-bar>
+  <van-search v-model="req.keyword" :placeholder="$t('common.pleaseEnterKeywords')" @search="onRefresh" />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list v-model:loading="loading" :finished="finished" :finished-text="$t('common.noMore')" @load="getList" style="margin-bottom: 60px">
+        <commonList :data="listData" @onClick="toDtl" :config="listConfig"></commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const onClickRight = () => {
+  proxy.$router.push({
+    path: "flowOfFundsAdd",
+    query: {
+      type: "add",
+    },
   });
-  const finished = ref(false);
-  const onRefresh = () => {
-    req.value.pageNum = 1;
-    finished.value = false;
-    getList("refresh");
-  };
-  const loading = ref(false);
-  const listData = ref([]);
-  const getList = (type) => {
-    loading.value = true;
-    proxy
-      .post("/accountRunningWater/page", req.value)
-      .then((res) => {
-        if (res.data.rows && res.data.rows.length > 0) {
-          res.data.rows = res.data.rows.map((item) => {
-            let status = "";
-            let style = "color: #04cb04";
-            if (item.status == 20) {
-              status = "-";
-              style = "color: red";
-            }
-            return {
-              ...item,
-              currencyAmount: item.currency + " " + status + item.amount,
-              style: style,
-            };
-          });
-        }
-        listData.value = type === "refresh" ? res.data.rows : listData.value.concat(res.data.rows);
-        if (req.value.pageNum * 10 >= res.data.total) {
-          finished.value = true;
-        }
-        req.value.pageNum++;
-        loading.value = false;
-      })
-      .catch(() => {
-        loading.value = false;
-      });
-  };
-  const toDtl = (row) => {
-    proxy.$router.push({
-      path: "flowOfFundsAdd",
-      query: {
-        id: row.id,
-        type: "edit",
-      },
+};
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+});
+const finished = ref(false);
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/accountRunningWater/page", req.value)
+    .then((res) => {
+      if (res.data.rows && res.data.rows.length > 0) {
+        res.data.rows = res.data.rows.map((item) => {
+          let status = "";
+          let style = "color: #04cb04";
+          if (item.status == 20) {
+            status = "-";
+            style = "color: red";
+          }
+          return {
+            ...item,
+            currencyAmount: item.currency + " " + status + item.amount,
+            style: style,
+          };
+        });
+      }
+      listData.value = type === "refresh" ? res.data.rows : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
     });
-  };
-  const listConfig = ref([
-    {
-      label: proxy.t("flowFunds.company"),
-      prop: "corporationName",
-    },
-    {
-      label: proxy.t("flowFunds.account"),
-      prop: "accountManagementName",
-    },
-    {
-      label: proxy.t("flowFunds.amount"),
-      prop: "currencyAmount",
-      style: "style",
+};
+const toDtl = (row) => {
+  proxy.$router.push({
+    path: "flowOfFundsAdd",
+    query: {
+      id: row.id,
+      type: "edit",
     },
-    {
-      label: proxy.t("flowFunds.tradingHour"),
-      prop: "transactionTime",
-    },
-    {
-      label: proxy.t("flowFunds.digest"),
-      prop: "remarks",
-    },
-  ]);
-  </script>
-  
-  <style lang="scss" scoped>
-  .list {
-    min-height: 70vh;
-  }
-  </style>
-  
+  });
+};
+const listConfig = ref([
+  {
+    label: proxy.t("flowFunds.company"),
+    prop: "corporationName",
+  },
+  {
+    label: proxy.t("flowFunds.account"),
+    prop: "accountManagementName",
+  },
+  {
+    label: proxy.t("flowFunds.amount"),
+    prop: "currencyAmount",
+    style: "style",
+  },
+  {
+    label: proxy.t("flowFunds.tradingHour"),
+    prop: "transactionTime",
+  },
+  {
+    label: proxy.t("flowFunds.digest"),
+    prop: "remarks",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 14 - 21
src/views/fund/funds/index.vue

@@ -18,12 +18,12 @@ import commonList from "@/components/common-list.vue";
 const proxy = getCurrentInstance().proxy;
 const onClickLeft = () => proxy.$router.push("/main/working");
 const onClickRight = () => {
-  // proxy.$router.push({
-  //   path: "flowOfFundsAdd",
-  //   query: {
-  //     type: "add",
-  //   },
-  // });
+  proxy.$router.push({
+    path: "/main/processDtl",
+    query: {
+      flowKey: "account_request_funds_flow",
+    },
+  });
 };
 const req = ref({
   pageNum: 1,
@@ -76,21 +76,14 @@ const getList = (type) => {
     });
 };
 const toDtl = (row) => {
-  // if (row.status == "10") {
-  //   proxy.$router.push({
-  //     path: "accountPaymentDetail",
-  //     query: {
-  //       id: row.id,
-  //     },
-  //   });
-  // } else if (row.status == "20") {
-  //   proxy.$router.push({
-  //     path: "accountPaymentAdd",
-  //     query: {
-  //       id: row.id,
-  //     },
-  //   });
-  // }
+  // proxy.$router.push({
+  //   path: "/main/processDtl",
+  //   query: {
+  //     flowKey: "account_request_funds_flow",
+  //     id: row.flowInfoId,
+  //     processType: 20,
+  //   },
+  // });
 };
 const listConfig = ref([
   {

+ 1 - 3
src/views/login.vue

@@ -216,18 +216,16 @@ const ddLoginInit = () => {
 			corpId: route.query.id, // 企业id
 			onSuccess: function (info) {
 				code.value = info.code
-				
 				proxy
 					.post('/open/dingApi/getUserToken', { code: code.value,corpId:route.query.id })
 					.then((res) => {
 						window.localStorage.setItem('corpId',route.query.id)
-						
 						setToken(res.data)
 						getInfo()
 					})
 			},
 			onFail: function (err) {
-			
+				
 			},
 		})
 	})

+ 6 - 1
src/views/main.vue

@@ -3,7 +3,7 @@
 		<router-view />
 		<div class="footer"></div>
 	</div>
-	<van-tabbar v-model="tabType">
+	<van-tabbar v-model="tabType" v-if="routerName != '/main/processDtl'">
 		<van-tabbar-item icon="home-o" to="/main/message">{{$t('common.message')}}</van-tabbar-item>
 		<van-tabbar-item icon="search" to="/main/working"
 			>{{$t('common.workbench')}}</van-tabbar-item
@@ -47,9 +47,14 @@ if (isDev) {
 	}
 }
 const corpId = window.localStorage.getItem('corpId')
+let routerName = ref(null)
 //监听路由变化
 const router = useRouter()
+//获取当前path
+routerName.value = router.currentRoute.value.path
 watch(router.currentRoute, (to, from) => {
+	routerName.value = to.path
+	console.log('routerName', routerName.value)
 	//滚动条回到顶部
 	document.documentElement.scrollTop = 0
 	if (!corpId) return

+ 888 - 0
src/views/processApproval/components/Contract.vue

@@ -0,0 +1,888 @@
+<template>
+  <div class="form">
+    <van-tabs v-model:active="active">
+      <van-tab :title="proxy.t('contract.transactionInformation')" />
+      <van-tab :title="proxy.t('contract.commodityInformation')" />
+      <van-tab :title="proxy.t('contract.otherCharges')" />
+      <van-tab :title="proxy.t('contract.deliveryInformation')" />
+      <van-tab :title="proxy.t('contract.shipmentPlan')" />
+      <div class="common-process-card" v-show="active == 0">
+        <div class="common-title">{{ proxy.t("contract.transactionInformation") }}</div>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formConfig" :rules="rules" ref="formDom1"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 1">
+        <div class="common-title">{{ proxy.t("contract.commodityInformation") }}</div>
+        <testForm v-model="formData.data" :formOption="formGoodsOption" :formConfig="formEmptyConfig" :rules="rules" ref="formDom2"> </testForm>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formAmountProductConfig" :rules="rules" ref="formDom3"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 2">
+        <div class="common-title">{{ proxy.t("contract.otherCharges") }}</div>
+        <testForm v-model="formData.data" :formOption="formProjectOption" :formConfig="formEmptyConfig" :rules="rules" ref="formDom4"> </testForm>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formAmountProjectConfig" :rules="rules" ref="formDom5"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 3">
+        <div class="common-title">{{ proxy.t("contract.deliveryInformation") }}</div>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formDeliveryConfig" :rules="rulesTwo" ref="formDom6"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 4">
+        <div class="common-title">{{ proxy.t("contract.shipmentPlan") }}</div>
+        <testForm v-model="formData.data" :formOption="formShipmentOption" :formConfig="formEmptyConfig" :rules="rulesTwo" ref="formDom7"> </testForm>
+      </div>
+    </van-tabs>
+  </div>
+</template>
+
+<script setup>
+import { ref, getCurrentInstance, onMounted, defineProps, defineExpose, watch, reactive } from "vue";
+import { useRoute } from "vue-router";
+import testForm from "@/components/testForm/index.vue";
+import { getUserInfo } from "@/utils/auth";
+import { showFailToast } from "vant";
+
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const active = ref(0);
+const formData = reactive({
+  data: {
+    contractType: "1",
+    contractProductList: [],
+    contractProjectList: [],
+    contractShipmentList: [],
+  },
+});
+const formDom1 = ref(null);
+const formDom2 = ref(null);
+const formDom3 = ref(null);
+const formDom4 = ref(null);
+const formDom5 = ref(null);
+const formDom6 = ref(null);
+const formDom7 = ref(null);
+const formOption = reactive({
+  readonly: false,
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+});
+const formConfig = reactive([
+  {
+    type: "picker",
+    label: proxy.t("contract.contractType"),
+    prop: "contractType",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "picker",
+    label: proxy.t("contract.contractTemplateId"),
+    prop: "contractTemplateId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: (val, data) => {
+      proxy.formChange(val, data, formData);
+      formData.data.sellCorporationId = "";
+      formData.data.sellCountryName = "";
+      formData.data.sellProvinceName = "";
+      formData.data.sellCityName = "";
+      formData.data.sellAddress = "";
+      formData.data.sellContactName = "";
+      formData.data.sellContactNumber = "";
+      if (val.selectedValues[0]) {
+        proxy.post("/contractTemplate/detail", { id: val.selectedValues[0] }).then((res) => {
+          formData.data.sellCorporationId = res.data.corporationId;
+          if (res.data.corporationId) {
+            proxy.post("/corporation/detail", { id: res.data.corporationId }).then((detailCorporation) => {
+              let sellCity = "";
+              if (detailCorporation.data.countryEnStr) {
+                formData.data.sellCountryName = detailCorporation.data.countryEnStr;
+                sellCity = detailCorporation.data.countryEnStr;
+              }
+              if (detailCorporation.data.provinceEnStr) {
+                formData.data.sellProvinceName = detailCorporation.data.provinceEnStr;
+                sellCity = sellCity + " " + detailCorporation.data.provinceEnStr;
+              }
+              if (detailCorporation.data.cityEnStr) {
+                formData.data.sellCityName = detailCorporation.data.cityEnStr;
+                sellCity = sellCity + " " + detailCorporation.data.cityEnStr;
+              }
+              if (detailCorporation.data.addressEn) {
+                formData.data.sellAddress = detailCorporation.data.addressEn;
+              }
+              formData.data.sellCity = sellCity;
+              formDom1.value.formDataShowLabelOne();
+            });
+          }
+          formData.data.sellContactName = res.data.contactName;
+          formData.data.sellContactNumber = res.data.contactNumber;
+          formDom1.value.formDataShowLabelOne();
+        });
+      }
+      data.showPicker = false;
+    },
+  },
+  {
+    type: "title",
+    title: proxy.t("contract.sellerInformation"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("contract.sellCorporationId"),
+    prop: "sellCorporationId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.cityText"),
+    prop: "sellCity",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.address"),
+    prop: "sellAddress",
+    itemType: "textarea",
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.contactName"),
+    prop: "sellContactName",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.contactNumber"),
+    prop: "sellContactNumber",
+    itemType: "text",
+  },
+  {
+    type: "title",
+    title: proxy.t("contract.buyerInformation"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("contract.buyCorporationId"),
+    prop: "buyCorporationId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: (val, data) => {
+      proxy.formChange(val, data, formData);
+      formData.data.buyContactName = "";
+      formData.data.buyContactNumber = "";
+      if (val.selectedValues[0]) {
+        proxy.post("/customer/detail", { id: val.selectedValues[0] }).then((res) => {
+          if (res.data.customerUserList && res.data.customerUserList.length > 0) {
+            formData.data.buyContactName = res.data.customerUserList[0].name;
+            if (res.data.customerUserList[0].contactJson) {
+              let contactJson = JSON.parse(res.data.customerUserList[0].contactJson);
+              if (contactJson && contactJson.length > 0) {
+                formData.data.buyContactNumber = contactJson[0].contactNo;
+              }
+            }
+          }
+          let cityName = "";
+          if (res.data.countryName) {
+            cityName = res.data.countryName;
+            if (res.data.provinceName) {
+              cityName = cityName + " " + res.data.provinceName;
+              if (res.data.cityName) {
+                cityName = cityName + " " + res.data.cityName;
+              }
+            }
+          }
+          formData.data.cityName = cityName;
+          if (res.data.cityId) {
+            formData.data.city = res.data.cityId;
+          } else if (res.data.provinceId) {
+            formData.data.city = res.data.provinceId;
+          } else if (res.data.countryId) {
+            formData.data.city = res.data.countryId;
+          } else {
+            formData.data.city = "";
+          }
+          formData.data.countryId = res.data.countryId;
+          formData.data.provinceId = res.data.provinceId;
+          formData.data.cityId = res.data.cityId;
+          formData.data.buyPostalCode = res.data.zipCode;
+          formData.data.buyAddress = res.data.address;
+        });
+      } else {
+        formData.data.countryId = "";
+        formData.data.provinceId = "";
+        formData.data.cityId = "";
+        formData.data.buyPostalCode = "";
+        formData.data.buyAddress = "";
+      }
+      data.showPicker = false;
+    },
+  },
+  {
+    type: "cascader",
+    label: proxy.t("contract.cityText"),
+    prop: "city",
+    itemType: "city",
+    showPicker: false,
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.address"),
+    prop: "buyAddress",
+    itemType: "textarea",
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.postalCode"),
+    prop: "buyPostalCode",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.contactName"),
+    prop: "buyContactName",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.contactNumber"),
+    prop: "buyContactNumber",
+    itemType: "text",
+  },
+]);
+const formGoodsOption = reactive({
+  readonly: false,
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+  btnConfig: {
+    isNeed: true,
+    prop: "contractProductList",
+    plain: true,
+    listTitle: proxy.t("contract.commodityInformation"),
+    listConfig: [
+      {
+        type: "picker",
+        label: proxy.t("contract.productId"),
+        prop: "productId",
+        itemType: "onePicker",
+        showPicker: false,
+        readonly: false,
+        fieldNames: {
+          text: "label",
+          value: "value",
+        },
+        data: [],
+        changeFn: (val, data, index, indexTwo, propName) => {
+          let selectList = formData.data[propName].filter((item, itemIndex) => item[data.prop] === val.selectedValues[0] && itemIndex !== index);
+          if (selectList && selectList.length > 0) {
+            return showFailToast(proxy.t("contract.productRepeat"));
+          }
+          formData.data[propName][index][data.prop] = val.selectedValues[0];
+          formData.data.contractShipmentList[index][data.prop] = val.selectedValues[0];
+          let list = data.data.filter((item) => item[data.fieldNames.value] == val.selectedValues[0]);
+          if (list && list.length > 0) {
+            formData.data[propName][index][data.prop + "Name"] = list[0][data.fieldNames.text];
+            let name = list[0].name;
+            if (list[0].standardJson) {
+              let standardJson = JSON.parse(list[0].standardJson);
+              if (standardJson && standardJson.englishName) {
+                name = standardJson.englishName;
+              }
+            }
+            formData.data[propName][index].productName = name;
+            formData.data[propName][index].productModel = list[0].spec;
+            formData.data.contractShipmentList[index].productName = name;
+          } else {
+            formData.data[propName][index][data.prop + "Name"] = "";
+          }
+          formData.data[propName][index].quantity = null;
+          formData.data[propName][index].price = null;
+          formData.data[propName][index].amount = null;
+          formData.data[propName][index].remark = null;
+          formData.data.contractShipmentList[index].shipmentTime = null;
+          formData.data.contractShipmentList[index].quantity = null;
+          formData.data.contractShipmentList[index].remark = null;
+          data.showPicker = false;
+        },
+      },
+      {
+        type: "input",
+        label: proxy.t("contract.productName"),
+        prop: "productName",
+        itemType: "text",
+      },
+      {
+        type: "input",
+        label: proxy.t("contract.productModel"),
+        prop: "productModel",
+        itemType: "text",
+      },
+      {
+        type: "input",
+        label: proxy.t("contract.quantity"),
+        prop: "quantity",
+        itemType: "number",
+        changeFn: () => {
+          calculatedAmount();
+        },
+      },
+      {
+        type: "input",
+        label: proxy.t("contract.price"),
+        prop: "price",
+        itemType: "number",
+        changeFn: () => {
+          calculatedAmount();
+        },
+      },
+    ],
+    clickFn: () => {
+      if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+        formData.data.contractProductList.push({
+          productId: null,
+          productName: null,
+          productModel: null,
+          quantity: null,
+          price: null,
+          amount: null,
+          remark: null,
+        });
+        formData.data.contractShipmentList.push({
+          productId: null,
+          productName: null,
+          shipmentTime: null,
+          quantity: null,
+          remark: null,
+        });
+      } else {
+        formData.data.contractProductList = [
+          {
+            productId: null,
+            productName: null,
+            productModel: null,
+            quantity: null,
+            price: null,
+            amount: null,
+            remark: null,
+          },
+        ];
+        formData.data.contractShipmentList = [
+          {
+            productId: null,
+            productName: null,
+            shipmentTime: null,
+            quantity: null,
+            remark: null,
+          },
+        ];
+      }
+    },
+    deleteFn: (index) => {
+      formData.data.contractProductList.splice(index, 1);
+      formData.data.contractShipmentList.splice(index, 1);
+      handleChangeAmount();
+    },
+  },
+});
+const formEmptyConfig = reactive([]);
+const formAmountProductConfig = reactive([
+  {
+    type: "input",
+    label: proxy.t("contract.amountProduct"),
+    prop: "amountProduct",
+    itemType: "text",
+    readonly: true,
+    placeholder: proxy.t("contract.amountProductPlaceholder"),
+  },
+]);
+const formAmountProjectConfig = reactive([
+  {
+    type: "input",
+    label: proxy.t("contract.amountProject"),
+    prop: "amountProject",
+    itemType: "text",
+    readonly: true,
+    placeholder: proxy.t("contract.amountProjectPlaceholder"),
+  },
+]);
+const formProjectOption = reactive({
+  readonly: false,
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+  btnConfig: {
+    isNeed: true,
+    prop: "contractProjectList",
+    plain: true,
+    listTitle: proxy.t("contract.chargeItem"),
+    listConfig: [
+      {
+        type: "input",
+        label: proxy.t("contract.chargeItem"),
+        prop: "payName",
+        itemType: "text",
+      },
+      {
+        type: "input",
+        label: proxy.t("contract.amount"),
+        prop: "amount",
+        itemType: "number",
+        changeFn: () => {
+          handleChangeAmount();
+        },
+      },
+      {
+        type: "input",
+        label: proxy.t("contract.remark"),
+        prop: "remark",
+        itemType: "textarea",
+      },
+    ],
+    clickFn: () => {
+      if (formData.data.contractProjectList && formData.data.contractProjectList.length > 0) {
+        formData.data.contractProjectList.push({
+          payName: null,
+          amount: null,
+          remark: null,
+        });
+      } else {
+        formData.data.contractProjectList = [
+          {
+            payName: null,
+            amount: null,
+            remark: null,
+          },
+        ];
+      }
+    },
+    deleteFn: (index) => {
+      formData.data.contractProjectList.splice(index, 1);
+      handleChangeAmount();
+    },
+  },
+});
+const formDeliveryConfig = reactive([
+  {
+    type: "title",
+    title: proxy.t("contract.collectionInformation"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("contract.currency"),
+    prop: "currency",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.amountAll"),
+    prop: "amount",
+    itemType: "text",
+    readonly: true,
+    placeholder: proxy.t("contract.amountAllPlaceholder"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("contract.paymentMethod"),
+    prop: "paymentMethod",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.advanceRatio"),
+    prop: "advanceRatio",
+    itemType: "number",
+    inputFn: (val) => {
+      if (val) {
+        if (val > 100) {
+          formData.data.advanceRatio = 100;
+        } else if (val < 0) {
+          formData.data.advanceRatio = 0;
+        }
+      }
+    },
+  },
+  {
+    type: "picker",
+    label: proxy.t("contract.shroffAccountId"),
+    prop: "shroffAccountId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "title",
+    title: proxy.t("contract.deliveryInformation"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("contract.tradeMethods"),
+    prop: "tradeMethods",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "picker",
+    label: proxy.t("contract.transportMethod"),
+    prop: "transportMethod",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.transportRemark"),
+    prop: "transportRemark",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.remarks"),
+    prop: "remark",
+    itemType: "textarea",
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.warranty"),
+    prop: "warranty",
+    itemType: "digit",
+  },
+  {
+    type: "input",
+    label: proxy.t("contract.deliveryTime"),
+    prop: "deliveryTime",
+    itemType: "digit",
+  },
+]);
+const formShipmentOption = reactive({
+  readonly: false,
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+  btnConfig: {
+    isNeed: false,
+    prop: "contractShipmentList",
+    plain: true,
+    listTitle: proxy.t("contract.commodity"),
+    listConfig: [
+      {
+        type: "input",
+        label: proxy.t("contract.productName"),
+        prop: "productName",
+        itemType: "text",
+        readonly: true,
+        placeholder: proxy.t("contract.productNamePlaceholder"),
+      },
+      {
+        type: "picker",
+        label: proxy.t("contract.shipmentTime"),
+        prop: "shipmentTime",
+        itemType: "datePicker",
+        showPicker: false,
+        split: "-",
+        columnsType: ["year", "month", "day"],
+      },
+      {
+        type: "input",
+        label: proxy.t("contract.quantityShipment"),
+        prop: "quantity",
+        itemType: "number",
+      },
+    ],
+  },
+});
+const rules = {
+  contractType: [{ required: true, message: proxy.t("contract.contractTypeMsg") }],
+  contractTemplateId: [{ required: true, message: proxy.t("contract.contractTemplateIdMsg") }],
+  sellCorporationId: [{ required: true, message: proxy.t("contract.sellCorporationIdMsg") }],
+  buyCorporationId: [{ required: true, message: proxy.t("contract.buyCorporationIdMsg") }],
+  sellCity: [{ required: true, message: proxy.t("contract.cityMsg") }],
+  city: [{ required: true, message: proxy.t("contract.cityMsg") }],
+  sellAddress: [{ required: true, message: proxy.t("contract.addressMsg") }],
+  buyAddress: [{ required: true, message: proxy.t("contract.addressMsg") }],
+  sellContactName: [{ required: true, message: proxy.t("contract.contactNameMsg") }],
+  sellContactNumber: [{ required: true, message: proxy.t("contract.contactNumberMsg") }],
+  buyPostalCode: [{ required: true, message: proxy.t("contract.postalCodeMsg") }],
+  buyContactName: [{ required: true, message: proxy.t("contract.contactNameMsg") }],
+  buyContactNumber: [{ required: true, message: proxy.t("contract.contactNumberMsg") }],
+  productId: [{ required: true, message: proxy.t("contract.productIdMsg") }],
+  productName: [{ required: true, message: proxy.t("contract.productNameMsg") }],
+  productModel: [{ required: true, message: proxy.t("contract.productModelMsg") }],
+  quantity: [{ required: true, message: proxy.t("contract.quantityMsg") }],
+  price: [{ required: true, message: proxy.t("contract.priceMsg") }],
+  payName: [{ required: true, message: proxy.t("contract.chargeItemMsg") }],
+  amount: [{ required: true, message: proxy.t("contract.amountMsg") }],
+};
+const rulesTwo = {
+  currency: [{ required: true, message: proxy.t("contract.currencyMsg") }],
+  paymentMethod: [{ required: true, message: proxy.t("contract.paymentMethodMsg") }],
+  advanceRatio: [{ required: true, message: proxy.t("contract.advanceRatioMsg") }],
+  shroffAccountId: [{ required: true, message: proxy.t("contract.shroffAccountIdMsg") }],
+  tradeMethods: [{ required: true, message: proxy.t("contract.tradeMethodsMsg") }],
+  transportMethod: [{ required: true, message: proxy.t("contract.transportMethodMsg") }],
+  transportRemark: [{ required: true, message: proxy.t("contract.transportRemarkMsg") }],
+  remark: [{ required: true, message: proxy.t("contract.remarksMsg") }],
+};
+const getDict = () => {
+  let query = {
+    pageNum: 1,
+    pageSize: 999,
+    tenantId: getUserInfo().tenantId,
+  };
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "contract_type" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[0].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/contractTemplate/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[1].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.templateName,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[3].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/customer/privateSeaPage", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[9].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/productInfo/page", { pageNum: 1, pageSize: 9999, definition: "1" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formGoodsOption.btnConfig.listConfig[0].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "account_currency" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[1].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "funds_payment_method" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[3].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/accountManagement/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[5].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.alias,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "trade_mode" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[7].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "shipping_method" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[8].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+};
+getDict();
+const calculatedAmount = () => {
+  if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+    for (let i = 0; i < formData.data.contractProductList.length; i++) {
+      let money = 0;
+      if (formData.data.contractProductList[i].quantity && formData.data.contractProductList[i].price) {
+        money = parseFloat(Number(formData.data.contractProductList[i].quantity) * Number(formData.data.contractProductList[i].price)).toFixed(2);
+      }
+      formData.data.contractProductList[i].amount = money;
+    }
+  }
+  handleChangeAmount();
+};
+const handleChangeAmount = () => {
+  let money = 0;
+  let amountProduct = 0;
+  let amountProject = 0;
+  if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+    for (let i = 0; i < formData.data.contractProductList.length; i++) {
+      if (formData.data.contractProductList[i].amount) {
+        money = parseFloat(Number(money) + Number(formData.data.contractProductList[i].amount)).toFixed(2);
+        amountProduct = parseFloat(Number(amountProduct) + Number(formData.data.contractProductList[i].amount)).toFixed(2);
+      }
+    }
+  }
+  if (formData.data.contractProjectList && formData.data.contractProjectList.length > 0) {
+    for (let i = 0; i < formData.data.contractProjectList.length; i++) {
+      if (formData.data.contractProjectList[i].amount) {
+        money = parseFloat(Number(money) + Number(formData.data.contractProjectList[i].amount)).toFixed(2);
+        amountProject = parseFloat(Number(amountProject) + Number(formData.data.contractProjectList[i].amount)).toFixed(2);
+      }
+    }
+  }
+  formData.data.amount = money;
+  formData.data.amountProduct = amountProduct;
+  formData.data.amountProject = amountProject;
+};
+const handleSubmit = async () => {
+  const flag = await formDom1.value.validateForm().then((status) => {
+    if (status) {
+      active.value = 0;
+      return false;
+    } else {
+      if (!(formData.data.contractProductList && formData.data.contractProductList.length > 0)) {
+        active.value = 1;
+        showFailToast(proxy.t("contract.pleaseAddProduct"));
+        return false;
+      }
+      return formDom2.value.validateForm().then((status1) => {
+        if (status1) {
+          active.value = 1;
+          return false;
+        } else {
+          return formDom4.value.validateForm().then((status2) => {
+            if (status2) {
+              active.value = 2;
+              return false;
+            } else {
+              return formDom6.value.validateForm().then((status3) => {
+                if (status3) {
+                  active.value = 3;
+                  return false;
+                } else {
+                  return true;
+                }
+              });
+            }
+          });
+        }
+      });
+    }
+  });
+  if (flag) {
+    return formData.data;
+  }
+};
+watch(
+  props.queryData,
+  () => {
+    if (props.queryData && [10, 20, 30].includes(route.query.processType)) {
+      for (const key in props.queryData) {
+        formData.data[key] = props.queryData[key];
+      }
+    }
+  },
+  {
+    deep: true,
+  }
+);
+defineExpose({
+  handleSubmit,
+});
+onMounted(() => {});
+</script>
+<style lang="scss" scoped></style>

+ 773 - 0
src/views/processApproval/components/PriceSheet.vue

@@ -0,0 +1,773 @@
+<template>
+  <div class="form">
+    <van-tabs v-model:active="active">
+      <van-tab :title="proxy.t('priceSheet.transactionInformation')" />
+      <van-tab :title="proxy.t('priceSheet.quotationDetails')" />
+      <van-tab :title="proxy.t('priceSheet.otherCharges')" />
+      <van-tab :title="proxy.t('priceSheet.otherInformation')" />
+      <div class="common-process-card" v-show="active == 0">
+        <div class="common-title">{{ proxy.t("priceSheet.transactionInformation") }}</div>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formConfig" :rules="rules" ref="formDom1"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 1">
+        <div class="common-title">{{ proxy.t("priceSheet.quotationDetails") }}</div>
+        <testForm v-model="formData.data" :formOption="formGoodsOption" :formConfig="formEmptyConfig" :rules="rules" ref="formDom2"> </testForm>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formAmountProductConfig" :rules="rules" ref="formDom3"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 2">
+        <div class="common-title">{{ proxy.t("priceSheet.otherCharges") }}</div>
+        <testForm v-model="formData.data" :formOption="formProjectOption" :formConfig="formEmptyConfig" :rules="rules" ref="formDom4"> </testForm>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formAmountProjectConfig" :rules="rules" ref="formDom5"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 3">
+        <div class="common-title">{{ proxy.t("priceSheet.otherInformation") }}</div>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formDeliveryConfig" :rules="rulesTwo" ref="formDom6"> </testForm>
+      </div>
+    </van-tabs>
+  </div>
+</template>
+
+<script setup>
+import { ref, getCurrentInstance, onMounted, defineProps, defineExpose, watch, reactive } from "vue";
+import { useRoute } from "vue-router";
+import testForm from "@/components/testForm/index.vue";
+import { getUserInfo } from "@/utils/auth";
+import { showFailToast } from "vant";
+
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const active = ref(0);
+const formData = reactive({
+  data: {
+    quotationProductList: [],
+    quotationPayList: [],
+  },
+});
+const formDom1 = ref(null);
+const formDom2 = ref(null);
+const formDom3 = ref(null);
+const formDom4 = ref(null);
+const formDom5 = ref(null);
+const formDom6 = ref(null);
+const formOption = reactive({
+  readonly: false,
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+});
+const formConfig = reactive([
+  {
+    type: "picker",
+    label: proxy.t("priceSheet.contractTemplateId"),
+    prop: "contractTemplateId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: (val, data) => {
+      proxy.formChange(val, data, formData);
+      formData.data.sellCorporationId = "";
+      formData.data.sellCountryName = "";
+      formData.data.sellProvinceName = "";
+      formData.data.sellCityName = "";
+      formData.data.sellAddress = "";
+      formData.data.sellContactName = "";
+      formData.data.sellContactNumber = "";
+      if (val.selectedValues[0]) {
+        proxy.post("/contractTemplate/detail", { id: val.selectedValues[0] }).then((res) => {
+          formData.data.sellCorporationId = res.data.corporationId;
+          if (res.data.corporationId) {
+            proxy.post("/corporation/detail", { id: res.data.corporationId }).then((detailCorporation) => {
+              let sellCity = "";
+              if (detailCorporation.data.countryEnStr) {
+                formData.data.sellCountryName = detailCorporation.data.countryEnStr;
+                sellCity = detailCorporation.data.countryEnStr;
+              }
+              if (detailCorporation.data.provinceEnStr) {
+                formData.data.sellProvinceName = detailCorporation.data.provinceEnStr;
+                sellCity = sellCity + " " + detailCorporation.data.provinceEnStr;
+              }
+              if (detailCorporation.data.cityEnStr) {
+                formData.data.sellCityName = detailCorporation.data.cityEnStr;
+                sellCity = sellCity + " " + detailCorporation.data.cityEnStr;
+              }
+              if (detailCorporation.data.addressEn) {
+                formData.data.sellAddress = detailCorporation.data.addressEn;
+              }
+              formData.data.sellCity = sellCity;
+              formDom1.value.formDataShowLabelOne();
+            });
+          }
+          formData.data.sellContactName = res.data.contactName;
+          formData.data.sellContactNumber = res.data.contactNumber;
+          formDom1.value.formDataShowLabelOne();
+        });
+      }
+      data.showPicker = false;
+    },
+  },
+  {
+    type: "title",
+    title: proxy.t("priceSheet.sellerInformation"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("priceSheet.sellCorporationId"),
+    prop: "sellCorporationId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.cityText"),
+    prop: "sellCity",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.address"),
+    prop: "sellAddress",
+    itemType: "textarea",
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.contactName"),
+    prop: "sellContactName",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.contactNumber"),
+    prop: "sellContactNumber",
+    itemType: "text",
+  },
+  {
+    type: "title",
+    title: proxy.t("priceSheet.buyerInformation"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("priceSheet.buyCorporationId"),
+    prop: "buyCorporationId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: (val, data) => {
+      proxy.formChange(val, data, formData);
+      formData.data.buyContactName = "";
+      formData.data.buyContactNumber = "";
+      if (val.selectedValues[0]) {
+        proxy.post("/customer/detail", { id: val.selectedValues[0] }).then((res) => {
+          if (res.data.customerUserList && res.data.customerUserList.length > 0) {
+            formData.data.buyContactName = res.data.customerUserList[0].name;
+            if (res.data.customerUserList[0].contactJson) {
+              let contactJson = JSON.parse(res.data.customerUserList[0].contactJson);
+              if (contactJson && contactJson.length > 0) {
+                formData.data.buyContactNumber = contactJson[0].contactNo;
+              }
+            }
+          }
+          let cityName = "";
+          if (res.data.countryName) {
+            cityName = res.data.countryName;
+            if (res.data.provinceName) {
+              cityName = cityName + " " + res.data.provinceName;
+              if (res.data.cityName) {
+                cityName = cityName + " " + res.data.cityName;
+              }
+            }
+          }
+          formData.data.cityName = cityName;
+          if (res.data.cityId) {
+            formData.data.city = res.data.cityId;
+          } else if (res.data.provinceId) {
+            formData.data.city = res.data.provinceId;
+          } else if (res.data.countryId) {
+            formData.data.city = res.data.countryId;
+          } else {
+            formData.data.city = "";
+          }
+          formData.data.countryId = res.data.countryId;
+          formData.data.provinceId = res.data.provinceId;
+          formData.data.cityId = res.data.cityId;
+          formData.data.buyPostalCode = res.data.zipCode;
+          formData.data.buyAddress = res.data.address;
+        });
+      } else {
+        formData.data.countryId = "";
+        formData.data.provinceId = "";
+        formData.data.cityId = "";
+        formData.data.buyPostalCode = "";
+        formData.data.buyAddress = "";
+      }
+      data.showPicker = false;
+    },
+  },
+  {
+    type: "cascader",
+    label: proxy.t("priceSheet.cityText"),
+    prop: "city",
+    itemType: "city",
+    showPicker: false,
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.address"),
+    prop: "buyAddress",
+    itemType: "textarea",
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.postalCode"),
+    prop: "buyPostalCode",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.contactName"),
+    prop: "buyContactName",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.contactNumber"),
+    prop: "buyContactNumber",
+    itemType: "text",
+  },
+]);
+const formGoodsOption = reactive({
+  readonly: false,
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+  btnConfig: {
+    isNeed: true,
+    prop: "quotationProductList",
+    plain: true,
+    listTitle: proxy.t("priceSheet.commodityInformation"),
+    listConfig: [
+      {
+        type: "picker",
+        label: proxy.t("priceSheet.productId"),
+        prop: "productId",
+        itemType: "onePicker",
+        showPicker: false,
+        readonly: false,
+        fieldNames: {
+          text: "label",
+          value: "value",
+        },
+        data: [],
+        changeFn: (val, data, index, indexTwo, propName) => {
+          let selectList = formData.data[propName].filter((item, itemIndex) => item[data.prop] === val.selectedValues[0] && itemIndex !== index);
+          if (selectList && selectList.length > 0) {
+            return showFailToast(proxy.t("priceSheet.productRepeat"));
+          }
+          formData.data[propName][index][data.prop] = val.selectedValues[0];
+          let list = data.data.filter((item) => item[data.fieldNames.value] == val.selectedValues[0]);
+          if (list && list.length > 0) {
+            formData.data[propName][index][data.prop + "Name"] = list[0][data.fieldNames.text];
+            let name = list[0].name;
+            if (list[0].standardJson) {
+              let standardJson = JSON.parse(list[0].standardJson);
+              if (standardJson && standardJson.englishName) {
+                name = standardJson.englishName;
+              }
+            }
+            formData.data[propName][index].productName = name;
+            formData.data[propName][index].productModel = list[0].spec;
+          } else {
+            formData.data[propName][index][data.prop + "Name"] = "";
+          }
+          formData.data[propName][index].quantity = null;
+          formData.data[propName][index].price = null;
+          formData.data[propName][index].amount = null;
+          formData.data[propName][index].remark = null;
+          data.showPicker = false;
+        },
+      },
+      {
+        type: "input",
+        label: proxy.t("priceSheet.productName"),
+        prop: "productName",
+        itemType: "text",
+      },
+      {
+        type: "input",
+        label: proxy.t("priceSheet.productModel"),
+        prop: "productModel",
+        itemType: "text",
+      },
+      {
+        type: "input",
+        label: proxy.t("priceSheet.quantity"),
+        prop: "quantity",
+        itemType: "number",
+        changeFn: () => {
+          calculatedAmount();
+        },
+      },
+      {
+        type: "input",
+        label: proxy.t("priceSheet.price"),
+        prop: "price",
+        itemType: "number",
+        changeFn: () => {
+          calculatedAmount();
+        },
+      },
+    ],
+    clickFn: () => {
+      if (formData.data.quotationProductList && formData.data.quotationProductList.length > 0) {
+        formData.data.quotationProductList.push({
+          productId: null,
+          productName: null,
+          productModel: null,
+          quantity: null,
+          price: null,
+          amount: null,
+          remark: null,
+        });
+      } else {
+        formData.data.quotationProductList = [
+          {
+            productId: null,
+            productName: null,
+            productModel: null,
+            quantity: null,
+            price: null,
+            amount: null,
+            remark: null,
+          },
+        ];
+      }
+    },
+    deleteFn: (index) => {
+      formData.data.quotationProductList.splice(index, 1);
+      handleChangeAmount();
+    },
+  },
+});
+const formEmptyConfig = reactive([]);
+const formAmountProductConfig = reactive([
+  {
+    type: "input",
+    label: proxy.t("priceSheet.amountProduct"),
+    prop: "amountProduct",
+    itemType: "text",
+    readonly: true,
+    placeholder: proxy.t("priceSheet.amountProductPlaceholder"),
+  },
+]);
+const formAmountProjectConfig = reactive([
+  {
+    type: "input",
+    label: proxy.t("priceSheet.amountProject"),
+    prop: "amountProject",
+    itemType: "text",
+    readonly: true,
+    placeholder: proxy.t("priceSheet.amountProjectPlaceholder"),
+  },
+]);
+const formProjectOption = reactive({
+  readonly: false,
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+  btnConfig: {
+    isNeed: true,
+    prop: "quotationPayList",
+    plain: true,
+    listTitle: proxy.t("priceSheet.chargeItem"),
+    listConfig: [
+      {
+        type: "input",
+        label: proxy.t("priceSheet.chargeItem"),
+        prop: "payName",
+        itemType: "text",
+      },
+      {
+        type: "input",
+        label: proxy.t("priceSheet.amount"),
+        prop: "amount",
+        itemType: "number",
+        changeFn: () => {
+          handleChangeAmount();
+        },
+      },
+      {
+        type: "input",
+        label: proxy.t("priceSheet.remark"),
+        prop: "remark",
+        itemType: "textarea",
+      },
+    ],
+    clickFn: () => {
+      if (formData.data.quotationPayList && formData.data.quotationPayList.length > 0) {
+        formData.data.quotationPayList.push({
+          payName: null,
+          amount: null,
+          remark: null,
+        });
+      } else {
+        formData.data.quotationPayList = [
+          {
+            payName: null,
+            amount: null,
+            remark: null,
+          },
+        ];
+      }
+    },
+    deleteFn: (index) => {
+      formData.data.quotationPayList.splice(index, 1);
+      handleChangeAmount();
+    },
+  },
+});
+const formDeliveryConfig = reactive([
+  {
+    type: "title",
+    title: proxy.t("priceSheet.quotedAmount"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("priceSheet.currency"),
+    prop: "currency",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.amountAll"),
+    prop: "amount",
+    itemType: "text",
+    readonly: true,
+    placeholder: proxy.t("priceSheet.amountAllPlaceholder"),
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.effective"),
+    prop: "effective",
+    itemType: "digit",
+  },
+  {
+    type: "picker",
+    label: proxy.t("priceSheet.paymentMethod"),
+    prop: "paymentMethod",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.advanceRatio"),
+    prop: "advanceRatio",
+    itemType: "number",
+    inputFn: (val) => {
+      if (val) {
+        if (val > 100) {
+          formData.data.advanceRatio = 100;
+        } else if (val < 0) {
+          formData.data.advanceRatio = 0;
+        }
+      }
+    },
+  },
+  {
+    type: "title",
+    title: proxy.t("priceSheet.deliveryInformation"),
+  },
+  {
+    type: "picker",
+    label: proxy.t("priceSheet.tradeMethods"),
+    prop: "tradeMethods",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "picker",
+    label: proxy.t("priceSheet.transportMethod"),
+    prop: "transportMethod",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.transportRemark"),
+    prop: "transportRemark",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.remarks"),
+    prop: "remark",
+    itemType: "textarea",
+  },
+  {
+    type: "input",
+    label: proxy.t("priceSheet.warranty"),
+    prop: "warranty",
+    itemType: "digit",
+  },
+]);
+const rules = {
+  contractTemplateId: [{ required: true, message: proxy.t("priceSheet.contractTemplateIdMsg") }],
+  sellCorporationId: [{ required: true, message: proxy.t("priceSheet.sellCorporationIdMsg") }],
+  buyCorporationId: [{ required: true, message: proxy.t("priceSheet.buyCorporationIdMsg") }],
+  sellCity: [{ required: true, message: proxy.t("priceSheet.cityMsg") }],
+  city: [{ required: true, message: proxy.t("priceSheet.cityMsg") }],
+  sellAddress: [{ required: true, message: proxy.t("priceSheet.addressMsg") }],
+  buyAddress: [{ required: true, message: proxy.t("priceSheet.addressMsg") }],
+  sellContactName: [{ required: true, message: proxy.t("priceSheet.contactNameMsg") }],
+  sellContactNumber: [{ required: true, message: proxy.t("priceSheet.contactNumberMsg") }],
+  buyPostalCode: [{ required: true, message: proxy.t("priceSheet.postalCodeMsg") }],
+  buyContactName: [{ required: true, message: proxy.t("priceSheet.contactNameMsg") }],
+  buyContactNumber: [{ required: true, message: proxy.t("priceSheet.contactNumberMsg") }],
+  productId: [{ required: true, message: proxy.t("priceSheet.productIdMsg") }],
+  productName: [{ required: true, message: proxy.t("priceSheet.productNameMsg") }],
+  productModel: [{ required: true, message: proxy.t("priceSheet.productModelMsg") }],
+  quantity: [{ required: true, message: proxy.t("priceSheet.quantityMsg") }],
+  price: [{ required: true, message: proxy.t("priceSheet.priceMsg") }],
+  payName: [{ required: true, message: proxy.t("priceSheet.chargeItemMsg") }],
+  amount: [{ required: true, message: proxy.t("priceSheet.amountMsg") }],
+};
+const rulesTwo = {
+  currency: [{ required: true, message: proxy.t("priceSheet.currencyMsg") }],
+  effective: [{ required: true, message: proxy.t("priceSheet.effectiveMsg") }],
+  paymentMethod: [{ required: true, message: proxy.t("priceSheet.paymentMethodMsg") }],
+  advanceRatio: [{ required: true, message: proxy.t("priceSheet.advanceRatioMsg") }],
+  tradeMethods: [{ required: true, message: proxy.t("priceSheet.tradeMethodsMsg") }],
+  transportMethod: [{ required: true, message: proxy.t("priceSheet.transportMethodMsg") }],
+  transportRemark: [{ required: true, message: proxy.t("priceSheet.transportRemarkMsg") }],
+  remark: [{ required: true, message: proxy.t("priceSheet.remarksMsg") }],
+};
+const getDict = () => {
+  let query = {
+    pageNum: 1,
+    pageSize: 999,
+    tenantId: getUserInfo().tenantId,
+  };
+  proxy.post("/contractTemplate/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[0].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.templateName,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[2].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/customer/privateSeaPage", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[8].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/productInfo/page", { pageNum: 1, pageSize: 9999, definition: "1" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formGoodsOption.btnConfig.listConfig[0].data = res.data.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "account_currency" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[1].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "funds_payment_method" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[4].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "trade_mode" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[7].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "shipping_method" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDeliveryConfig[8].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+};
+getDict();
+const calculatedAmount = () => {
+  if (formData.data.quotationProductList && formData.data.quotationProductList.length > 0) {
+    for (let i = 0; i < formData.data.quotationProductList.length; i++) {
+      let money = 0;
+      if (formData.data.quotationProductList[i].quantity && formData.data.quotationProductList[i].price) {
+        money = parseFloat(Number(formData.data.quotationProductList[i].quantity) * Number(formData.data.quotationProductList[i].price)).toFixed(2);
+      }
+      formData.data.quotationProductList[i].amount = money;
+    }
+  }
+  handleChangeAmount();
+};
+const handleChangeAmount = () => {
+  let money = 0;
+  let amountProduct = 0;
+  let amountProject = 0;
+  if (formData.data.quotationProductList && formData.data.quotationProductList.length > 0) {
+    for (let i = 0; i < formData.data.quotationProductList.length; i++) {
+      if (formData.data.quotationProductList[i].amount) {
+        money = parseFloat(Number(money) + Number(formData.data.quotationProductList[i].amount)).toFixed(2);
+        amountProduct = parseFloat(Number(amountProduct) + Number(formData.data.quotationProductList[i].amount)).toFixed(2);
+      }
+    }
+  }
+  if (formData.data.quotationPayList && formData.data.quotationPayList.length > 0) {
+    for (let i = 0; i < formData.data.quotationPayList.length; i++) {
+      if (formData.data.quotationPayList[i].amount) {
+        money = parseFloat(Number(money) + Number(formData.data.quotationPayList[i].amount)).toFixed(2);
+        amountProject = parseFloat(Number(amountProject) + Number(formData.data.quotationPayList[i].amount)).toFixed(2);
+      }
+    }
+  }
+  formData.data.amount = money;
+  formData.data.amountProduct = amountProduct;
+  formData.data.amountProject = amountProject;
+};
+const handleSubmit = async () => {
+  const flag = await formDom1.value.validateForm().then((status) => {
+    if (status) {
+      active.value = 3;
+      return false;
+    } else {
+      if (!(formData.data.quotationProductList && formData.data.quotationProductList.length > 0)) {
+        active.value = 1;
+        showFailToast(proxy.t("priceSheet.pleaseAddProduct"));
+        return false;
+      }
+      return formDom2.value.validateForm().then((status1) => {
+        if (status1) {
+          active.value = 1;
+          return false;
+        } else {
+          return formDom4.value.validateForm().then((status2) => {
+            if (status2) {
+              active.value = 2;
+              return false;
+            } else {
+              return formDom6.value.validateForm().then((status3) => {
+                if (status3) {
+                  active.value = 3;
+                  return false;
+                } else {
+                  return true;
+                }
+              });
+            }
+          });
+        }
+      });
+    }
+  });
+  if (flag) {
+    return formData.data;
+  }
+};
+watch(
+  props.queryData,
+  () => {
+    if (props.queryData && [10, 20, 30].includes(route.query.processType)) {
+      for (const key in props.queryData) {
+        formData.data[key] = props.queryData[key];
+      }
+    }
+  },
+  {
+    deep: true,
+  }
+);
+defineExpose({
+  handleSubmit,
+});
+onMounted(() => {});
+</script>
+<style lang="scss" scoped></style>

+ 521 - 0
src/views/processApproval/components/SendFunds.vue

@@ -0,0 +1,521 @@
+<template>
+  <div class="form">
+    <van-tabs v-model:active="active">
+      <van-tab :title="proxy.t('funds.basicInformation')"> </van-tab>
+      <van-tab :title="proxy.t('funds.claimDetails')"> </van-tab>
+      <van-tab :title="proxy.t('funds.receiptPaymentInformation')"> </van-tab>
+      <div class="common-process-card" v-show="active == 0">
+        <div class="common-title">{{ proxy.t("funds.basicInformation") }}</div>
+        <testForm v-model="formData.data" :formOption="formOption" :formConfig="formConfig" :rules="rules" ref="formDom1"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 1">
+        <div class="common-title">{{ proxy.t("funds.claimDetails") }}</div>
+        <testForm v-model="formData.data" :formOption="formDetailOption" :formConfig="formDetailConfig" :rules="rules" ref="formDom2"> </testForm>
+        <testForm v-model="formData.data" :formOption="formDetailTwoOption" :formConfig="formDetailTwoConfig" :rules="rules" ref="formDom3"> </testForm>
+      </div>
+      <div class="common-process-card" v-show="active == 2">
+        <div class="common-title">{{ proxy.t("funds.receiptPaymentInformation") }}</div>
+        <testForm v-model="formData.data" :formOption="formReceiptPaymentOption" :formConfig="formReceiptPaymentConfig" :rules="rules" ref="formDom4">
+        </testForm>
+      </div>
+    </van-tabs>
+  </div>
+</template>
+
+<script setup>
+import { ref, getCurrentInstance, onMounted, defineProps, defineExpose, watch, reactive } from "vue";
+import { useRoute } from "vue-router";
+import testForm from "@/components/testForm/index.vue";
+import { getUserInfo } from "@/utils/auth";
+
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const active = ref(0);
+const oldType = ref("");
+const formData = reactive({
+  data: {
+    corporationId: null,
+    departmentId: null,
+    type: null,
+    advanceId: null,
+    currency: null,
+    paymentRemarks: null,
+    accountRequestFundsDetailList: [],
+    total: null,
+    quantity: null,
+    paymentMethod: null,
+    accountManagementId: null,
+    username: null,
+    accountOpening: null,
+    openingBank: null,
+    interbankNumber: null,
+  },
+});
+const formDom1 = ref(null);
+const formDom2 = ref(null);
+const formDom3 = ref(null);
+const formDom4 = ref(null);
+const formOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+});
+const formConfig = reactive([
+  {
+    type: "picker",
+    label: proxy.t("funds.corporationId"),
+    prop: "corporationId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: (val, data) => {
+      proxy.formChange(val, data, formData);
+      if (formData.data.type == "3") {
+        getAdvanceList();
+      }
+      data.showPicker = false;
+    },
+  },
+  {
+    type: "picker",
+    label: proxy.t("funds.departmentId"),
+    prop: "departmentId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "picker",
+    label: proxy.t("funds.type"),
+    prop: "type",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: (val, data) => {
+      if (val.selectedValues[0] === "3" || oldType.value === "3") {
+        for (let text in formData.data) {
+          if (text === "advanceId") {
+            formData.data.advanceId = "";
+          } else if (["corporationId", "corporationIdName", "type", "typeName", "paymentTime", "paymentTimeName"].includes(text)) {
+          } else if (text === "accountRequestFundsDetailList") {
+            formData.data.accountRequestFundsDetailList = [];
+          } else if (text === "fileList") {
+            formData.data.fileList = [];
+          } else {
+            delete formData.data[text];
+          }
+        }
+      }
+      oldType.value = JSON.parse(JSON.stringify(val.selectedValues[0]));
+      proxy.formChange(val, data, formData);
+      if (val.selectedValues[0] === "3") {
+        formConfig[3].type = "picker";
+        getAdvanceList();
+      } else {
+        formConfig[3].type = "pickerAAA";
+      }
+      data.showPicker = false;
+    },
+  },
+  {
+    type: "pickerAAA",
+    label: proxy.t("funds.advanceId"),
+    prop: "advanceId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: (val, data) => {
+      proxy.formChange(val, data, formData);
+      if (val.selectedValues && val.selectedValues.length > 0) {
+        proxy.post("/accountRequestFunds/detail", { id: val.selectedValues[0] }).then((res) => {
+          formData.data.departmentId = res.data.departmentId;
+          formData.data.currency = res.data.currency;
+          formData.data.paymentRemarks = res.data.paymentRemarks;
+          formData.data.accountRequestFundsDetailList = res.data.accountRequestFundsDetailList.map((item) => {
+            return {
+              costType: item.costType,
+              amount: item.amount,
+              contractId: item.contractId,
+              advanceAmount: item.amount,
+              remarks: item.remarks,
+            };
+          });
+          handleChangeAmount();
+          formData.data.advanceAmounts = res.data.total;
+          formData.data.quantity = res.data.quantity;
+          formData.data.paymentMethod = res.data.paymentMethod;
+          formData.data.accountManagementId = res.data.accountManagementId;
+          formData.data.name = res.data.name;
+          formData.data.accountOpening = res.data.accountOpening;
+          formData.data.openingBank = res.data.openingBank;
+          formData.data.interbankNumber = res.data.interbankNumber;
+          formDom1.value.formDataShowLabelOne();
+          formDom2.value.formDataListShowLabelOne();
+          formDom4.value.formDataShowLabelOne();
+        });
+      }
+      data.showPicker = false;
+    },
+  },
+  {
+    type: "picker",
+    label: proxy.t("funds.currency"),
+    prop: "currency",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("funds.paymentRemarks"),
+    prop: "paymentRemarks",
+    itemType: "textarea",
+  },
+]);
+const formDetailOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+  btnConfig: {
+    isNeed: true,
+    prop: "accountRequestFundsDetailList",
+    plain: true,
+    listTitle: proxy.t("funds.claimDetails"),
+    listConfig: [
+      {
+        type: "picker",
+        label: proxy.t("funds.costType"),
+        prop: "costType",
+        itemType: "onePicker",
+        showPicker: false,
+        readonly: false,
+        fieldNames: {
+          text: "label",
+          value: "value",
+        },
+        data: [],
+      },
+      {
+        type: "picker",
+        label: proxy.t("funds.contractId"),
+        prop: "contractId",
+        itemType: "onePicker",
+        showPicker: false,
+        readonly: false,
+        fieldNames: {
+          text: "label",
+          value: "value",
+        },
+        data: [],
+      },
+      {
+        type: "input",
+        label: proxy.t("funds.amount"),
+        prop: "amount",
+        itemType: "number",
+        changeFn: () => {
+          handleChangeAmount();
+        },
+      },
+      {
+        type: "input",
+        label: proxy.t("funds.remarks"),
+        prop: "remarks",
+        itemType: "textarea",
+      },
+    ],
+    clickFn: () => {
+      if (formData.data.accountRequestFundsDetailList && formData.data.accountRequestFundsDetailList.length > 0) {
+        formData.data.accountRequestFundsDetailList.push({
+          costType: null,
+          contractId: null,
+          amount: null,
+          remarks: null,
+        });
+      } else {
+        formData.data.accountRequestFundsDetailList = [
+          {
+            costType: null,
+            contractId: null,
+            amount: null,
+            remarks: null,
+          },
+        ];
+      }
+    },
+    deleteFn: (index) => {
+      formData.data.accountRequestFundsDetailList.splice(index, 1);
+      handleChangeAmount();
+    },
+  },
+});
+const formDetailConfig = reactive([]);
+const formDetailTwoOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+});
+const formDetailTwoConfig = reactive([
+  {
+    type: "input",
+    label: proxy.t("funds.total"),
+    prop: "total",
+    itemType: "number",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("funds.quantity"),
+    prop: "quantity",
+    itemType: "number",
+  },
+]);
+const formReceiptPaymentOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: true,
+});
+const formReceiptPaymentConfig = reactive([
+  {
+    type: "picker",
+    label: proxy.t("funds.paymentMethod"),
+    prop: "paymentMethod",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "picker",
+    label: proxy.t("funds.accountManagementId"),
+    prop: "accountManagementId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("funds.username"),
+    prop: "name",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("funds.accountOpening"),
+    prop: "accountOpening",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("funds.openingBank"),
+    prop: "openingBank",
+    itemType: "text",
+  },
+  {
+    type: "input",
+    label: proxy.t("funds.interbankNumber"),
+    prop: "interbankNumber",
+    itemType: "text",
+  },
+]);
+const rules = {
+  corporationId: [{ required: true, message: proxy.t("funds.corporationIdMsg") }],
+  departmentId: [{ required: true, message: proxy.t("funds.departmentIdMsg") }],
+  type: [{ required: true, message: proxy.t("funds.typeMsg") }],
+  advanceId: [{ required: true, message: proxy.t("funds.advanceIdMsg") }],
+  currency: [{ required: true, message: proxy.t("funds.currencyMsg") }],
+  costType: [{ required: true, message: proxy.t("funds.costTypeMsg") }],
+  contractId: [{ required: true, message: proxy.t("funds.contractIdMsg") }],
+  amount: [{ required: true, message: proxy.t("funds.amountMsg") }],
+  remarks: [{ required: true, message: proxy.t("funds.remarksMsg") }],
+  quantity: [{ required: true, message: proxy.t("funds.quantityMsg") }],
+  paymentMethod: [{ required: true, message: proxy.t("funds.paymentMethodMsg") }],
+  accountManagementId: [{ required: true, message: proxy.t("funds.accountManagementIdMsg") }],
+};
+const getAdvanceList = () => {
+  proxy
+    .post("/accountRequestFunds/page", {
+      pageNum: 1,
+      pageSize: 999,
+      type: "1",
+      writeOffStatus: "0",
+      corporationId: formData.data.corporationId,
+      status: "30",
+      createUser: getUserInfo().userId,
+    })
+    .then((res) => {
+      if (res.data.rows && res.data.rows.length > 0) {
+        formConfig[3].data = res.data.rows.map((item) => {
+          return {
+            label: item.createTime.substr(0, 10) + "  " + item.currency + " " + item.total,
+            value: item.id,
+          };
+        });
+      }
+    });
+};
+const getDict = () => {
+  let query = {
+    pageNum: 1,
+    pageSize: 999,
+    tenantId: getUserInfo().tenantId,
+  };
+  proxy.post("/corporation/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[0].data = res.data.rows.map((item) => {
+        return {
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.get("/tenantDept/list", query).then((res) => {
+    if (res.data && res.data.length > 0) {
+      formConfig[1].data = res.data
+        .filter((item) => item.parentId != "0")
+        .map((item) => {
+          return {
+            label: item.deptName,
+            value: item.deptId,
+          };
+        });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "founds_type" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[2].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "account_currency" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[4].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "funds_cost_type" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDetailOption.btnConfig.listConfig[0].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/contract/page1", { pageNum: 1, pageSize: 9999, status: 30 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formDetailOption.btnConfig.listConfig[1].data = res.data.rows.map((item) => {
+        return {
+          label: item.code,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "funds_payment_method" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formReceiptPaymentConfig[0].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.post("/accountManagement/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formReceiptPaymentConfig[1].data = res.data.rows.map((item) => {
+        return {
+          label: item.alias,
+          value: item.id,
+        };
+      });
+    }
+  });
+};
+getDict();
+const handleChangeAmount = () => {
+  let sum = 0;
+  for (let i = 0; i < formData.data.accountRequestFundsDetailList.length; i++) {
+    const e = formData.data.accountRequestFundsDetailList[i];
+    if (e.amount) {
+      sum = Number(parseFloat(Number(sum) + Number(e.amount)).toFixed(2));
+    }
+  }
+  formData.data.total = sum;
+};
+const handleSubmit = async () => {
+  return formData.data;
+};
+watch(
+  props.queryData,
+  () => {
+    if (props.queryData && [10, 20, 30].includes(route.query.processType)) {
+      for (const key in props.queryData) {
+        formData.data[key] = props.queryData[key];
+      }
+    }
+  },
+  {
+    deep: true,
+  }
+);
+defineExpose({
+  handleSubmit,
+});
+onMounted(() => {});
+</script>
+<style lang="scss" scoped></style>

+ 433 - 0
src/views/processApproval/components/SendPurchase.vue

@@ -0,0 +1,433 @@
+<template>
+  <div class="form" style="padding-bottom: 60px">
+    <van-form
+      @submit="onSubmit"
+      label-align="top"
+      style="margin-top: 20px"
+      ref="formDom"
+    >
+      <van-cell-group inset>
+        <van-field
+          v-model="formData.deptName"
+          is-link
+          readonly
+          :label="$t('procureList.procurementDepartment')"
+          :placeholder="$t('procureList.selectProcurementDepartment')"
+          :rules="[
+            {
+              required: true,
+              message: $t('procureList.procurementDepartmentCanNotBeEmpty'),
+            },
+          ]"
+          :readonly="true"
+          required
+        />
+        <van-field
+          v-model="formData.purchaseName"
+          type="text"
+          :name="$t('procureList.procurementPersonName')"
+          :label="$t('procureList.procurementPersonName')"
+          :placeholder="$t('procureList.pleaseFillInTheProcurementPersonName')"
+          :rules="[
+            {
+              required: true,
+              message: $t('procureList.procurementPersonNameCanNotBeEmpty'),
+            },
+          ]"
+          required
+          :readonly="true"
+        />
+        <van-field
+          v-model="formData.purchaseTime"
+          is-link
+          readonly
+          name="datePicker"
+          :label="$t('procureList.procurementTime')"
+          :placeholder="$t('procureList.clickToSelectTime')"
+          :rules="[
+            {
+              required: true,
+              message: $t('procureList.procurementTimeCanNotBeEmpty'),
+            },
+          ]"
+          required
+          :readonly="true"
+        />
+        <van-popup v-model:show="timePicker" position="bottom">
+          <van-date-picker
+            @confirm="timeOnConfirm"
+            @cancel="timePicker = false"
+          />
+        </van-popup>
+        <van-field
+          v-model="formData.supplyName"
+          is-link
+          readonly
+          :label="$t('procureList.supplier')"
+          :placeholder="$t('procureList.selectSupplier')"
+          @click="typeModal = true"
+          :rules="[
+            {
+              required: true,
+              message: $t('procureList.supplierCanNotBeEmpty'),
+            },
+          ]"
+          required
+        />
+        <van-popup v-model:show="typeModal" position="bottom">
+          <van-picker
+            :title="$t('common.title')"
+            :columns="supplyList"
+            @confirm="onConfirm"
+            @cancel="typeModal = false"
+          />
+        </van-popup>
+        <van-field
+          v-model="formData.purchaseContent"
+          type="textarea"
+          :name="$t('procureList.procurementDescription')"
+          :label="$t('procureList.procurementDescription')"
+          :placeholder="$t('procureList.pleaseFillInTheProcurementDescription')"
+          :rules="[
+            {
+              required: true,
+              message: $t('procureList.procurementDescriptionCanNotBeEmpty'),
+            },
+          ]"
+          required
+          rows="3"
+        />
+      </van-cell-group>
+
+      <!-- 明细列表 -->
+      <div v-for="(item, index) in formData.purchaseDetailList" :key="index">
+        <div class="commons-delete">
+          <div class="title">{{ $t("common.details") }}{{ index + 1 }}</div>
+          <!-- <div
+						class="delete"
+						@click.native="handleDel(index)"
+						v-if="!route.query.id"
+					>
+						<van-icon name="cross" />
+					</div> -->
+        </div>
+        <van-cell-group inset>
+          <van-field
+            v-model="formData.purchaseDetailList[index].productName"
+            is-link
+            readonly
+            :label="$t('procureList.procurementProduct')"
+            :placeholder="$t('procureList.selectProcurementProduct')"
+            :readonly="true"
+            :rules="[
+              {
+                required: true,
+                message: $t('procureList.procurementProductCanNotBeEmpty'),
+              },
+            ]"
+            required
+          />
+          <van-field
+            v-model="formData.purchaseDetailList[index].count2"
+            :label="$t('procureList.quantity')"
+            :placeholder="$t('procureList.pleaseEnterTheQuantity')"
+            :rules="[
+              {
+                required: true,
+                message: $t('procureList.quantityCanNotBeEmpty'),
+              },
+            ]"
+            required
+            type="number"
+            :readonly="true"
+          />
+
+          <van-field
+            v-model="formData.purchaseDetailList[index].count"
+            :name="$t('procureList.thisPurchase')"
+            :label="$t('procureList.thisPurchase')"
+            :placeholder="$t('procureList.pleaseEnterThisPurchase')"
+            @change="changePrice(index)"
+            :rules="[
+              {
+                required: true,
+                message: $t('procureList.thisPurchaseCanNotBeEmpty'),
+              },
+            ]"
+            required
+            type="number"
+          />
+          <van-field
+            v-model="formData.purchaseDetailList[index].price"
+            :name="$t('procureList.unitPrice')"
+            :label="$t('procureList.unitPrice')"
+            @change="changePrice(index)"
+            :placeholder="$t('procureList.pleaseEnterTheUnitPrice')"
+            :rules="[
+              {
+                required: true,
+                message: $t('procureList.unitPriceCanNotBeEmpty'),
+              },
+            ]"
+            required
+            type="number"
+          />
+          <van-field
+            v-model="formData.purchaseDetailList[index].amount"
+            :name="$t('procureList.totalPrice')"
+            :label="$t('procureList.totalPrice')"
+            :placeholder="$t('procureList.accordingToThisPurchaseAndUnitPrice')"
+            :readonly="true"
+            type="number"
+          />
+        </van-cell-group>
+      </div>
+      <van-field
+        style="margin-top: 16px"
+        v-model="formData.amount"
+        :name="$t('procureList.totalPrice')"
+        :label="$t('procureList.totalPrice')"
+        :placeholder="$t('procureList.theTotalAmountOfAllDetails')"
+        :readonly="true"
+        type="number"
+      />
+      <van-popup v-model:show="typeModalOne" round position="bottom">
+        <van-picker
+          :columns="columnsOne"
+          @cancel="typeModalOne = false"
+          @confirm="(data) => onConfirmOne(data)"
+        />
+      </van-popup>
+      <!-- <div style="margin: 16px" v-if="!route.query.id">
+        <van-button round block type="primary" native-type="submit">
+          {{ $t("common.submit") }}
+        </van-button>
+      </div> -->
+    </van-form>
+  </div>
+</template>
+
+<script setup>
+import { ref, getCurrentInstance, onMounted, watch, toRefs } from "vue";
+import { showSuccessToast, showFailToast } from "vant";
+import { useRoute } from "vue-router";
+import { setUserInfo, setToken, getUserInfo, formatDate } from "@/utils/auth";
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const typeModal = ref(false);
+const typeModalOne = ref(false);
+let selectIndex = ref(null);
+const timePicker = ref(false);
+const userInfo = getUserInfo();
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+const refProps = toRefs(props);
+const formData = ref({
+  deptName: userInfo.dept.deptName,
+  purchaseName: userInfo.nickName,
+  purchaseTime: formatDate(new Date(), "yyyy-MM-dd"),
+  supplyId: "",
+  purchaseContent: "",
+  amount: "",
+  purchaseDetailList: [],
+});
+const handleAddRow = () => {
+  formData.value.subscribeDetailList.push({
+    bussinessId: "",
+    bussinessName: "",
+    name: "",
+    quantity: "",
+    content: "",
+    count: "",
+  });
+};
+
+const supplyList = ref([]);
+
+const timeOnConfirm = ({ selectedValues }) => {
+  formData.value.subcribeTime = selectedValues.join("-");
+  timePicker.value = false;
+};
+
+const getDict = () => {
+  proxy
+    .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      supplyList.value = res.data.rows.map((item) => {
+        return {
+          ...item,
+          text: item.name,
+          value: item.id,
+        };
+      });
+    });
+
+  proxy
+    .post("/productInfo/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      columnsOne.value = res.data.rows.map((item) => {
+        return {
+          ...item,
+          text: item.name,
+          value: item.id,
+        };
+      });
+    });
+};
+
+//总价保留两位小数
+const changePrice = (index) => {
+  formData.value.purchaseDetailList[index].amount = (
+    formData.value.purchaseDetailList[index].count *
+    formData.value.purchaseDetailList[index].price
+  ).toFixed(2);
+  formData.value.amount = formData.value.purchaseDetailList.reduce(
+    (total, item) => {
+      return total + Number(item.amount);
+    },
+    0
+  );
+};
+
+const getDetails = (id) => {
+  proxy.post("/subscribe/detail", { id: id }).then((res) => {
+    res.data.subscribeDetailList.map((item) => {
+      columnsOne.value.map((itemOne) => {
+        if (itemOne.value === item.bussinessId) {
+          item.bussinessName = itemOne.name;
+        }
+      });
+    });
+    formData.value = res.data;
+
+    console.log(formData.value);
+  });
+};
+
+const columns = ref([]);
+const columnsOne = ref([]);
+const submitType = ref("add");
+
+const onConfirm = ({ selectedOptions }) => {
+  formData.value.supplyId = selectedOptions[0].value;
+  formData.value.supplyName = selectedOptions[0].text;
+  typeModal.value = false;
+};
+
+const onConfirmOne = ({ selectedOptions }) => {
+  formData.value.subscribeDetailList[selectIndex.value].bussinessId =
+    selectedOptions[0].value;
+  formData.value.subscribeDetailList[selectIndex.value].bussinessName =
+    selectedOptions[0].text;
+  typeModalOne.value = false;
+};
+
+const handleSelect = (index) => {
+  if (submitType.value === "edit") return;
+  selectIndex.value = index;
+  typeModalOne.value = true;
+};
+
+const handleDel = (index) => {
+  formData.value.subscribeDetailList.splice(index, 1);
+};
+
+const onClickLeft = () => history.back();
+const formDom = ref(null);
+const handleSubmit = async () => {
+  try {
+    const flag = await formDom.value.validate();
+    return { ...formData.value };
+  } catch (error) {
+    return false;
+  }
+};
+const getDtl = (query) => {
+  // 是否交接单入口的采购
+  if (query.isReceipt) {
+    proxy
+      .post("/contractProduct/getListDetail", JSON.parse(query.ids))
+      .then((res) => {
+        formData.value.dataResource = "1";
+        formData.value.dataResourceId = query.contractId;
+        formData.value.purchaseDetailList = res.data.map((x) => {
+          let obj = {
+            ...x,
+            dataResource: "1", //来源写死外销合同采购
+            dataResourceId: x.id,
+            bussinessId: x.productId,
+            count2: x.quantity || x.sumPackQuantity || 0,
+            count: x.expendQuantity || 0,
+            price: null,
+            amount: null,
+          };
+          delete obj.id;
+          return obj;
+        });
+      });
+  } else {
+    proxy
+      .post("/subscribeDetail/detail", { ids: JSON.parse(query.ids) })
+      .then((res) => {
+        formData.value.purchaseDetailList = res.data.map((item) => {
+          return {
+            bussinessId: item.bussinessId,
+            productName: item.productName,
+            count2: item.count,
+            subscribeDetailId: item.id,
+            count: null,
+            content: null,
+            price: null,
+            amount: null,
+          };
+        });
+      });
+  }
+};
+defineExpose({
+  handleSubmit,
+});
+
+onMounted(() => {
+  if (route.query.processType) {
+  } else {
+    getDtl(route.query);
+  }
+  getDict();
+});
+
+watch(
+  refProps.queryData,
+  (val) => {
+    if (
+      (val && route.query.processType == 10) ||
+      route.query.processType == 20 ||
+      route.query.processType == 30
+    ) {
+      formData.value = refProps.queryData.value;
+    }
+  },
+  {
+    deep: true,
+  }
+);
+</script>
+<style lang="scss" scoped>
+.row {
+  display: flex;
+  padding: 5px 15px;
+  justify-content: space-between;
+  align-items: center;
+  color: #999999;
+  .title {
+    flex: 1;
+  }
+  .delete {
+    width: 20px;
+    cursor: pointer;
+    text-align: center;
+  }
+}
+</style>

+ 574 - 0
src/views/processApproval/components/SendPurchasePayment.vue

@@ -0,0 +1,574 @@
+<template>
+  <div class="form">
+    <testForm
+      v-model="formData.data"
+      :formOption="formOption"
+      :formConfig="formConfig"
+      :rules="rules"
+      @onSubmit="onSubmit"
+      ref="formDom"
+    ></testForm>
+    <testForm
+      v-model="formData.data"
+      :formOption="formOptionOne"
+      :formConfig="formConfigOne"
+      :rules="rules"
+      @onSubmit="onSubmit"
+      ref="formDomOne"
+    ></testForm>
+  </div>
+</template>
+
+<script setup>
+import {
+  ref,
+  reactive,
+  getCurrentInstance,
+  onMounted,
+  watch,
+  toRefs,
+} from "vue";
+import { showSuccessToast, showFailToast } from "vant";
+import { useRoute } from "vue-router";
+import testForm from "@/components/testForm/index.vue";
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const formDom = ref(null);
+const formDomOne = ref(null);
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+const refProps = toRefs(props);
+const formData = reactive({
+  data: {},
+});
+const rules = {
+  supplyId: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.supplyNameCanNotBeEmpty"),
+    },
+  ],
+  type: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.paymentTypeCanNotBeEmpty"),
+    },
+  ],
+  advanceCode: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.prepaymentCodeCanNotBeEmpty"),
+    },
+  ],
+  remark: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.descriptionCanNotBeEmpty"),
+    },
+  ],
+  invoiceType: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.invoiceTypeCanNotBeEmpty"),
+    },
+  ],
+  rate: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.taxRateCanNotBeEmpty"),
+    },
+  ],
+  purchaseId: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.purchaseContractCanNotBeEmpty"),
+    },
+  ],
+  money: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.paymentAmountCanNotBeEmpty"),
+    },
+  ],
+  payType: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.paymentMethonCanNotBeEmpty"),
+    },
+  ],
+  accountManagementId: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.paymentAccountCanNotBeEmpty"),
+    },
+  ],
+  name: [
+    {
+      required: true,
+      message: proxy.t("purchasePayment.accountNameCanNotBeEmpty"),
+    },
+  ],
+};
+const formOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  submitBtnText: proxy.t("common.submit"),
+  hiddenSubmitBtn: true,
+  btnConfig: {
+    isNeed: true,
+    label: proxy.t("purchasePayment.paymentDetails"),
+    prop: "payDetailList",
+    plain: true,
+    listConfig: [
+      {
+        type: "picker",
+        label: proxy.t("purchasePayment.purchaseContract"),
+        prop: "purchaseId",
+        itemType: "onePicker",
+        showPicker: false,
+        readonly: false,
+        fieldNames: {
+          text: "label",
+          value: "value",
+        },
+        data: [],
+        changeFn: function (option, item, index, currentSonIndex, prop) {
+          proxy.formChangeTwo(
+            option,
+            item,
+            index,
+            currentSonIndex,
+            prop,
+            formData
+          );
+          formDom.value.btnConfigCopy.listConfig[
+            currentSonIndex
+          ].showPicker = false;
+          changePurchaseId(option.selectedValues[0], index);
+        },
+      },
+      {
+        type: "input",
+        itemType: "number",
+        label: proxy.t("purchasePayment.contractAmount"),
+        prop: "amount",
+        readonly: true,
+      },
+      {
+        type: "input",
+        itemType: "number",
+        label: proxy.t("purchasePayment.paidAmount"),
+        prop: "sumPayMoney",
+        readonly: true,
+      },
+      {
+        type: "input",
+        itemType: "textarea",
+        label: proxy.t("purchasePayment.paymentDescription"),
+        prop: "remark",
+        readonly: false,
+      },
+      {
+        type: "input",
+        itemType: "number",
+        label: proxy.t("purchasePayment.paymentAmount"),
+        prop: "money",
+        readonly: false,
+        changeFn: (index, val) => {
+          changeMoney();
+        },
+      },
+    ],
+    clickFn: () => {
+      if (
+        formData.data.payDetailList &&
+        formData.data.payDetailList.length > 0
+      ) {
+        formData.data.payDetailList.push({
+          purchaseId: "",
+          money: "",
+          remark: "",
+        });
+      } else {
+        formData.data.payDetailList = [
+          { purchaseId: "", money: "", remark: "" },
+        ];
+      }
+    },
+  },
+});
+const formConfig = reactive([
+  {
+    type: "picker",
+    label: proxy.t("purchasePayment.supplyName"),
+    prop: "supplyId",
+    itemType: "onePicker",
+    showPicker: false,
+    readonly: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: function (option, item, index) {
+      formData.data[item.prop] = option.selectedOptions[0].value;
+      formData.data[item.prop + "Name"] = option.selectedOptions[0].label;
+      formConfig[index].showPicker = false;
+      changeSupply(option.selectedOptions[0].value);
+    },
+  },
+  {
+    type: "picker",
+    label: proxy.t("purchasePayment.paymentTerm"),
+    prop: "deadline",
+    itemType: "datePickerTime",
+    showPicker: false,
+    readonly: false,
+    needDefault: false,
+  },
+  // 先去掉以下选择
+  {
+    type: "pickerOne",
+    label: proxy.t("purchasePayment.paymentType"),
+    prop: "type",
+    itemType: "onePicker",
+    showPicker: false,
+    readonly: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [
+      { label: "未核销", value: "0" },
+      { label: "发票核销", value: "1" },
+    ],
+    changeFn: function (option, item, index) {
+      proxy.formChange(option, item, formData);
+      formConfig[index].showPicker = false;
+      changeType(formData.data[item.prop]);
+    },
+  },
+  {
+    type: "pickerOne",
+    label: proxy.t("purchasePayment.prepaymentCode"),
+    prop: "advanceCode",
+    itemType: "onePicker",
+    showPicker: false,
+    readonly: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    // changeFn: function (option, item, index) {
+    //   formData.data[item.prop] = option.selectedOptions[0].value;
+    //   formData.data[item.prop + "Name"] = option.selectedOptions[0].label;
+    //   formConfig[index].showPicker = false;
+    //   changeSupply(option.selectedOptions[0].value);
+    // },
+  },
+  {
+    type: "input",
+    label: proxy.t("purchasePayment.paymentDescription"),
+    prop: "remark",
+    itemType: "textarea",
+    readonly: false,
+  },
+  {
+    type: "input",
+    label: proxy.t("purchasePayment.documentNumber"),
+    prop: "receiptsNum",
+    itemType: "number",
+    readonly: false,
+  },
+  {
+    type: "picker",
+    label: proxy.t("purchasePayment.invoiceType"),
+    prop: "invoiceType",
+    itemType: "onePicker",
+    showPicker: false,
+    readonly: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: function (option, item, index) {
+      proxy.formChange(option, item, formData);
+      formConfig[index].showPicker = false;
+      changeInvoiceType(formData.data[item.prop]);
+    },
+  },
+  {
+    type: "input",
+    label: proxy.t("purchasePayment.taxRate") + "(%)",
+    prop: "rate",
+    itemType: "number",
+    readonly: false,
+  },
+]);
+const formOptionOne = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  submitBtnText: proxy.t("common.submit"),
+  hiddenSubmitBtn: true,
+});
+const formConfigOne = reactive([
+  {
+    type: "input",
+    label: proxy.t("purchasePayment.totalPaymentAmount"),
+    prop: "amount",
+    itemType: "number",
+    readonly: true,
+  },
+  {
+    type: "picker",
+    label: proxy.t("purchasePayment.paymentMethon"),
+    prop: "payType",
+    itemType: "onePicker",
+    showPicker: false,
+    readonly: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: function (option, item, index) {
+      proxy.formChange(option, item, formData);
+      formConfigOne[index].showPicker = false;
+    },
+  },
+  {
+    type: "picker",
+    label: proxy.t("purchasePayment.paymentAccount"),
+    prop: "accountManagementId",
+    itemType: "onePicker",
+    showPicker: false,
+    readonly: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    changeFn: function (option, item, index) {
+      proxy.formChange(option, item, formData);
+      formConfigOne[index].showPicker = false;
+      changeAccount(formData.data[item.prop]);
+    },
+  },
+  {
+    type: "input",
+    label: proxy.t("purchasePayment.accountName"),
+    prop: "name",
+    itemType: "text",
+    readonly: false,
+  },
+  {
+    type: "input",
+    label: proxy.t("purchasePayment.bankAccount"),
+    prop: "accountOpening",
+    itemType: "text",
+    readonly: false,
+  },
+  {
+    type: "input",
+    label: proxy.t("purchasePayment.bankOfDeposit"),
+    prop: "openingBank",
+    itemType: "text",
+    readonly: false,
+  },
+  {
+    type: "input",
+    label: proxy.t("purchasePayment.interbankNumber"),
+    prop: "interbankNumber",
+    itemType: "text",
+    readonly: false,
+  },
+]);
+const supplierList = ref([]);
+const accountList = ref([]);
+const invoiceType = ref([]);
+const fundsPaymentMethod = ref([]);
+const contractList = ref([]);
+const changeSupply = (val) => {
+  if (val) {
+    proxy.get("/purchase/getListBySupplyId", { supplyId: val }).then((res) => {
+      if (res.data && res.data.length > 0) {
+        contractList.value = res.data.map((item) => {
+          return {
+            value: item.id,
+            label: item.code,
+            amount: item.amount,
+            sumPayMoney: item.sumPayMoney,
+            sumInvoiceMoney: item.sumInvoiceMoney,
+          };
+        });
+      } else {
+        contractList.value = [];
+      }
+      formOption.btnConfig.listConfig[0].data = contractList.value;
+    });
+  } else {
+    contractList.value = [];
+  }
+  formData.data.payDetailList = [];
+};
+const changeMoney = () => {
+  let money = 0;
+  for (let i = 0; i < formData.data.payDetailList.length; i++) {
+    if (formData.data.payDetailList[i].money) {
+      money = parseFloat(
+        Number(money) + Number(formData.data.payDetailList[i].money)
+      ).toFixed(2);
+    }
+  }
+  formData.data.amount = money;
+};
+const changePurchaseId = (val, index) => {
+  const current = contractList.value.find((x) => x.value === val);
+  if (current) {
+    formData.data.payDetailList[index].amount = current.amount;
+    formData.data.payDetailList[index].sumPayMoney = current.sumPayMoney;
+    formData.data.payDetailList[index].sumInvoiceMoney =
+      current.sumInvoiceMoney;
+  } else {
+  }
+};
+const changeType = (val) => {
+  if (val == "1") {
+    formConfig[3].type = "picker";
+    proxy.get(`purchase/getAdvanceCode?money=${1}`).then((res) => {
+      console.log(res, "aaa");
+    });
+  } else {
+    formConfig[3].type = "pickerOne";
+  }
+};
+const changeInvoiceType = (val) => {
+  if (val == "1") {
+    formConfig[7].type = "input";
+    formData.data.rate = "13";
+  } else if (val == "2") {
+    formConfig[7].type = "input";
+    formData.data.rate = "6";
+  } else {
+    formConfig[7].type = "inputOne";
+    formData.data.rate = "";
+  }
+};
+const changeAccount = (val) => {
+  if (val) {
+    let data = accountList.value.filter((item) => item.value === val);
+    if (data && data.length > 0) {
+      formData.data.name = data[0].bankName;
+      formData.data.accountOpening = data[0].accountOpening;
+      formData.data.openingBank = data[0].openingBank;
+      formData.data.interbankNumber = data[0].interbankNumber;
+    }
+  }
+};
+const getDict = () => {
+  proxy
+    .post("/supplierInfo/page", { pageNum: 1, pageSize: 999 })
+    .then((res) => {
+      if (res.data.rows && res.data.rows.length > 0) {
+        supplierList.value = res.data.rows.map((item) => {
+          return {
+            label: item.name,
+            value: item.id,
+          };
+        });
+        formConfig[0].data = supplierList.value;
+      }
+    });
+  proxy
+    .post("/accountManagement/page", { pageNum: 1, pageSize: 999 })
+    .then((res) => {
+      accountList.value = res.data.rows.map((item) => {
+        return {
+          bankName: item.name,
+          accountOpening: item.accountOpening,
+          openingBank: item.openingBank,
+          interbankNumber: item.interbankNumber,
+          label: item.alias,
+          value: item.id,
+        };
+      });
+      formConfigOne[2].data = accountList.value;
+    });
+  proxy.getDictOne(["invoice_type", "funds_payment_method"]).then((res) => {
+    invoiceType.value = res["invoice_type"].data.map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    fundsPaymentMethod.value = res["funds_payment_method"].data.map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    formConfig[6].data = invoiceType.value;
+    formConfigOne[1].data = fundsPaymentMethod.value;
+  });
+};
+getDict();
+
+const handleSubmit = async () => {
+  const data = await formDom.value.validateForm().then((status) => {
+    if (status) {
+      return false;
+    } else {
+      if (
+        formData.data.payDetailList &&
+        formData.data.payDetailList.length > 0
+      ) {
+        return formDomOne.value.validateForm().then((status1) => {
+          if (status1) {
+            return false;
+          } else {
+            return true;
+          }
+        });
+      } else {
+        showFailToast(proxy.t("purchasePayment.pleaseAddPaymentDetails"));
+        return false;
+      }
+    }
+  });
+  if (data) {
+    return { ...formData.data };
+  }
+};
+
+watch(
+  refProps.queryData,
+  (val) => {
+    if (
+      (val && route.query.processType == 10) ||
+      route.query.processType == 20 ||
+      route.query.processType == 30
+    ) {
+      formData.data = refProps.queryData.value;
+      formDom.value.formDataShowLabelOne();
+      formDom.value.formDataListShowLabelOne();
+      formDomOne.value.formDataShowLabelOne();
+    }
+  },
+  {
+    deep: true,
+  }
+);
+
+defineExpose({
+  handleSubmit,
+});
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 366 - 4
src/views/processApproval/components/SendSubscribe.vue

@@ -1,5 +1,367 @@
 <template>
-    <div>
-        12312312
-    </div>
-</template>
+	<div class="form">
+		<van-tabs v-model:active="active">
+			<van-tab title="申购信息">
+				<div class="common-process-card">
+					<div class="common-title">申购信息</div>
+					<van-form 
+						@submit="onSubmit" 
+						label-align="top" 
+						style="margin-top: 20px" 
+						:readonly="route.query.processType == 10 || route.query.processType == 20">
+						<van-cell-group inset>
+							<van-field
+								v-model="formData.deptName"
+								is-link
+								readonly
+								:label="$t('purchased.procurementDepartment')"
+								:placeholder="$t('purchased.selectProcurementDepartment')"
+								:rules="[{ required: true, message: $t('purchased.procurementDepartmentCanNotBeEmpty') }]"
+								@click="route.query.processType == 10 || route.query.processType == 20 ? typeModal = false : typeModal = true"
+								required
+							/>
+							<van-popup v-model:show="typeModal" round position="bottom">
+								<van-picker
+									:columns="columns"
+									@cancel="typeModal = false"
+									@confirm="onConfirm"
+								/>
+							</van-popup>
+							<van-field
+								v-model="formData.subcribeName"
+								type="text"
+								:name="$t('purchased.procurementPersonName')"
+								:label="$t('purchased.procurementPersonName')"
+								:placeholder="$t('purchased.pleaseFillInTheProcurementPersonName')"
+								:rules="[{ required: true, message: $t('purchased.procurementPersonNameCanNotBeEmpty') }]"
+								required
+							/>
+							<van-field
+								v-model="formData.subcribeTime"
+								is-link
+								readonly
+								name="datePicker"
+								:label="$t('purchased.procurementTime')"
+								:placeholder="$t('purchased.clickToSelectTime')"
+								:rules="[{ required: true, message: $t('purchased.procurementTimeCanNotBeEmpty') }]"
+								@click="route.query.processType == 10 || route.query.processType == 20 ? timePicker = false : timePicker = true"
+								required
+							/>
+							<van-popup v-model:show="timePicker" position="bottom">
+								<van-date-picker
+									@confirm="timeOnConfirm"
+									@cancel="timePicker = false"
+								/>
+							</van-popup>
+							<van-field
+								v-model="formData.subcribeContent"
+								type="textarea"
+								:name="$t('purchased.procurementDescription')"
+								:label="$t('purchased.procurementDescription')"
+								:placeholder="$t('purchased.pleaseFillInTheProcurementDescription')"
+								:rules="[{ required: true, message: $t('purchased.procurementDescriptionCanNotBeEmpty') }]"
+								required
+								rows="3"
+							/>
+						</van-cell-group>
+
+						
+					</van-form>
+				</div>
+			</van-tab>
+			<van-tab title="明细">
+				<div class="common-process-card">
+					<div class="common-title">明细</div>
+					<!-- 明细列表 -->
+					<div  v-if="route.query.processType != 10 && route.query.processType != 20">
+						<div
+							v-for="(item, index) in formData.subscribeDetailList"
+							:key="index"
+						>
+							<div class="commons-delete">
+								<div class="title">{{$t('common.details')}}{{ index + 1 }}</div>
+								<div
+									class="delete"
+									@click.native="handleDel(index)"
+									v-if="!route.query.id"
+								>
+									<van-icon name="cross" />
+								</div>
+							</div>
+							<van-cell-group inset>
+								<van-field
+									v-model="formData.subscribeDetailList[index].bussinessName"
+									is-link
+									readonly
+									:label="$t('purchased.procurementProduct')"
+									:placeholder="$t('purchased.selectProcurementProduct')"
+									:readonly="submitType === 'edit'"
+									@click="handleSelect(index)"
+									:rules="[
+										{ required: true, message: $t('purchased.procurementProductCanNotBeEmpty') },
+									]"
+									required
+								/>
+								<van-field
+									v-model="formData.subscribeDetailList[index].count"
+									:label="$t('subscribe.quantity')"
+									:placeholder="$t('subscribe.pleaseEnterTheQuantity')"
+									:rules="[{ required: true, message: $t('subscribe.quantityCanNotBeEmpty') }]"
+									required
+									type="number"
+									:readonly="submitType === 'edit'"
+								/>
+
+								<van-field
+									v-model="formData.subscribeDetailList[index].content"
+									:label="$t('subscribe.cause')"
+									:placeholder="$t('subscribe.pleaseEnterTheCause')"
+									:rules="[
+										{ required: true, message: $t('subscribe.causeCanNotBeEmpty') },
+									]"
+									:readonly="submitType === 'edit'"
+									rows="3"
+									type="textarea"
+									required
+								/>
+							</van-cell-group>
+						</div>
+						<van-popup v-model:show="typeModalOne" round position="bottom">
+							<van-picker
+								:columns="columnsOne"
+								@cancel="typeModalOne = false"
+								@confirm="(data) => onConfirmOne(data)"
+							/>
+						</van-popup>
+						<div class="commons-add-btn"  v-if="!route.query.id">
+							<van-button
+							icon="plus"
+							type="default"
+							size="small"
+							style="margin-top: 10px"
+							block
+							@click="handleAddRow"
+							>{{$t('common.addDetails')}}</van-button
+							>
+						</div>
+					</div>
+					<!-- <div style="margin: 16px" v-if="!route.query.id">
+						<van-button round block type="primary" native-type="submit">
+							{{$t('common.submit')}}
+						</van-button>
+					</div> -->
+					<div class="common-mobile-table" v-else>
+						<table>
+							<thead>
+								<tr>
+									<th>申购产品</th>
+									<th>数量</th>
+									<th>事由</th>
+								</tr>
+							</thead>
+							<tbody>
+								<tr v-for="(i,index) in formData.subscribeDetailList" :key="index">
+									<td>{{ i.name }}</td>
+									<td>{{ i.count }}</td>
+									<td>{{ i.remark }}</td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</van-tab>
+		</van-tabs>
+		
+	</div>
+</template>
+
+<script setup>
+import { ref, getCurrentInstance, onMounted,defineProps,defineExpose,watch } from 'vue'
+import { showSuccessToast, showFailToast } from 'vant'
+import { useRoute } from 'vue-router'
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+
+const proxy = getCurrentInstance().proxy
+const route = useRoute()
+const typeModal = ref(false)
+const typeModalOne = ref(false)
+let selectIndex = ref(null)
+const timePicker = ref(false)
+const formData = ref({
+	productionTaskId: '',
+	code: '',
+	productName: '',
+	quantity: '',
+	personLiableName: '',
+	dueDate: '',
+	subscribeDetailList: [],
+})
+
+const active = ref(0)
+const tabsChange = () => {
+	active.value ++
+}
+
+const handleAddRow = () => {
+	console.log(formData.value)
+	if(!formData.value.subscribeDetailList) formData.value.subscribeDetailList = []
+	formData.value.subscribeDetailList.push({
+		bussinessId: '',
+		bussinessName: '',
+		name: '',
+		quantity: '',
+        content:"",
+        count:"",
+	})
+}
+watch(
+  props.queryData,
+  () => {
+    if (props.queryData && ["10", "20", "30"].includes(route.query.processType)) {
+      for (const key in props.queryData) {
+        formData.data[key] = props.queryData[key];
+      }
+    }
+  },
+  {
+    deep: true,
+  }
+);
+const timeOnConfirm = ({ selectedValues }) => {
+	formData.value.subcribeTime = selectedValues.join('-')
+	timePicker.value = false
+}
+
+const getDict = () => {
+	proxy
+		.get('/tenantDept/list', { pageNum: 1, pageSize: 9999 })
+		.then((res) => {
+			columns.value = res.data.map((item) => {
+				return {
+					...item,
+					text: item.deptName,
+					value: item.deptId,
+				}
+			})
+		})
+	setInterval(() => {
+		//停止循环
+		if (proxy.queryData) {
+			formData.value = proxy.queryData
+			clearInterval()
+		}
+	}, 1000)
+	proxy
+		.post('/productInfo/page', { pageNum: 1, pageSize: 9999 })
+		.then((res) => {
+			columnsOne.value = res.data.rows.map((item) => {
+				return {
+					...item,
+					text: item.name,
+					value: item.id,
+				}
+			})
+		})
+}
+
+const getDetails = (id) => {
+	proxy.post('/subscribe/detail', { id:id }).then((res) => {
+		res.data.subscribeDetailList.map((item) => {
+			columnsOne.value.map((itemOne) => {
+				if(itemOne.value === item.bussinessId) {
+					item.bussinessName = itemOne.name
+				}
+			})
+			
+		})
+		formData.value = res.data
+
+		
+		console.log(formData.value)
+	})
+}
+
+const columns = ref([])
+const columnsOne = ref([])
+const submitType = ref('add')
+
+const onConfirm = ({ selectedOptions }) => {
+	formData.value.deptName = selectedOptions[0].text
+	formData.value.productionTaskId = selectedOptions[0].value
+	formData.value.productName = selectedOptions[0].productName
+	formData.value.quantity = selectedOptions[0].quantity
+	formData.value.personLiableName = selectedOptions[0].personLiableName
+	formData.value.dueDate = selectedOptions[0].dueDate
+	typeModal.value = false
+}
+
+const onConfirmOne = ({ selectedOptions }) => {
+	formData.value.subscribeDetailList[selectIndex.value].bussinessId =
+		selectedOptions[0].value
+	formData.value.subscribeDetailList[selectIndex.value].bussinessName =
+		selectedOptions[0].text
+	typeModalOne.value = false
+}
+
+const handleSelect = (index) => {
+	if(submitType.value === 'edit') return
+	selectIndex.value = index
+	typeModalOne.value = true
+}
+
+const handleDel = (index) => {
+	formData.value.subscribeDetailList.splice(index, 1)
+}
+
+const onClickLeft = () => history.back()
+const handleSubmit = async () => {
+  return formData.value;
+};
+const onSubmit = () => {
+	if (!formData.value.subscribeDetailList.length > 0)
+		return showFailToast(proxy.t('common.pleaseAddDetails'))
+	proxy.post('/flowProcess/initiate', {
+		flowKey: 'subscribe_flow',
+		data:formData.value,
+		remark:null,
+	}).then(
+		(res) => {
+			setTimeout(() => {
+				showSuccessToast(proxy.t('common.procurementSuccess'))
+				proxy.$router.push('/main/subscribe')
+			}, 500)
+		},
+		(err) => {
+			return showFailToast(err.message)
+		}
+	)
+}
+defineExpose({
+  handleSubmit,
+  tabsChange
+});
+onMounted(() => {
+    
+	getDict()
+})
+</script>
+<style lang="scss" scoped>
+.row {
+	display: flex;
+	padding: 5px 15px;
+	justify-content: space-between;
+	align-items: center;
+	color: #999999;
+	.title {
+		flex: 1;
+	}
+	.delete {
+		width: 20px;
+		cursor: pointer;
+		text-align: center;
+	}
+}
+</style>

+ 17 - 13
src/views/processApproval/index.vue

@@ -93,8 +93,8 @@ const toDtl = (row) => {
 		return
 	}
 	proxy.post('flowExample/getApprovalRecord', { id: row.id }).then((res) => {
-		if (res.recordList.length > 0) {
-			let data = res.recordList.filter((item) => item.status === 2)
+		if (res.data.recordList.length > 0) {
+			let data = res.data.recordList.filter((item) => item.status === 2)
 			let nodeType = 0
 			if (data && data.length > 0) {
 				nodeType = data[0].nodeType
@@ -110,27 +110,31 @@ const toDtl = (row) => {
 			})
 		}
 	})
-	proxy.$router.push({
-		path: 'processDtl',
-		query: {
-			flowKey: row.flowKey,
-			id: row.id,
-			processType: 10,
-		},
-	})
+	// proxy.$router.push({
+	// 	path: 'processDtl',
+	// 	query: {
+	// 		flowKey: row.flowKey,
+	// 		id: row.id,
+	// 		processType: 10,
+	// 	},
+	// })
 }
 onMounted(() => {
 	if (route.query) {
-		console.log(route.query)
-		req.value.status = route.query.status
+		
 		getList()
 	}
 })
 
 const getList = (type) => {
 	loading.value = true
+	const postUrl = {
+		"1":'/flowExample/getToBeProcessedPage',
+		"2":'/flowExample/getHaveInitiatedPage',
+		"3":'/flowExample/getProcessedPage',
+	}
 	proxy
-		.post('/flowExample/getToBeProcessedPage', req.value)
+		.post(postUrl[route.query.status], req.value)
 		.then((res) => {
 			listData.value =
 				type === 'refresh'

+ 226 - 184
src/views/processApproval/processDtl.vue

@@ -1,158 +1,87 @@
 <template>
 	<div class="process">
-		<van-nav-bar
-			title="流程审批"
-			left-text=""
-			left-arrow
-			@click-left="onClickLeft"
-		>
+		<van-nav-bar title="流程审批" left-text="" left-arrow @click-left="onClickLeft">
 		</van-nav-bar>
-        <component ref="makeDom" :is='componentObj[route.query.flowKey].component'></component>
-		<div class="card">
-			<div class="common-title border-btm">申购信息</div>
-			<div class="common-form-text">
-				<div class="common-form-text-item">
-					<div class="common-form-text-item-label">申购单号</div>
-					<div class="common-form-text-item-value">
-						PR-221101-170404-296
-					</div>
-				</div>
-				<div class="common-form-text-item">
-					<div class="common-form-text-item-label">申购时间</div>
-					<div class="common-form-text-item-value">
-						2022-11-01 17:04:04
-					</div>
-				</div>
-				<div class="common-form-text-item">
-					<div class="common-form-text-item-label">申购部门</div>
-					<div class="common-form-text-item-value">仓库</div>
-				</div>
-				<div class="common-form-text-item">
-					<div class="common-form-text-item-label">申购人</div>
-					<div class="common-form-text-item-value">阮平芳</div>
-				</div>
-				<div class="common-form-text-item">
-					<div class="common-form-text-item-label">申购类型</div>
-					<div class="common-form-text-item-value">物料</div>
-				</div>
-				<div class="common-form-text-item textarea">
-					<div class="common-form-text-item-label">申购说明</div>
-					<van-field
-						v-model="message"
-						rows="3"
-						autosize
-						type="textarea"
-						maxlength="400"
-						placeholder="请输入申购说明"
-						show-word-limit
-					/>
-				</div>
-			</div>
+		<div>
+			<component ref="makeDom" :queryData="queryData.data" :is="
+					componentObj[route.query.flowKey]
+						? componentObj[route.query.flowKey].component
+						: SendSubscribe
+				"></component>
 		</div>
-		<div class="card">
-			<div class="common-title">申购明细</div>
-			<div class="common-mobile-table">
-				<table>
-					<thead>
-						<tr>
-							<th>物料编码</th>
-							<th>物料名称</th>
-							<th>规格型号</th>
-							<th>规格型号</th>
-							<th>规格型号</th>
-							<th>规格型号</th>
-							<th>规格型号</th>
-						</tr>
-					</thead>
-					<tbody>
-						<tr>
-							<td>1000000001</td>
-							<td>电脑</td>
-							<td>台</td>
-						</tr>
-						<tr>
-							<td>1000000002</td>
-							<td>显示器</td>
-							<td>台</td>
-						</tr>
-					</tbody>
-				</table>
+		<div class="btn-warp" :class="footerMoreType ? 'open-more' : ''">
+			<div class="more-btn" @click="footerMoreType = true">
+				更多 <van-icon name="arrow-up" />
+			</div>
+			<div class="foot-btn-warp">
+				<div class="agree-btn" @click="handleSubmit(1)">同意</div>
+				<div class="next-btn" @click="nextFn">下一步</div>
 			</div>
-			<div class="more-btn">查看更多</div>
 		</div>
-		<div class="card">
-			<div class="common-title">审批流程</div>
-			<van-steps
-				direction="vertical"
-				:active="stepsNum"
-				class="common-steps"
-			>
-				<van-step v-for="(i, index) in recordList" :key="i.nodeId">
-					<div class="label">
-						<span class="name">{{ i.processedUser }}</span>
-						<span class="tip">{{ i.nodeName }}</span>
-						<span
-							class="state"
-							:class="
-								index == stepsNum
-									? 'cl-yl'
-									: index < stepsNum
+		<van-action-sheet v-model:show="footerMoreType" title="审批记录" class="more-modal">
+			<div class="card">
+				<van-steps direction="vertical" :active="stepsNum" class="common-steps">
+					<van-step v-for="(i, index) in recordList" :key="i.nodeId">
+						<div class="label">
+							<span class="name">{{ i.processedUser }}</span>
+							<span class="tip">{{ i.nodeName }}</span>
+							<span class="state" :class="index == stepsNum
+								? 'cl-yl'
+								: index < stepsNum
 									? 'cl-blue'
 									: ''
-							"
-						>
-							{{ i.nodeName }}
-						</span>
-					</div>
-					<div class="content">审批意见:{{ i.remark }}</div>
-					<p>{{ i.processedDate }}</p>
-				</van-step>
-			</van-steps>
-			<div class="common-form-text">
-				<div class="common-form-text-item textarea">
-					<van-field
-						v-model="message"
-						rows="3"
-						autosize
-						type="textarea"
-						maxlength="400"
-						placeholder="请输入审批意见"
-						show-word-limit
-					/>
-				</div>
-				<div class="btn-warp">
-					<van-button
-						type="primary"
-						v-if="approvalRecordData.buttonInfoList.length == 0"
-						>同意</van-button
-					>
-					<van-button
-						type="primary"
-						v-else
-						v-for="i in approvalRecordData.buttonInfoList"
-						:key="i.type"
-						>{{ i.name }}</van-button
-					>
+								">
+								{{ i.nodeName }}
+							</span>
+						</div>
+						<div class="content">审批意见:{{ i.remark }}</div>
+						<p>{{ i.processedDate }}</p>
+					</van-step>
+				</van-steps>
+			</div>
+			<div style="padding: 0 12px">
+				<van-field v-model="flowForm.remark" rows="3" autosize type="textarea" maxlength="400" placeholder="请输入审批意见"
+					show-word-limit style="backround: #f1f1f1" />
+			</div>
+			<div class="load-btn-box">
+				<van-button size="small" type="primary" plain round v-for="i in approvalRecordData.buttonInfoList"
+					:key="i.type" v-show="i.type != 1" @click="handleSubmit(i.type)">{{ i.name }}
+				</van-button>
+			</div>
+			<div class="content">
+				<div class="foot-btn-warp">
+					<div class="agree-btn" @click="handleSubmit(1)">同意</div>
+					<div class="next-btn" @click="nextFn">下一步</div>
 				</div>
 			</div>
-		</div>
+		</van-action-sheet>
 	</div>
 </template>
 <script setup>
 import { ref, getCurrentInstance, onMounted, reactive } from 'vue'
 import { useRoute } from 'vue-router'
 import SendSubscribe from './components/SendSubscribe'
+import SendFunds from './components/SendFunds'
+import PriceSheet from './components/PriceSheet'
+import Contract from './components/Contract'
+import SendPurchase from './components/SendPurchase'
+import SendPurchasePayment from './components/SendPurchasePayment'
+
+import { showSuccessToast, showFailToast } from 'vant'
 const route = useRoute()
 const proxy = getCurrentInstance().proxy
-const onClickLeft = () => proxy.$router.push('/main/working')
+// const onClickLeft = () => proxy.$router.push(componentObj.value[route.query.flowKey].backUrl)
+const onClickLeft = () => proxy.$router.go(-1)
 const message = ref('')
 const onClickRight = () => {
 	proxy.$router.push('/main/working')
 }
+const makeDom = ref(null)
 let stepsNum = ref(0)
 let queryData = reactive({
 	data: {},
 })
+let footerMoreType = ref(false)
 const flowForm = reactive({
 	flowKey: '',
 	tenantType: '',
@@ -165,8 +94,8 @@ const approvalRecordData = ref({
 	buttonInfoList: [],
 })
 
-const getAuxiliaryData = (data)=>{
-  auxiliaryData.value=data
+const getAuxiliaryData = (data) => {
+	auxiliaryData.value = data
 }
 
 let componentObj = ref({
@@ -175,23 +104,53 @@ let componentObj = ref({
 		component: SendSubscribe,
 		backUrl: '/main/subscribe',
 	},
+	account_request_funds_flow: {
+		title: '请款',
+		component: SendFunds,
+		backUrl: '/main/funds',
+	},
+	sale_quotation_flow: {
+		title: '报价单',
+		component: PriceSheet,
+		backUrl: '/main/priceSheet',
+	},
+	contract_flow: {
+		title: '销售合同',
+		component: Contract,
+		backUrl: '/main/contract',
+	},
+	
+		purchase_flow: {
+		title: '采购',
+		component: SendPurchase,
+		backUrl: '/main/procureList',
+	},
+		pay_flow: {
+		title: '采购付款',
+		component: SendPurchasePayment,
+		backUrl: '/main/purchasePayment',
+	},
 })
 
-let dialogVisible = ref(false);
+let dialogVisible = ref(false)
 //判断是否有下一节点处理人
 const handleResult = (res) => {
-  if (res !== null && res.success) {
-    skipPage();
-  } else {
-    dialogVisible.value = true;
-    nextHandleUser.value = res.userList;
-  }
-};
+	if (res !== null && res.success) {
+		skipPage()
+	} else {
+		dialogVisible.value = true
+		nextHandleUser.value = res.userList
+	}
+}
 const skipPage = () => {
-    router.replace({
-      path: route.query.processType === 10 ?  "/main/processApproval" : componentObj[route.query.flowKey].backUrl,
-    });
-};
+	onClickLeft()
+	// proxy.$router({
+	// 	path:
+	// 		route.query.processType === 10
+	// 			? '/main/processApproval'
+	// 			: componentObj.value[route.query.flowKey].backUrl,
+	// })
+}
 
 const handleSelectUser = () => {
 	if (!flowForm.handleUserId) {
@@ -203,45 +162,46 @@ const handleSelectUser = () => {
 	handleSubmit()
 }
 const handleSubmit = async (_type) => {
-	const flag = await makeDom.value.handleSubmit()
-	if (flag) {
-		flowFormDom.value.validate((valid) => {
-			if (
-				route.query.processType == 10 ||
-				route.query.processType == 30
-			) {
-				proxy
-					.post('/flowProcess/jump', {
-						...flowForm,
-						data,
-						handleType: _type,
-						version: route.query.version,
-						flowId: route.query.id,
-					})
-					.then((res) => {
-						handleResult(res)
-					})
-				if (_type && _type == 1) {
-					proxy
-						.post('/flowExample/setStartData', {
-							exampleId: route.query.id,
-							startDate: data,
-						})
-						.then()
-				}
-				return
-			} else {
+	const childrenData = await makeDom.value.handleSubmit()
+	console.log(childrenData,'www');
+	if (childrenData) {
+		if (route.query.processType == 10 || route.query.processType == 30) {
+			proxy
+				.post('/flowProcess/jump', {
+					...flowForm,
+					data: childrenData,
+					handleType: _type,
+					version: route.query.version,
+					flowId: route.query.id,
+				})
+				.then((res) => {
+					handleResult(res.data)
+				})
+			if (_type && _type == 1) {
 				proxy
-					.post('/flowProcess/initiate', {
-						...flowForm,
-						data,
-					})
-					.then((res) => {
-						handleResult(res)
+					.post('/flowExample/setStartData', {
+						exampleId: route.query.id,
+						startDate: childrenData,
 					})
+					.then()
 			}
-		})
+			return
+		} else {
+			proxy
+				.post('/flowProcess/initiate', {
+					...flowForm,
+					data: childrenData,
+				})
+				.then((res) => {
+					handleResult(res.data)
+				})
+		}
 	}
+	proxy.$router.go(-1)
+}
+
+const nextFn = () => {
+	makeDom.value.tabsChange()
 }
 
 const getRecords = (_id) => {
@@ -261,6 +221,7 @@ const getRecords = (_id) => {
 				recordList.value = res.data.recordList
 				queryData.data.recordList = res.data.recordList
 				approvalRecordData.value = res.data
+
 			})
 	} else {
 		proxy
@@ -274,7 +235,11 @@ const getRecords = (_id) => {
 	}
 }
 onMounted(async () => {
-	//processType 10 为修改 20为查看 30回退发起 无为发起
+	//processType 10 为审批 20为查看 30回退发起 无为发起
+	if (!componentObj.value[route.query.flowKey]) {
+		showSuccessToast('代码未配置此流程!')
+		return
+	}
 	if (
 		route.query.processType == 10 ||
 		route.query.processType == 20 ||
@@ -283,7 +248,7 @@ onMounted(async () => {
 		await proxy
 			.post('/flowProcess/getStartData', { flowId: route.query.id })
 			.then((res) => {
-				queryData.data = { ...res }
+				queryData.data = { ...res.data }
 			})
 	} else {
 		queryData.data = { ...route.query }
@@ -292,23 +257,99 @@ onMounted(async () => {
 	getRecords(route.query.id)
 })
 </script>
+<style>
+.van-step--vertical .van-step__circle-container {
+	top: 25px;
+}
+
+.van-step--vertical .van-step__line {
+	top: 23px;
+}
+</style>
 <style lang="scss">
 .process {
-	padding-bottom: 60px;
-	.btn-warp {
+	.more-modal {
+		.van-field {
+			border: none;
+			background: #f1f1f1;
+			border-radius: 5px;
+			padding: 5px 10px;
+		}
+	}
+
+	.load-btn-box {
+		height: 50px;
+		text-align: center;
+		padding: 9px;
+		box-sizing: border-box;
+	}
+
+	.foot-btn-warp {
+		height: 50px;
+		line-height: 50px;
+		text-align: center;
 		display: flex;
-		justify-content: space-between;
+		width: 100vw;
+		font-size: 16px;
+
+		.agree-btn {
+			flex: 1;
+			background: #eaf0ff;
+			color: #0084ff;
+		}
+
+		.next-btn {
+			flex: 1;
+			background: #0084ff;
+			color: #fff;
+		}
+	}
+
+	.btn-warp {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		margin: 0;
+		z-index: 2;
 
-		margin: 20px 0 10px;
 		button {
 			width: 48%;
 		}
+
+		.content {
+			height: 0;
+			overflow: hidden;
+			transition: all 0.3s ease;
+			background: #fff;
+			padding: 0 12px;
+		}
+
+		.more-btn {
+			width: 100%;
+			background: #fff;
+			color: #999999;
+			font-size: 14px;
+			text-align: center;
+			height: 50px;
+			line-height: 50px;
+		}
 	}
+
+	.open-more {
+		.content {
+			height: 170px;
+		}
+	}
+
+	padding-bottom: 60px;
+
 	.card {
 		background: #fff;
 		padding: 0 12px;
 		margin-top: 10px;
 	}
+
 	.textarea {
 		.van-field {
 			border: none;
@@ -317,6 +358,7 @@ onMounted(async () => {
 			padding: 5px 10px;
 		}
 	}
+
 	.more-btn {
 		height: 60px;
 		line-height: 60px;

+ 185 - 0
src/views/procurementManagement/arrival/add.vue

@@ -0,0 +1,185 @@
+<template>
+  <div class="form">
+    <van-nav-bar
+      :title="$t('arrivalQuality.name')"
+      :left-text="$t('common.back')"
+      left-arrow
+      @click-left="onClickLeft"
+    >
+    </van-nav-bar>
+    <testForm
+      v-model="formData.data"
+      :formOption="formOption"
+      :formConfig="formConfig"
+      :rules="rules"
+      @onSubmit="onSubmit"
+      ref="formDom"
+    ></testForm>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, getCurrentInstance, onMounted } from "vue";
+import { showSuccessToast, showFailToast } from "vant";
+import { useRoute } from "vue-router";
+import testForm from "@/components/testForm/index.vue";
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const formDom = ref(null);
+const formData = reactive({
+  data: {},
+});
+const rules = {
+  qualifiedCount: [
+    {
+      required: true,
+      message: proxy.t("arrivalQuality.qualityQualifiedCanNotBeEmpty"),
+    },
+  ],
+  noQualifiedCount: [
+    {
+      required: true,
+      message: proxy.t("arrivalQuality.qualityUnQualifiedCanNotBeEmpty"),
+    },
+  ],
+};
+const formOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  submitBtnText: proxy.t("common.submit"),
+  btnConfig: {
+    isNeed: false,
+    listTitle: proxy.t("arrivalQuality.relatedContract"),
+    prop: "arrivalQualityContractList",
+    plain: true,
+    listConfig: [],
+  },
+});
+const formConfig = reactive([
+  {
+    type: "input",
+    label: proxy.t("arrivalQuality.supplyName"),
+    prop: "supplyName",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("arrivalQuality.arrivalCode"),
+    prop: "code",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("arrivalQuality.productName"),
+    prop: "productName",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("arrivalQuality.productSpec"),
+    prop: "productSpec",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("arrivalQuality.arrivalNumber"),
+    prop: "count",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("arrivalQuality.alreadyQualityNumber"),
+    prop: "sumQualityCount",
+    itemType: "text",
+    readonly: true,
+  },
+
+  {
+    type: "input",
+    label: proxy.t("arrivalQuality.qualityQualified"),
+    prop: "qualifiedCount",
+    itemType: "number",
+  },
+  {
+    type: "input",
+    label: proxy.t("arrivalQuality.qualityUnQualified"),
+    prop: "noQualifiedCount",
+    itemType: "number",
+  },
+]);
+const onClickLeft = () => history.back();
+
+onMounted(() => {
+  if (route.query && route.query.id) {
+    let ids = [route.query.id];
+    proxy.post("/arrivalDetail/detail", { ids }).then((res) => {
+      formData.data = {
+        arrivalId: route.query.arrivalId,
+        supplyId: route.query.supplyId,
+        supplyName: route.query.supplyName,
+        code: route.query.code,
+        productSpec: route.query.productSpec,
+        productName: route.query.productName,
+        count: route.query.count,
+        arrivalDetailId: res.data[0].id,
+        sumQualityCount: res.data[0].sumQualityCount,
+        qualifiedCount: "",
+        noQualifiedCount: "",
+      };
+    });
+  }
+});
+
+const onSubmit = () => {
+  let data = { ...formData.data };
+  if (Number(data.qualifiedCount) + Number(data.noQualifiedCount) > 0) {
+    if (
+      Number(data.qualifiedCount) +
+        Number(data.noQualifiedCount) +
+        Number(data.sumQualityCount) >
+      Number(data.count)
+    ) {
+      return showFailToast(
+        proxy.t(
+          "arrivalQuality.qualityInspectionQuantityNotBeGreaterThanArrivalNumber"
+        )
+      );
+    } else {
+      let obj = {
+        arrivalDetailId: data.arrivalDetailId,
+        qualifiedCount: data.qualifiedCount,
+        noQualifiedCount: data.noQualifiedCount,
+      };
+      delete data.arrivalDetailId;
+      delete data.qualifiedCount;
+      delete data.noQualifiedCount;
+      data.qualityDetailList = [obj];
+      proxy.post("/quality/add", data).then(
+        () => {
+          showSuccessToast(proxy.t("common.operationSuccessful"));
+          setTimeout(() => {
+            onClickLeft();
+          }, 500);
+        },
+        (err) => {
+          return showFailToast(err.message);
+        }
+      );
+    }
+  } else {
+    return showFailToast(
+      proxy.t("arrivalQuality.qualityInspectionQuantityCannotBeZero")
+    );
+  }
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 120 - 0
src/views/procurementManagement/arrival/index.vue

@@ -0,0 +1,120 @@
+<template>
+  <van-nav-bar
+    :title="$t('arrivalQuality.name')"
+    left-text=""
+    left-arrow
+    @click-left="onClickLeft"
+  >
+  </van-nav-bar>
+  <van-search
+    v-model="req.keyword"
+    :placeholder="$t('common.pleaseEnterKeywords')"
+    @search="onRefresh"
+  />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list
+        v-model:loading="loading"
+        :finished="finished"
+        :finished-text="$t('common.noMore')"
+        @load="getList"
+        style="margin-bottom: 60px"
+      >
+        <commonList :data="listData" @onClick="toDtl" :config="listConfig">
+          <template #quality="{ row }">
+            <div>
+              <span style="color: #70b603">{{ row.qualifiedCount }}</span>
+              /
+              <span style="color: #d9001b">{{ row.noQualifiedCount }}</span>
+              /
+              <span> {{ row.qualifiedCount + row.noQualifiedCount }}</span>
+            </div>
+          </template>
+        </commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+  dataType: "1",
+});
+const finished = ref(false);
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/arrivalDetail/page", req.value)
+    .then((res) => {
+      if (res.data.rows && res.data.rows.length > 0) {
+        res.data.rows = res.data.rows.map((x) => {
+          return {
+            ...x,
+          };
+        });
+      }
+      listData.value =
+        type === "refresh"
+          ? res.data.rows
+          : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+};
+const toDtl = (row) => {
+  proxy.$router.push({
+    path: "/main/arrivalAdd",
+    query: {
+      ...row,
+    },
+  });
+};
+const listConfig = ref([
+  {
+    label: proxy.t("arrivalQuality.supplyName"),
+    prop: "supplyName",
+  },
+  {
+    label: proxy.t("arrivalQuality.productName"),
+    prop: "productName",
+  },
+  {
+    label: proxy.t("arrivalQuality.productSpec"),
+    prop: "productSpec",
+  },
+  {
+    label: proxy.t("arrivalQuality.arrivalNumber"),
+    prop: "count",
+  },
+  {
+    type: "slot",
+    label: proxy.t("arrivalQuality.qualitySituation"),
+    slotName: "quality",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 149 - 0
src/views/procurementManagement/payment/index.vue

@@ -0,0 +1,149 @@
+<template>
+  <van-nav-bar
+    :title="$t('purchasePayment.name')"
+    left-text=""
+    left-arrow
+    @click-left="onClickLeft"
+    @click-right="onClickRight"
+  >
+    <template #right> {{ $t("purchasePayment.sendPayment") }} </template>
+  </van-nav-bar>
+  <van-search
+    v-model="req.keyword"
+    :placeholder="$t('common.pleaseEnterKeywords')"
+    @search="onRefresh"
+  />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list
+        v-model:loading="loading"
+        :finished="finished"
+        :finished-text="$t('common.noMore')"
+        @load="getList"
+        style="margin-bottom: 60px"
+      >
+        <commonList :data="listData" @onClick="toDtl" :config="listConfig">
+          <template #money="{ row }">
+            <div>{{ row.currency }} {{ moneyFormat(row.amount, 2) }}</div>
+          </template>
+          <template #approvalStatus="{ row }">
+            <div>{{ dictValueLabel(row.status, statusData) }}</div>
+          </template>
+          <template #paymentStatus="{ row }">
+            <div>{{ dictValueLabel(row.payStatus, payStatus) }}</div>
+          </template>
+        </commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+});
+const finished = ref(false);
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const statusData = ref([
+  {
+    label: "草稿",
+    value: 0,
+  },
+  {
+    label: "审批中",
+    value: 10,
+  },
+  {
+    label: "驳回",
+    value: 20,
+  },
+  {
+    label: "审批通过",
+    value: 30,
+  },
+  {
+    label: "终止",
+    value: 99,
+  },
+]);
+const payStatusData = ref([]);
+const getDict = () => {
+  proxy.getDictOne(["pay_status"]).then((res) => {
+    payStatusData.value = res["pay_status"].data.map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+  });
+};
+getDict();
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/pay/page", req.value)
+    .then((res) => {
+      listData.value =
+        type === "refresh"
+          ? res.data.rows
+          : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+};
+const toDtl = (row) => {};
+const onClickRight = () => {
+  proxy.$router.push({
+    path: "/main/processDtl",
+    query: {
+      flowKey: "pay_flow",
+    },
+  });
+};
+const listConfig = ref([
+  {
+    label: proxy.t("purchasePayment.supplyName"),
+    prop: "supplyName",
+  },
+  {
+    label: proxy.t("purchasePayment.applicationsTime"),
+    prop: "createTime",
+  },
+  {
+    type: "slot",
+    label: proxy.t("purchasePayment.applicationsAmount"),
+    slotName: "money",
+  },
+  {
+    type: "slot",
+    label: proxy.t("purchasePayment.approvalStatus"),
+    slotName: "approvalStatus",
+  },
+  {
+    type: "slot",
+    label: proxy.t("purchasePayment.paymentStatus"),
+    slotName: "paymentStatus",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 118 - 114
src/views/procurementManagement/procureList/index.vue

@@ -1,135 +1,139 @@
 <template>
-	<van-nav-bar
-		:title="$t('procureList.name')"
-		left-text=""
-		left-arrow
-		@click-left="onClickLeft"
-		@click-right="onClickRight"
-	>
-		<template #right> {{$t('procureList.purchase')}} </template>
-	</van-nav-bar>
-	<van-search
-		v-model="req.keyword"
-		:placeholder="$t('common.pleaseEnterKeywords')"
-		@search="onRefresh"
-	/>
-	<van-pull-refresh v-model="loading" @refresh="onRefresh">
-		<div class="list">
-			<van-list
-				v-model:loading="loading"
-				:finished="finished"
-				:finished-text="$t('common.noMore')"
-				@load="onLoad"
-				style="margin-bottom: 60px"
-			>
-				<commonList
-					:data="listData"
-					@onClick="toDtl"
-					:config="listConfig"
-					:isCheckbox="true"
-					@onCheck="onCkeckbox"
-					optionalKey='subcribeId'
-				></commonList>
-			</van-list>
-		</div>
-	</van-pull-refresh>
+  <van-nav-bar
+    :title="$t('procureList.name')"
+    left-text=""
+    left-arrow
+    @click-left="onClickLeft"
+    @click-right="onClickRight"
+  >
+    <template #right> {{ $t("procureList.purchase") }} </template>
+  </van-nav-bar>
+  <van-search
+    v-model="req.keyword"
+    :placeholder="$t('common.pleaseEnterKeywords')"
+    @search="onRefresh"
+  />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list
+        v-model:loading="loading"
+        :finished="finished"
+        :finished-text="$t('common.noMore')"
+        @load="onLoad"
+        style="margin-bottom: 60px"
+      >
+        <commonList
+          :data="listData"
+          @onClick="toDtl"
+          :config="listConfig"
+          :isCheckbox="true"
+          @onCheck="onCkeckbox"
+          optionalKey="subcribeId"
+        ></commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
 </template>
 <script setup>
-import { ref, getCurrentInstance, onMounted } from 'vue'
-import commonList from '@/components/common-list.vue'
-import { useRoute } from 'vue-router'
-const loading = ref(false)
-const router = useRoute()
+import { ref, getCurrentInstance, onMounted } from "vue";
+import commonList from "@/components/common-list.vue";
+import { useRoute } from "vue-router";
+import { showSuccessToast, showFailToast } from "vant";
+
+const loading = ref(false);
+const router = useRoute();
 const req = ref({
-	pageNum: 1,
-	type: '1',
-	keyword: null,
-})
-const finished = ref(false)
-const proxy = getCurrentInstance().proxy
-const listData = ref([])
+  pageNum: 1,
+  type: "1",
+  keyword: null,
+});
+const finished = ref(false);
+const proxy = getCurrentInstance().proxy;
+const listData = ref([]);
 
 const listConfig = ref([
-	{
-		label: proxy.t('procureList.procurementNumber'),
-		prop: 'subscribeCode',
-	},
-	{
-		label: proxy.t('procureList.itemName'),
-		prop: 'productName',
-	},
-	{
-		label: proxy.t('procureList.procurementQuantity'),
-		prop: 'count',
-	},
-	{
-		label: proxy.t('procureList.purchased'),
-		prop: 'purchaseCount',
-	},
-])
+  {
+    label: proxy.t("procureList.procurementNumber"),
+    prop: "subscribeCode",
+  },
+  {
+    label: proxy.t("procureList.itemName"),
+    prop: "productName",
+  },
+  {
+    label: proxy.t("procureList.procurementQuantity"),
+    prop: "count",
+  },
+  {
+    label: proxy.t("procureList.purchased"),
+    prop: "purchaseCount",
+  },
+]);
 const onRefresh = () => {
-	req.value.pageNum = 1
-	finished.value = false
-	getList('refresh')
-}
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
 const onLoad = () => {
-	getList()
-}
-let ids = []
-
+  getList();
+};
+let ids = [];
 const onCkeckbox = (row) => {
-	ids = []
-	row.map((i) => {
-		ids.push(i.id)
-	})
-}
+  row.map((i) => {
+    ids.push(i.id);
+  });
+};
 
-const onClickLeft = () => proxy.$router.push('/main/working')
+const onClickLeft = () => proxy.$router.push("/main/working");
 
 const onClickRight = () => {
-	proxy.$router.push({
-		path: 'procureListAdd',
-		query: {
-			ids: JSON.stringify(ids),
-		},
-	})
-}
-proxy.uploadDdRightBtn(onClickRight,'采购')
+  if (ids && ids.length > 0) {
+    proxy.$router.push({
+      path: "/main/processDtl",
+      query: {
+        flowKey: "purchase_flow",
+        ids: JSON.stringify(ids),
+      },
+    });
+  } else {
+    return showFailToast(proxy.t("procureList.pleaseCheckTheData"));
+  }
+};
+proxy.uploadDdRightBtn(onClickRight, "采购");
 const toDtl = (row) => {
-	proxy.$router.push({
-		path: 'procureListAdd',
-		query: {
-			ids: JSON.stringify([row.id]),
-			
-		},
-	})
-}
+  proxy.$router.push({
+    path: "procureListAdd",
+    query: {
+      ids: JSON.stringify([row.id]),
+    },
+  });
+};
 
 const getList = (type) => {
-	loading.value = true
-	proxy
-		.post('/subscribeDetail/page', req.value)
-		.then((res) => {
-			console.log(req.value)
-			listData.value =
-				type === 'refresh'
-					? res.data.rows
-					: listData.value.concat(res.data.rows)
-			if (req.value.pageNum * 10 >= res.data.total) {
-				finished.value = true
-			}
-			req.value.pageNum++
-			loading.value = false
-		})
-		.catch((err) => {
-			loading.value = false
-		})
-}
-getList()
+  loading.value = true;
+  proxy
+    .post("/subscribeDetail/page", req.value)
+    .then((res) => {
+      console.log(req.value);
+      listData.value =
+        type === "refresh"
+          ? res.data.rows
+          : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch((err) => {
+      loading.value = false;
+    });
+};
+getList();
 </script>
 
 <style lang="scss" scoped>
 .list {
-	min-height: 70vh;
+  min-height: 70vh;
 }
 </style>

+ 160 - 0
src/views/procurementManagement/receipt/index.vue

@@ -0,0 +1,160 @@
+<template>
+  <van-nav-bar
+    :title="$t('receipt.name')"
+    left-text=""
+    left-arrow
+    @click-left="onClickLeft"
+    @click-right="onClickRight"
+  >
+    <template #right> {{ $t("receipt.mergePurchase") }} </template>
+  </van-nav-bar>
+  <van-search
+    v-model="req.keyword"
+    :placeholder="$t('common.pleaseEnterKeywords')"
+    @search="onRefresh"
+  />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list
+        v-model:loading="loading"
+        :finished="finished"
+        :finished-text="$t('common.noMore')"
+        @load="getList"
+        style="margin-bottom: 60px"
+      >
+        <commonList
+          :data="listData"
+          @onClick="toDtl"
+          :config="listConfig"
+          :isCheckbox="true"
+          @onCheck="handleSelectData"
+          optionalKey="contractId"
+        >
+        </commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+  status: "15",
+});
+const finished = ref(false);
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const statusData = ref([
+  {
+    label: "草稿",
+    value: 0,
+  },
+  {
+    label: "审批中",
+    value: 10,
+  },
+  {
+    label: "驳回",
+    value: 20,
+  },
+  {
+    label: "审批通过",
+    value: 30,
+  },
+  {
+    label: "终止",
+    value: 99,
+  },
+]);
+const payStatusData = ref([]);
+const getDict = () => {
+  proxy.getDictOne(["pay_status"]).then((res) => {
+    payStatusData.value = res["pay_status"].data.map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+  });
+};
+getDict();
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/contractProduct/page", req.value)
+    .then((res) => {
+      listData.value =
+        type === "refresh"
+          ? res.data.rows
+          : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+};
+const toDtl = (row) => {};
+const onClickRight = () => {
+  if (ids && ids.length > 0) {
+    proxy.$router.push({
+      path: "/main/processDtl",
+      query: {
+        isReceipt: true,
+        flowKey: "purchase_flow",
+        ids: JSON.stringify(ids),
+        contractId: selectData.value[0].contractId,
+      },
+    });
+  } else {
+    return showFailToast(proxy.t("procureList.pleaseCheckTheData"));
+  }
+};
+const listConfig = ref([
+  {
+    label: proxy.t("receipt.belongToCompany"),
+    prop: "corporationName",
+  },
+  {
+    label: proxy.t("receipt.contractCode"),
+    prop: "contractCode",
+  },
+  {
+    label: proxy.t("receipt.orderTime"),
+    prop: "contractTime",
+  },
+  {
+    label: proxy.t("receipt.productName"),
+    prop: "productName",
+  },
+  {
+    label: proxy.t("receipt.pendingProcessing"),
+    prop: "expendQuantity",
+  },
+]);
+let ids = [];
+let selectData = ref([]);
+const handleSelectData = (row) => {
+  selectData.value = row;
+  row.map((i) => {
+    ids.push(i.id);
+  });
+};
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 1 - 1
src/views/procurementManagement/subscribe/index.vue

@@ -72,7 +72,7 @@ const onLoad = () => {
 const onClickLeft = () => proxy.$router.push("/main/working");
 
 const onClickRight = () => {
-  proxy.$router.push("/main/subscribeAdd");
+  proxy.$router.push("/main/processDtl?flowKey=subscribe_flow");
 };
 proxy.uploadDdRightBtn(onClickRight,'发起申购')
 const toDtl = (row) => {

+ 1 - 1
src/views/product-material/product-library/index.vue

@@ -98,11 +98,11 @@ const getList = (type) => {
       res.data.rows = res.data.rows.map((item) => {
         return {
           ...item,
-          productClassifyName: item.classifyNameGroup.join(" / "),
         };
       });
       listData.value = type === "refresh" ? res.data.rows : listData.value.concat(res.data.rows);
       if (req.value.pageNum * 10 >= res.data.total) {
+        
         finished.value = true;
       }
       req.value.pageNum++;

+ 205 - 0
src/views/product-material/standard-product-library/add.vue

@@ -0,0 +1,205 @@
+<template>
+	<div class="form">
+		<van-nav-bar
+			:title="$t('productLibrary.name')"
+			:left-text="$t('common.back')"
+			left-arrow
+			@click-left="onClickLeft"
+		>
+		</van-nav-bar>
+		
+    <testForm
+      v-model="formData.data"
+      :formOption="formOption"
+      :formConfig="formConfig"
+      :rules="rules"
+      @onSubmit="onSubmit"
+      ref="formDom"
+    ></testForm>
+	</div>
+</template>
+
+<script setup>
+import { ref, getCurrentInstance, onMounted,reactive } from "vue";
+import { showSuccessToast, showToast } from "vant";
+import { useRoute } from "vue-router";
+import { getUserInfo } from '@/utils/auth';
+import testForm from "@/components/testForm/index.vue";
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const show = ref(false);
+const typeModal = ref(false);
+const unitModal = ref(false);
+const classification = ref([]);
+const formData = reactive({
+  data: {
+  },
+});
+const formDom = ref(null);
+const formOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  // hiddenSubmitBtn: true,
+});
+const formConfig = reactive([
+  {
+    type: "cascader",
+    label: proxy.t('productLibrary.productClassification'),
+    prop: "productClassifyId",
+    itemType: "common",
+    showPicker: false,
+    // data: classification.value,
+    data: [],
+    fieldNames: {
+      text: "label",
+      value: "id",
+      children: "children",
+    },
+    // onChangeFn: (option) => {
+    //   // console.log("aa");
+    // },
+    // finishFn: (current, option) => {
+    //   current.showPicker = false;
+    // },
+  },
+  {
+    type: "picker",
+    label: proxy.t('productLibrary.productType'),
+    prop: "type",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "id",
+    },
+    data: [
+      {
+        label: proxy.t('productLibrary.finishedProduct'),
+        id: "10",
+      },
+      {
+        label: proxy.t('productLibrary.semifinishedProduct'),
+        id: "2",
+      },
+    ],
+  },
+  {
+    type: "input",
+    itemType: "text",
+    label: proxy.t('productLibrary.productName'),
+    prop: "name",
+    clearable: true,
+  },
+  {
+    type: "input",
+    itemType: "text",
+    label: proxy.t('productLibrary.specificationModel'),
+    prop: "spec",
+    clearable: true,
+  },
+  {
+    type: "picker",
+    label: proxy.t('productLibrary.unit'),
+    prop: "unit",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "dictValue",
+      value: "dictKey",
+    },
+    data: []
+  },
+  {
+    type: "upload",
+    label: proxy.t('productLibrary.fileUpload'),
+    prop: "fileList",
+  },
+  {
+    type: "input",
+    itemType: "textarea",
+    label: proxy.t('productLibrary.remarks'),
+    prop: "remark",
+  },
+]);
+const rules = {
+  productClassifyId: [{ required: true, message: proxy.t('productLibrary.productClassificationCanNotBeEmpty') }],
+  type: [{ required: true, message: proxy.t('productLibrary.productTypeCanNotBeEmpty') }],
+  name: [{ required: true, message: proxy.t('productLibrary.productNameCanNotBeEmpty') }],
+  spec: [{ required: true, message: proxy.t('productLibrary.specificationModelCanNotBeEmpty') }],
+  unit: [{ required: true, message: proxy.t('productLibrary.unitCanNotBeEmpty') }],
+  select: [{ required: true, message: proxy.t('productLibrary.pleaseSelect') }],
+  date: [{ required: true, message: proxy.t('productLibrary.pleaseSelectTime') }],
+  common: [{ required: true, message: proxy.t('productLibrary.pleaseSelectCascader') }],
+  // city: [{ required: true, message: "请选择城市" }],
+};
+const unitList = ref([]);
+
+const getDict = () => {
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      tenantId: getUserInfo().tenantId,
+      dictCode: "unit",
+    })
+    .then((res) => {
+      formConfig[4].data = res.data.rows
+    })
+}
+getDict()
+const fileList = ref([]);
+const onClickLeft = () => history.back();
+const onSubmit = () => {
+  console.log(formData)
+  
+  proxy.post("/productInfo/" + route.query.type, formData.data).then(() => {
+    showSuccessToast(proxy.t('common.addSuccess'));
+    setTimeout(() => {
+      history.back();
+    }, 500);
+  });
+};
+const treeToList = (arr) => {
+  let res = []; // 用于存储递归结果(扁平数据)
+  // 递归函数
+  let fn = (source) => {
+    source.forEach((el) => {
+      res.push(el);
+      el.children && el.children.length > 0 ? fn(el.children) : ""; // 子级递归
+    });
+  };
+  fn(arr);
+  return res;
+};
+onMounted(() => {
+  proxy.post("/productClassify/tree", { parentId: "", name: "", definition: "1" }).then((res) => {
+    formConfig[0].data = res.data;
+    let classList = treeToList(res.data);
+    if (route.query.id) {
+      proxy.post("/productInfo/detail", { id: route.query.id }).then((resDetail) => {
+        formData.data = resDetail.data
+        
+      });
+      // proxy.post("/fileInfo/getList", { businessIdList: [route.query.id] }).then((res) => {
+      //   if (res.data[route.query.id] && res.data[route.query.id].length > 0) {
+      //     formData.value.fileList = res.data[route.query.id];
+      //     fileList.value = res.data[route.query.id].map((item) => {
+      //       return {
+      //         ...item,
+      //         url: item.fileUrl,
+      //       };
+      //     });
+      //   } else {
+      //     formData.value.fileList = [];
+      //     fileList.value = [];
+      //   }
+      // });
+    }else {
+      
+    }
+  });
+});
+</script>

+ 122 - 0
src/views/product-material/standard-product-library/index.vue

@@ -0,0 +1,122 @@
+<template>
+    <van-nav-bar :title="$t('productLibrary.name')" left-text="" left-arrow @click-left="onClickLeft" @click-right="onClickRight">
+      <template #right> {{$t('common.add')}} </template>
+    </van-nav-bar>
+    <van-search v-model="req.keyword" :placeholder="$t('common.pleaseEnterKeywords')" @search="onRefresh" />
+    <van-pull-refresh v-model="loading" @refresh="onRefresh">
+      <div class="list">
+        <van-list v-model:loading="loading" :finished="finished" :finished-text="$t('common.noMore')" @load="onLoad" style="margin-bottom: 60px">
+          <commonList :data="listData" @onClick="toDtl" :config="listConfig"></commonList>
+        </van-list>
+      </div>
+    </van-pull-refresh>
+  </template>
+  <script setup>
+  import { ref, getCurrentInstance } from "vue";
+  import commonList from "@/components/common-list.vue";
+  import { useRoute } from "vue-router";
+  
+  const loading = ref(false);
+  const router = useRoute();
+  const req = ref({
+    pageNum: 1,
+    keyword: null,
+    definition: "1",
+  });
+  const finished = ref(false);
+  const proxy = getCurrentInstance().proxy;
+  const listData = ref([]);
+  const classification = ref([]);
+  const listConfig = ref([
+    {
+      label: proxy.t('productLibrary.productClassification'),
+      prop: "productClassifyName",
+    },
+    {
+      label: proxy.t('productLibrary.productCode'),
+      prop: "code",
+    },
+    {
+      label: proxy.t('productLibrary.productName'),
+      prop: "name",
+    },
+  ]);
+  const onRefresh = () => {
+    req.value.pageNum = 1;
+    finished.value = false;
+    getList("refresh");
+  };
+  const onLoad = () => {
+    getClassification();
+  };
+  const onClickLeft = () => proxy.$router.push("/main/working");
+  const onClickRight = () => {
+    proxy.$router.push({
+      path: "productLibraryAdd",
+      query: {
+          type: 'add'
+      },
+    });
+  };
+  proxy.uploadDdRightBtn(onClickRight,proxy.t('common.add'))
+  const toDtl = (row) => {
+    proxy.$router.push({
+      path: "productLibraryAdd",
+      query: {
+        id: row.id,
+        type: 'edit'
+      },
+    });
+  };
+  const treeToList = (arr) => {
+    let res = []; // 用于存储递归结果(扁平数据)
+    // 递归函数
+    let fn = (source) => {
+      source.forEach((el) => {
+        res.push(el);
+        el.children && el.children.length > 0 ? fn(el.children) : ""; // 子级递归
+      });
+    };
+    fn(arr);
+    return res;
+  };
+  const getClassification = () => {
+    if (classification.value && classification.value.length > 0) {
+      getList();
+    } else {
+      proxy.post("/productClassify/tree", { parentId: "", name: "", definition: "1" }).then((res) => {
+        classification.value = treeToList(res.data);
+        getList();
+      });
+    }
+  };
+  const getList = (type) => {
+    loading.value = true;
+    proxy
+      .post("/productInfo/page", req.value)
+      .then((res) => {
+        res.data.rows = res.data.rows.map((item) => {
+          return {
+            ...item,
+          };
+        });
+        listData.value = type === "refresh" ? res.data.rows : listData.value.concat(res.data.rows);
+        if (req.value.pageNum * 10 >= res.data.total) {
+          
+          finished.value = true;
+        }
+        req.value.pageNum++;
+        loading.value = false;
+      })
+      .catch((err) => {
+        loading.value = false;
+      });
+  };
+  </script>
+  
+  <style lang="scss" scoped>
+  .list {
+    min-height: 70vh;
+  }
+  </style>
+  

+ 194 - 0
src/views/purchase-payment/invoice/add.vue

@@ -0,0 +1,194 @@
+<template>
+  <div class="form">
+    <van-nav-bar :title="$t('invoice.' + route.query.type)" :left-text="$t('common.back')" left-arrow @click-left="onClickLeft"> </van-nav-bar>
+    <testForm v-model="formData.data" :formOption="formOption" :formConfig="formConfig" :rules="rules" @onSubmit="onSubmit" ref="formDom"> </testForm>
+  </div>
+</template>
+
+<script setup>
+import { ref, getCurrentInstance, onMounted, reactive } from "vue";
+import { showSuccessToast, showFailToast } from "vant";
+import { useRoute } from "vue-router";
+import { getUserInfo } from "@/utils/auth";
+import testForm from "@/components/testForm/index.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => history.back();
+const route = useRoute();
+const getDict = () => {
+  proxy.post("/supplierInfo/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[0].data = res.data.rows.map((item) => {
+        return {
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  let query = {
+    pageNum: 1,
+    pageSize: 999,
+    tenantId: getUserInfo().tenantId,
+  };
+  proxy.post("/dictTenantData/page", { ...query, dictCode: "invoice_type" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      formConfig[1].data = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+  proxy.get("/tenantUser/list", { pageNum: 1, pageSize: 10000, tenantId: getUserInfo().tenantId }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+    }
+  });
+};
+getDict();
+const formData = reactive({
+  data: {
+    supplyId: null,
+    money: null,
+    type: null,
+    remark: null,
+    invoiceDetailsList: [],
+  },
+});
+const formDom = ref(null);
+const formOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  hiddenSubmitBtn: false,
+  btnConfig: {
+    isNeed: false,
+    prop: "invoiceDetailsList",
+    plain: true,
+    listTitle: proxy.t("invoice.purchaseContract"),
+    listConfig: [
+      {
+        type: "input",
+        label: proxy.t("invoice.contractCode"),
+        prop: "code",
+        readonly: true,
+      },
+      {
+        type: "input",
+        label: proxy.t("invoice.contractMoney"),
+        prop: "amount",
+        readonly: true,
+      },
+      {
+        type: "input",
+        label: proxy.t("invoice.receivedInvoice"),
+        prop: "sumInvoiceMoney",
+        readonly: true,
+      },
+      {
+        type: "input",
+        label: proxy.t("invoice.relatedAmount"),
+        prop: "money",
+        itemType: "number",
+      },
+    ],
+  },
+});
+const formConfig = reactive([
+  {
+    type: "picker",
+    label: proxy.t("invoice.supplyName"),
+    prop: "supplyId",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+    readonly: route.query.id,
+    changeFn: (val, data) => {
+      proxy.formChange(val, data, formData);
+      proxy.get("/purchase/getNoInvoiceListBySupplyId", { supplyId: val.selectedValues[0] }).then((res) => {
+        if (res.data && res.data.length > 0) {
+          formData.data.invoiceDetailsList = res.data.map((item) => {
+            return {
+              purchaseId: item.id,
+              code: item.code,
+              amount: item.amount,
+              sumInvoiceMoney: item.sumInvoiceMoney,
+              money: null,
+              remark: "",
+            };
+          });
+        } else {
+          formData.data.invoiceDetailsList = [];
+        }
+      });
+      data.showPicker = false;
+    },
+  },
+  {
+    type: "picker",
+    label: proxy.t("invoice.type"),
+    prop: "type",
+    itemType: "onePicker",
+    showPicker: false,
+    fieldNames: {
+      text: "label",
+      value: "value",
+    },
+    data: [],
+  },
+  {
+    type: "input",
+    label: proxy.t("invoice.invoiceAmount"),
+    prop: "money",
+    itemType: "number",
+  },
+]);
+const rules = {
+  supplyId: [{ required: true, message: proxy.t("invoice.supplyNameMsg") }],
+  type: [{ required: true, message: proxy.t("invoice.typeMsg") }],
+  money: [{ required: true, message: proxy.t("invoice.invoiceAmountMsg") }],
+  relatedAmount: [{ required: true, message: proxy.t("invoice.relatedAmountMsg") }],
+};
+const onSubmit = () => {
+  if (!(formData.data.invoiceDetailsList && formData.data.invoiceDetailsList.length > 0)) {
+    return showFailToast(proxy.t("invoice.supplierNoContract"));
+  }
+  let money = 0;
+  for (let i = 0; i < formData.data.invoiceDetailsList.length; i++) {
+    money = parseFloat(Number(money) + Number(formData.data.invoiceDetailsList[i].money)).toFixed(2);
+  }
+  if (Number(money) != Number(formData.data.money)) {
+    return showFailToast(proxy.t("invoice.unequalAmounts"));
+  }
+  proxy.post("/invoice/" + route.query.type, formData.data).then(() => {
+    showSuccessToast(route.query.type === "add" ? proxy.t("common.addSuccess") : proxy.t("common.modifySuccess"));
+    setTimeout(() => {
+      onClickLeft();
+    }, 500);
+  });
+};
+onMounted(() => {
+  if (route.query.id) {
+    proxy.post("/invoice/detail", { id: route.query.id }).then((res) => {
+      res.data.type = res.data.type + "";
+      res.data.invoiceDetailsList = res.data.invoiceDetailsVoList.map((item) => {
+        return {
+          code: item.purchaseCode,
+          purchaseId: item.purchaseId,
+          amount: item.purchaseAmount,
+          sumInvoiceMoney: item.sumMoney,
+          money: item.money,
+        };
+      });
+      formData.data = res.data;
+    });
+  }
+});
+</script>

+ 112 - 0
src/views/purchase-payment/invoice/index.vue

@@ -0,0 +1,112 @@
+<template>
+  <van-nav-bar :title="$t('invoice.name')" left-text="" left-arrow @click-left="onClickLeft" @click-right="onClickRight">
+    <template #right>{{ $t("common.add") }}</template>
+  </van-nav-bar>
+  <van-search v-model="req.keyword" :placeholder="$t('common.pleaseEnterKeywords')" @search="onRefresh" />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list v-model:loading="loading" :finished="finished" :finished-text="$t('common.noMore')" @load="getList" style="margin-bottom: 60px">
+        <commonList :data="listData" @onClick="toDtl" :config="listConfig"></commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+import { getUserInfo } from "@/utils/auth";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const onClickRight = () => {
+  proxy.$router.push({
+    path: "invoiceAdd",
+    query: {
+      type: "add",
+    },
+  });
+};
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+});
+const finished = ref(false);
+const invoiceType = ref([]);
+const getDict = () => {
+  return proxy.post("/dictTenantData/page", { pageNum: 1, pageSize: 999, tenantId: getUserInfo().tenantId, dictCode: "invoice_type" }).then((res) => {
+    if (res.data.rows && res.data.rows.length > 0) {
+      invoiceType.value = res.data.rows.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    }
+  });
+};
+getDict();
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/invoice/page", req.value)
+    .then((res) => {
+      if (res.data.rows && res.data.rows.length > 0) {
+        res.data.rows = res.data.rows.map((item) => {
+          let typeText = "";
+          if (item.type) {
+            typeText = proxy.dictValueLabel(item.type, invoiceType.value);
+          }
+          return {
+            ...item,
+            typeText: typeText,
+          };
+        });
+      }
+      listData.value = type === "refresh" ? res.data.rows : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+};
+const toDtl = (row) => {
+  proxy.$router.push({
+    path: "invoiceAdd",
+    query: {
+      type: "edit",
+      id: row.id,
+    },
+  });
+};
+const listConfig = ref([
+  {
+    label: proxy.t("invoice.supplyName"),
+    prop: "supplyName",
+  },
+  {
+    label: proxy.t("invoice.type"),
+    prop: "typeText",
+  },
+  {
+    label: proxy.t("invoice.money"),
+    prop: "money",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 212 - 0
src/views/purchase-sales/inventory-management/Inventory/add.vue

@@ -0,0 +1,212 @@
+<template>
+  <div class="form">
+    <van-nav-bar
+      :title="$t('inventoryCount.name')"
+      :left-text="$t('common.back')"
+      left-arrow
+      @click-left="onClickLeft"
+    >
+    </van-nav-bar>
+    <testForm
+      v-model="formData.data"
+      :formOption="formOption"
+      :formConfig="formConfig"
+      :rules="rules"
+      @onSubmit="onSubmit"
+      ref="formDom"
+    ></testForm>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, getCurrentInstance, onMounted } from "vue";
+import { showSuccessToast, showFailToast } from "vant";
+import { useRoute } from "vue-router";
+import testForm from "@/components/testForm/index.vue";
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const formDom = ref(null);
+const formData = reactive({
+  data: {},
+});
+const rules = {
+  warehouseId: [
+    {
+      required: true,
+      message: proxy.t("inventoryCount.inventoryWarehouseCanNotBeEmpty"),
+    },
+  ],
+  productId: [
+    {
+      required: true,
+      message: proxy.t("inventoryCount.goodsNameCanNotBeEmpty"),
+    },
+  ],
+  checkQuantity: [
+    {
+      required: true,
+      message: proxy.t("inventoryCount.inventoryNumberCanNotBeEmpty"),
+    },
+  ],
+};
+const formOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  submitBtnText: proxy.t("common.submit"),
+  hiddenSubmitBtn: false,
+  btnConfig: {
+    isNeed: true,
+    label: proxy.t("common.details"),
+    prop: "list",
+    plain: true,
+    listConfig: [
+      {
+        type: "picker",
+        label: proxy.t("inventoryCount.goodsName"),
+        prop: "productId",
+        itemType: "onePicker",
+        showPicker: false,
+        readonly: false,
+        fieldNames: {
+          text: "name",
+          value: "id",
+        },
+        data: [],
+        changeFn: function (option, item, index, currentSonIndex) {
+          formData.data.list[index][item.prop] = option.selectedOptions[0].id;
+          formData.data.list[index][item.prop + "Name"] =
+            option.selectedOptions[0].name;
+          formDom.value.btnConfigCopy.listConfig[
+            currentSonIndex
+          ].showPicker = false;
+          getStokeQuantity();
+        },
+      },
+      {
+        type: "input",
+        itemType: "text",
+        label: proxy.t("inventoryCount.stockNumber"),
+        prop: "quantity",
+        readonly: true,
+      },
+      {
+        type: "input",
+        itemType: "number",
+        label: proxy.t("inventoryCount.inventoryNumber"),
+        prop: "checkQuantity",
+        readonly: false,
+      },
+    ],
+    clickFn: () => {
+      if (formData.data.list && formData.data.list.length > 0) {
+        formData.data.list.push({
+          productId: "",
+          quantity: "",
+          checkQuantity: "",
+        });
+      } else {
+        formData.data.list = [
+          {
+            productId: "",
+            quantity: "",
+            checkQuantity: "",
+          },
+        ];
+      }
+    },
+  },
+});
+const formConfig = reactive([
+  {
+    type: "picker",
+    label: proxy.t("inventoryCount.inventoryWarehouse"),
+    prop: "warehouseId",
+    itemType: "onePicker",
+    showPicker: false,
+    readonly: false,
+    fieldNames: {
+      text: "name",
+      value: "id",
+    },
+    data: [],
+    changeFn: function (option, item, index) {
+      formData.data[item.prop] = option.selectedOptions[0].id;
+      formData.data[item.prop + "Name"] = option.selectedOptions[0].name;
+      formConfig[index].showPicker = false;
+      getStokeQuantity();
+    },
+  },
+]);
+const onClickLeft = () => history.back();
+const productData = ref([]);
+const getDict = () => {
+  proxy.post("/warehouse/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
+    formConfig[0].data = res.data.rows;
+  });
+  proxy
+    .post("/productInfo/page", { pageNum: 1, pageSize: 9999, definition: "" })
+    .then((res) => {
+      formOption.btnConfig.listConfig[0].data = res.data.rows;
+      productData.value = res.data.rows;
+    });
+};
+const getStokeQuantity = () => {
+  if (
+    formData.data.warehouseId &&
+    formData.data.list &&
+    formData.data.list.length > 0
+  ) {
+    let arr = [];
+    arr = formData.data.list.map((x) => x.productId);
+    if (arr.length > 0) {
+      proxy
+        .post("/stock/pageByWarehouse", {
+          id: formData.data.warehouseId,
+          productIds: arr,
+        })
+        .then((res) => {
+          for (let i = 0; i < formData.data.list.length; i++) {
+            const e = formData.data.list[i];
+            const current = res.data.rows.find(
+              (x) => x.productId === e.productId
+            );
+            if (current) {
+              e.quantity = current.quantity;
+            } else {
+              e.quantity = "0";
+            }
+          }
+        });
+    }
+  }
+};
+onMounted(() => {
+  getDict();
+  if (route.query && route.query.id) {
+    formOption.hiddenSubmitBtn = true;
+    formOption.btnConfig.isNeed = false;
+    proxy.post("/stockCheck/detail", { id: route.query.id }).then((res) => {
+      formData.data = res.data;
+    });
+  }
+});
+
+const onSubmit = () => {
+  proxy.post("/stockCheck/add", formData.data).then(
+    () => {
+      showSuccessToast(proxy.t("common.operationSuccessful"));
+      setTimeout(() => {
+        onClickLeft();
+      }, 500);
+    },
+    (err) => {
+      return showFailToast(err.message);
+    }
+  );
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 110 - 0
src/views/purchase-sales/inventory-management/Inventory/index.vue

@@ -0,0 +1,110 @@
+<template>
+  <van-nav-bar
+    :title="$t('inventoryCount.name')"
+    left-text=""
+    left-arrow
+    @click-left="onClickLeft"
+    @click-right="onClickRight"
+  >
+    <template #right> {{ $t("common.add") }} </template>
+  </van-nav-bar>
+  <van-search
+    v-model="req.keyword"
+    :placeholder="$t('common.pleaseEnterKeywords')"
+    @search="onRefresh"
+  />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list
+        v-model:loading="loading"
+        :finished="finished"
+        :finished-text="$t('common.noMore')"
+        @load="getList"
+        style="margin-bottom: 60px"
+      >
+        <commonList :data="listData" @onClick="toDtl" :config="listConfig">
+          <template #inventoryResult="{ row }">
+            <div>
+              <span v-if="row.result == 0">正常</span>
+              <span style="color: #d9001b" v-else>异常</span>
+            </div>
+          </template>
+        </commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+  dataType: "1",
+});
+const finished = ref(false);
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/stockCheck/page", req.value)
+    .then((res) => {
+      listData.value =
+        type === "refresh"
+          ? res.data.rows
+          : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+};
+const toDtl = (row) => {
+  proxy.$router.push({
+    path: "/main/inventoryCountAdd",
+    query: {
+      id: row.id,
+    },
+  });
+};
+const onClickRight = () => {
+  proxy.$router.push({
+    path: "/main/inventoryCountAdd",
+    query: {},
+  });
+};
+const listConfig = ref([
+  {
+    label: proxy.t("inventoryCount.inventoryTime"),
+    prop: "createTime",
+  },
+  {
+    label: proxy.t("inventoryCount.inventoryPerson"),
+    prop: "userName",
+  },
+  {
+    type: "slot",
+    label: proxy.t("inventoryCount.inventoryResult"),
+    slotName: "inventoryResult",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 1 - 1
src/views/purchase-sales/inventory-management/outInList/index.vue

@@ -1,6 +1,6 @@
 <template>
   <van-nav-bar
-    :title="$t('inventoryQuery.inOutFlow')"
+    :title="$t('inventoryQuery.inOutWarehouseFlow')"
     left-text=""
     left-arrow
     @click-left="onClickLeft"

+ 230 - 0
src/views/salesContract/claim/add.vue

@@ -0,0 +1,230 @@
+<template>
+  <div class="form">
+    <van-nav-bar
+      :title="$t('claim.name')"
+      :left-text="$t('common.back')"
+      left-arrow
+      @click-left="onClickLeft"
+    >
+    </van-nav-bar>
+    <testForm
+      v-model="formData.data"
+      :formOption="formOption"
+      :formConfig="formConfig"
+      :rules="rules"
+      @onSubmit="onSubmit"
+      ref="formDom"
+    ></testForm>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, getCurrentInstance, onMounted } from "vue";
+import { showSuccessToast, showFailToast } from "vant";
+import { useRoute } from "vue-router";
+import testForm from "@/components/testForm/index.vue";
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const formDom = ref(null);
+const formData = reactive({
+  data: {},
+});
+const rules = {
+  contractId: [
+    {
+      required: true,
+      message: proxy.t("claim.contractCanNotBeEmpty"),
+    },
+  ],
+  money: [
+    {
+      required: true,
+      message: proxy.t("claim.relatedAmountCanNotBeEmpty"),
+    },
+  ],
+};
+const formOption = reactive({
+  readonly: false, //用于控制整个表单是否只读
+  disabled: false,
+  labelAlign: "top",
+  scroll: true,
+  labelWidth: "62pk",
+  submitBtnText: proxy.t("common.submit"),
+  btnConfig: {
+    isNeed: true,
+    listTitle: proxy.t("claim.relatedContract"),
+    prop: "claimContractList",
+    plain: true,
+    listConfig: [
+      {
+        type: "picker",
+        label: proxy.t("claim.contractCode"),
+        prop: "contractId",
+        itemType: "onePicker",
+        showPicker: false,
+        readonly: false,
+        fieldNames: {
+          text: "code",
+          value: "id",
+        },
+        data: [],
+      },
+      {
+        type: "input",
+        itemType: "number",
+        label: proxy.t("claim.relatedAmount"),
+        prop: "money",
+      },
+    ],
+    clickFn: () => {
+      if (
+        formData.data.claimContractList &&
+        formData.data.claimContractList.length > 0
+      ) {
+        formData.data.claimContractList.push({
+          contractId: "",
+          contractCode: "",
+          money: "",
+        });
+      } else {
+        formData.data.claimContractList = [
+          {
+            contractId: "",
+            contractCode: "",
+            money: "",
+          },
+        ];
+      }
+    },
+  },
+});
+const formConfig = reactive([
+  {
+    type: "title",
+    title: proxy.t("claim.accountInfo"),
+  },
+  {
+    type: "input",
+    label: proxy.t("claim.accountName"),
+    prop: "accountManagementName",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("claim.accountTime"),
+    prop: "transactionTime",
+    itemType: "text",
+    readonly: true,
+  },
+  {
+    type: "input",
+    label: proxy.t("claim.accountAmount"),
+    prop: "currencyMoney",
+    itemType: "text",
+    readonly: true,
+  },
+]);
+const onClickLeft = () => history.back();
+const getDict = () => {
+  proxy
+    .post("/contract/page", {
+      pageNum: 1,
+      pageSize: 9999,
+      status: "30",
+      refundStatusNew: "0,10",
+    })
+    .then((res) => {
+      formOption.btnConfig.listConfig[0].data = res.data.rows;
+    });
+};
+onMounted(() => {
+  getDict();
+  if (route.query.isClaim != "1") {
+    proxy
+      .get(`/claim/sumClaimMoney?businessId=${route.query.id}`)
+      .then((res) => {
+        let waitAmount = Number(route.query.amount) - Number(res.data);
+        formData.data = {
+          businessId: route.query.id,
+          status: route.query.status + "",
+          currency: route.query.currency,
+          waitAmount,
+          accountManagementId: route.query.accountManagementId,
+          accountManagementName: route.query.accountManagementName,
+          currencyMoney: route.query.currency + " " + parseFloat(waitAmount),
+          transactionTime: route.query.transactionTime,
+          claimContractList: [],
+        };
+      });
+  } else {
+    formOption.btnConfig.isNeed = false;
+    formOption.readonly = true;
+    formOption.submitBtnText = proxy.t("claim.cancelClaim");
+    proxy.post("/claim/claimRecord", { businessId: route.query.id }).then(
+      (res) => {
+        formData.data = {
+          accountManagementName: route.query.accountManagementName,
+          currencyMoney: route.query.currency + " " + route.query.amount,
+          transactionTime: route.query.transactionTime,
+          claimContractList: res.data,
+        };
+        // formDom.value.formDataListShowLabelOne();
+      },
+      (err) => {
+        return showFailToast(err.message);
+      }
+    );
+  }
+});
+
+const onSubmit = () => {
+  if (route.query.isClaim != "1") {
+    if (formData.data.claimContractList.length > 0) {
+      let list = formData.data.claimContractList;
+      for (let i = 0; i < list.length; i++) {
+        const e = list[i];
+        if (!(Number(e.money) > 0)) {
+          return showFailToast(
+            proxy.t("claim.relatedAmountMustBeGreaterThanZero")
+          );
+        }
+      }
+      const total = list.reduce((total, x) => (total += Number(x.money)), 0);
+      if (total > Number(formData.data.waitAmount)) {
+        return showFailToast(
+          proxy.t("claim.relatedAmountTotalNotBeGreaterThanAccountAmount")
+        );
+      }
+      formData.data.amount = total;
+      proxy.post("/claim/add", formData.data).then(
+        () => {
+          showSuccessToast(proxy.t("common.operationSuccessful"));
+          setTimeout(() => {
+            onClickLeft();
+          }, 500);
+        },
+        (err) => {
+          return showFailToast(err.message);
+        }
+      );
+    } else {
+      return showFailToast(proxy.t("claim.addDetails"));
+    }
+  } else {
+    proxy.post("/claim/delete", { id: route.query.id }).then(
+      () => {
+        showSuccessToast(proxy.t("common.operationSuccessful"));
+        setTimeout(() => {
+          onClickLeft();
+        }, 500);
+      },
+      (err) => {
+        return showFailToast(err.message);
+      }
+    );
+  }
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 124 - 0
src/views/salesContract/claim/index.vue

@@ -0,0 +1,124 @@
+<template>
+  <van-nav-bar
+    :title="$t('claim.name')"
+    left-text=""
+    left-arrow
+    @click-left="onClickLeft"
+  >
+  </van-nav-bar>
+  <van-search
+    v-model="req.keyword"
+    :placeholder="$t('common.pleaseEnterKeywords')"
+    @search="onRefresh"
+  />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list
+        v-model:loading="loading"
+        :finished="finished"
+        :finished-text="$t('common.noMore')"
+        @load="getList"
+        style="margin-bottom: 60px"
+      >
+        <commonList
+          :data="listData"
+          @onClick="toDtl"
+          :config="listConfig"
+        ></commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+  dataType: "1",
+});
+const finished = ref(false);
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/accountRunningWater/page", req.value)
+    .then((res) => {
+      if (res.data.rows && res.data.rows.length > 0) {
+        res.data.rows = res.data.rows.map((x) => {
+          let text = "";
+          if (x.isClaim == 0) {
+            text = "未认领";
+          } else if (x.isClaim == 1) {
+            text = "已认领";
+          } else {
+            text = "部分认领";
+          }
+          return {
+            ...x,
+            isClaimText: text,
+            dfAcountName: x.name + ` (${x.accountOpening})`,
+            currencyMoney: x.currency + " " + x.amount,
+          };
+        });
+      }
+      listData.value =
+        type === "refresh"
+          ? res.data.rows
+          : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+};
+const toDtl = (row) => {
+  proxy.$router.push({
+    path: "/main/claimAdd",
+    query: {
+      ...row,
+    },
+  });
+};
+const listConfig = ref([
+  {
+    label: proxy.t("claim.accountName"),
+    prop: "accountManagementName",
+  },
+  {
+    label: proxy.t("claim.accountAmount"),
+    prop: "currencyMoney",
+  },
+  {
+    label: proxy.t("claim.accountTime"),
+    prop: "transactionTime",
+  },
+  {
+    label: proxy.t("claim.oppositeAccount"),
+    prop: "dfAcountName",
+  },
+  {
+    label: proxy.t("claim.claimStatus"),
+    prop: "isClaimText",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 102 - 0
src/views/salesContract/contract/index.vue

@@ -0,0 +1,102 @@
+<template>
+  <van-nav-bar :title="$t('contract.name')" left-text="" left-arrow @click-left="onClickLeft" @click-right="onClickRight">
+    <template #right>{{ $t("common.add") }}</template>
+  </van-nav-bar>
+  <van-search v-model="req.keyword" :placeholder="$t('common.pleaseEnterKeywords')" @search="onRefresh" />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list v-model:loading="loading" :finished="finished" :finished-text="$t('common.noMore')" @load="getList" style="margin-bottom: 60px">
+        <commonList :data="listData" @onClick="toDtl" :config="listConfig"></commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const onClickRight = () => {
+  proxy.$router.push({
+    path: "/main/processDtl",
+    query: {
+      flowKey: "contract_flow",
+    },
+  });
+};
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+});
+const finished = ref(false);
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/contract/page", req.value)
+    .then((res) => {
+      if (res.data.rows && res.data.rows.length > 0) {
+        res.data.rows = res.data.rows.map((item) => {
+          return {
+            ...item,
+            currencyAmount: item.currency + " " + item.amount,
+          };
+        });
+      }
+      listData.value = type === "refresh" ? res.data.rows : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+};
+const toDtl = (row) => {
+  // proxy.$router.push({
+  //   path: "/main/processDtl",
+  //   query: {
+  //     flowKey: "contract_flow",
+  //     id: row.flowInfoId,
+  //     processType: 20,
+  //   },
+  // });
+};
+const listConfig = ref([
+  {
+    label: proxy.t("contract.sellCorporation"),
+    prop: "sellCorporationName",
+  },
+  {
+    label: proxy.t("contract.contractType"),
+    prop: "contractTypeVal",
+  },
+  {
+    label: proxy.t("contract.code"),
+    prop: "code",
+  },
+  {
+    label: proxy.t("contract.buyCorporation"),
+    prop: "buyCorporationName",
+  },
+  {
+    label: proxy.t("contract.amount"),
+    prop: "currencyAmount",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 136 - 0
src/views/salesContract/priceSheet/index.vue

@@ -0,0 +1,136 @@
+<template>
+  <van-nav-bar :title="$t('priceSheet.name')" left-text="" left-arrow @click-left="onClickLeft" @click-right="onClickRight">
+    <template #right>{{ $t("common.add") }}</template>
+  </van-nav-bar>
+  <van-search v-model="req.keyword" :placeholder="$t('common.pleaseEnterKeywords')" @search="onRefresh" />
+  <van-pull-refresh v-model="loading" @refresh="onRefresh">
+    <div class="list">
+      <van-list v-model:loading="loading" :finished="finished" :finished-text="$t('common.noMore')" @load="getList" style="margin-bottom: 60px">
+        <commonList :data="listData" @onClick="toDtl" :config="listConfig"></commonList>
+      </van-list>
+    </div>
+  </van-pull-refresh>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import commonList from "@/components/common-list.vue";
+
+const proxy = getCurrentInstance().proxy;
+const onClickLeft = () => proxy.$router.push("/main/working");
+const onClickRight = () => {
+  proxy.$router.push({
+    path: "/main/processDtl",
+    query: {
+      flowKey: "sale_quotation_flow",
+    },
+  });
+};
+const req = ref({
+  pageNum: 1,
+  keyword: null,
+});
+const finished = ref(false);
+const onRefresh = () => {
+  req.value.pageNum = 1;
+  finished.value = false;
+  getList("refresh");
+};
+const loading = ref(false);
+const listData = ref([]);
+const status = ref([
+  {
+    label: "草稿",
+    value: 0,
+  },
+  {
+    label: "审批中",
+    value: 10,
+  },
+  {
+    label: "驳回",
+    value: 20,
+  },
+  {
+    label: "审批通过",
+    value: 30,
+  },
+  {
+    label: "作废",
+    value: 70,
+  },
+  {
+    label: "终止",
+    value: 99,
+  },
+]);
+const getList = (type) => {
+  loading.value = true;
+  proxy
+    .post("/saleQuotation/page", req.value)
+    .then((res) => {
+      if (res.data.rows && res.data.rows.length > 0) {
+        res.data.rows = res.data.rows.map((item) => {
+          let statusText = "";
+          if (item.status) {
+            let list = status.value.filter((itemStatus) => itemStatus.value == item.status);
+            if (list && list.length > 0) {
+              statusText = list[0].label;
+            }
+          }
+          return {
+            ...item,
+            currencyAmount: item.currency + " " + item.amount,
+            statusText: statusText,
+          };
+        });
+      }
+      listData.value = type === "refresh" ? res.data.rows : listData.value.concat(res.data.rows);
+      if (req.value.pageNum * 10 >= res.data.total) {
+        finished.value = true;
+      }
+      req.value.pageNum++;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+};
+const toDtl = (row) => {
+  // proxy.$router.push({
+  //   path: "/main/processDtl",
+  //   query: {
+  //     flowKey: "sale_quotation_flow",
+  //     id: row.flowInfoId,
+  //     processType: 20,
+  //   },
+  // });
+};
+const listConfig = ref([
+  {
+    label: proxy.t("priceSheet.sellCorporation"),
+    prop: "sellCorporationName",
+  },
+  {
+    label: proxy.t("priceSheet.code"),
+    prop: "code",
+  },
+  {
+    label: proxy.t("priceSheet.buyCorporation"),
+    prop: "buyCorporationName",
+  },
+  {
+    label: proxy.t("priceSheet.amount"),
+    prop: "currencyAmount",
+  },
+  {
+    label: proxy.t("priceSheet.status"),
+    prop: "statusText",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.list {
+  min-height: 70vh;
+}
+</style>

+ 2 - 1
src/views/working/iframWinfaster.vue

@@ -6,7 +6,7 @@
         @click-left="onClickLeft"
     ></van-nav-bar>
     <div class="iframWinfaster">
-        <iframe src="https://www.winfaster.cn/#/" frameborder="0"></iframe>
+        <iframe id="your-iframe-id"  src="http://139.9.102.170:10008/#/" frameborder="0"></iframe>
     </div>
 </template>
 <style lang="scss">
@@ -23,4 +23,5 @@
 import { ref, reactive, getCurrentInstance, toRaw } from "vue";
 const proxy = getCurrentInstance().proxy;
 const onClickLeft = () => history.back();
+
 </script>

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác