lxf il y a 1 an
Parent
commit
bb1423c2bb

+ 20 - 0
src/lang/cnLXF.js

@@ -309,6 +309,26 @@ export function cnLXF() {
       remarksMsg: "请输入付款条件",
       warranty: "质保期 (天)",
     },
+    invoice: {
+      name: "发票管理",
+      supplyName: "供应商",
+      supplyNameMsg: " 请选择供应商",
+      type: "发票类型",
+      typeMsg: "请选择发票类型",
+      money: "发票金额",
+      add: "添加发票",
+      edit: "编辑发票",
+      invoiceAmount: "开票金额",
+      invoiceAmountMsg: "请输入开票金额",
+      purchaseContract: "采购合同",
+      contractCode: "合同编号",
+      contractMoney: "合同金额",
+      receivedInvoice: "已收发票",
+      relatedAmount: "关联金额",
+      relatedAmountMsg: "请输入关联金额",
+      supplierNoContract: "该供应商暂无关联合同",
+      unequalAmounts: "开票金额不等于关联金额",
+    },
   };
   return cnLXF;
 }

+ 10 - 0
src/router/routerLXF.js

@@ -145,6 +145,16 @@ export function routesLXF() {
       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"),
+    },
   ];
   return routesLXF;
 }

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