Browse Source

拆开菜单
对账中心新加开票功能

Qukatie 3 days ago
parent
commit
99882a36ed

+ 16 - 0
src/api/iosBasicData/finstlbills.js

@@ -248,4 +248,20 @@ export const voucherRemove = (ids) => {
       ids,
     }
   })
+}
+//  生成发票单
+export const generateInvoice  = (data) => {
+  return request({
+    url: '/api/blade-los/finstlbills/generateInvoice ',
+    method: 'post',
+    data: data
+  })
+}
+// 撤销生成发票单
+export const revokeInvoice  = (data) => {
+  return request({
+    url: '/api/blade-los/finstlbills/revokeInvoice ',
+    method: 'post',
+    data: data
+  })
 }

+ 17 - 4
src/router/views/index.js

@@ -4224,16 +4224,29 @@ export default [{
   }]
 },
 {
-  path: '/iosBasicData/cashier/index',
+  path: '/iosBasicData/cashier/indexD',
   component: Layout,
   hidden: true,
   children: [{
-    path: '/iosBasicData/cashier/index',
-    name: '出纳管理',
+    path: '/iosBasicData/cashier/indexD',
+    name: '到账管理',
     meta: {
       keepAlive: true,
     },
-    component: () => import( /* webpackChunkName: "views" */ '@/views/iosBasicData/cashier/index')
+    component: () => import( /* webpackChunkName: "views" */ '@/views/iosBasicData/cashier/indexD')
+  }]
+},
+{
+  path: '/iosBasicData/cashier/indexC',
+  component: Layout,
+  hidden: true,
+  children: [{
+    path: '/iosBasicData/cashier/indexC',
+    name: '支付管理',
+    meta: {
+      keepAlive: true,
+    },
+    component: () => import( /* webpackChunkName: "views" */ '@/views/iosBasicData/cashier/indexC')
   }]
 },
 {

+ 6 - 40
src/views/iosBasicData/cashier/index.vue → src/views/iosBasicData/cashier/indexC.vue

@@ -3,10 +3,8 @@
     <basic-container v-show="isShow">
       <div style="margin-top: 10px">
         <el-tabs type="card" v-model="tabsValue" @tab-click="handleClick">
-          <el-tab-pane label="对账收费" name="对账收费"> </el-tab-pane>
           <el-tab-pane label="对账付费" name="对账付费"> </el-tab-pane>
           <el-tab-pane label="付费申请" name="付费申请"> </el-tab-pane>
-          <el-tab-pane label="销项发票" name="销项发票"> </el-tab-pane>
         </el-tabs>
       </div>
       <avue-crud
@@ -34,12 +32,12 @@
         @saveColumn="saveColumnTwo('crud', 'option', 'optionBack', 485)"
       >
         <template slot="menu" slot-scope="{ row }">
-          <el-button type="text" size="small" @click="allClick('出纳', row)">{{ row.dc == "D" ? "收款" : "支付" }}</el-button>
+          <el-button type="text" size="small" @click="allClick('出纳', row)">支付</el-button>
         </template>
         <template slot="menuLeft">
           <span style="font-size: 24px;font-weight: 600;">
             <el-button type="primary" size="small" @click="allClick('合并')" :disabled="selectionList.length == 0"
-              >合并{{ tabsValue == "对账收费" || tabsValue == "销项发票" ? "收费" : "支付" }}</el-button
+              >合并支付</el-button
             >
             <span style="color: #67C23A;margin-right: 10px;"> CNY:¥{{ amountSubSum.toFixed(2) }}元 </span>
             <span style="color: #E6A23C;"> USD:${{ amountSubUsdSum.toFixed(2) }}元 </span>
@@ -62,16 +60,12 @@
           <span class="pointerClick" @click="editfun(row)">{{ row.billNo }} </span>
         </template>
         <template slot="amountSub" slot-scope="{ row }">
-          <span v-if="tabsValue == '对账收费'">{{ row.amountDr }} </span>
           <span v-if="tabsValue == '对账付费'">{{ row.amountCr }} </span>
           <span v-if="tabsValue == '付费申请'">{{ row.amountSub }} </span>
-          <span v-if="tabsValue == '销项发票'">{{ row.amountSub }} </span>
         </template>
         <template slot="amountSubUsd" slot-scope="{ row }">
-          <span v-if="tabsValue == '对账收费'">{{ row.amountDrUsd }} </span>
           <span v-if="tabsValue == '对账付费'">{{ row.amountCrUsd }} </span>
           <span v-if="tabsValue == '付费申请'">{{ row.amountSubUsd }} </span>
-          <span v-if="tabsValue == '销项发票'">{{ row.amountSubUsd }} </span>
         </template>
         <template slot="cashierStatusSearch">
           <el-checkbox v-model="query.cashierStatus" :true-label="2" :false-label="1"></el-checkbox>
@@ -100,7 +94,7 @@ export default {
       selectionList: [], // 多选的数据
       isShow: true,
       editSave: false, // 详情是否禁用
-      tabsValue: "对账费", // tabs切换
+      tabsValue: "对账费", // tabs切换
       // 动画
       loading: false,
       // 分页
@@ -476,20 +470,13 @@ export default {
             }
           });
         }
-      } else if (this.tabsValue == "对账收费" || this.tabsValue == "对账付费") {
+      } else if (this.tabsValue == "对账付费") {
         this.$router.push({
           path: `/iosBasicData/finstlbills/index`,
           query: {
             id: row.id
           }
         });
-      } else if (this.tabsValue == "销项发票") {
-        this.$router.push({
-          path: `/iosBasicData/fininvoicesOutput/index`,
-          query: {
-            id: row.id
-          }
-        });
       }
     },
     // tabs 切换
@@ -535,15 +522,11 @@ export default {
       this.amountSubUsdSum = 0;
       if (list.length) {
         list.forEach(e => {
-          if (this.tabsValue == "对账收费") {
-            this.amountSubSum += Number(e.amountDr);
-            this.amountSubUsdSum += Number(e.amountDrUsd);
-          }
           if (this.tabsValue == "对账付费") {
             this.amountSubSum += Number(e.amountCr);
             this.amountSubUsdSum += Number(e.amountCrUsd);
           }
-          if (this.tabsValue == "付费申请" || this.tabsValue == "销项发票") {
+          if (this.tabsValue == "付费申请") {
             this.amountSubSum += Number(e.amountSub);
             this.amountSubUsdSum += Number(e.amountSubUsd);
           }
@@ -649,15 +632,7 @@ export default {
     async onLoad(page, params = {}) {
       this.loading = true;
       let res = {};
-      if (this.tabsValue == "对账收费") {
-        // 调用 付费申请数据
-        res = await finstlbillsList(page.currentPage, page.pageSize, {
-          ...Object.assign(params, this.query),
-          businessType: "CHK",
-          dc: "D",
-          cashierStatus: this.query.cashierStatus ? this.query.cashierStatus : 1
-        });
-      } else if (this.tabsValue == "对账付费") {
+    if (this.tabsValue == "对账付费") {
         // 调用 付费申请数据
         res = await finstlbillsList(page.currentPage, page.pageSize, {
           ...Object.assign(params, this.query),
@@ -672,15 +647,6 @@ export default {
           businessType: "FFSQ",
           cashierStatus: this.query.cashierStatus ? this.query.cashierStatus : 1
         });
-      } else if (this.tabsValue == "销项发票") {
-        // 应收应付 业务数据
-        res = await fininvoicesList(page.currentPage, page.pageSize, {
-          ...Object.assign(params, this.query),
-          type: "销项",
-          billNoFormat: "XXFP",
-          businessTypeCode: "XXFP",
-          cashierStatus: this.query.cashierStatus ? this.query.cashierStatus : 1
-        });
       }
       const data = res.data.data;
       this.page.total = data.total;

+ 703 - 0
src/views/iosBasicData/cashier/indexD.vue

@@ -0,0 +1,703 @@
+<template>
+  <div>
+    <basic-container v-show="isShow">
+      <div style="margin-top: 10px">
+        <el-tabs type="card" v-model="tabsValue" @tab-click="handleClick">
+          <el-tab-pane label="对账收费" name="对账收费"> </el-tab-pane>
+          <el-tab-pane label="销项发票" name="销项发票"> </el-tab-pane>
+        </el-tabs>
+      </div>
+      <avue-crud
+        :option="option"
+        :table-loading="loading"
+        :data="data"
+        :page.sync="page"
+        id="out-table"
+        :header-cell-class-name="headerClassName"
+        :before-open="beforeOpen"
+        v-model="form"
+        ref="crud"
+        :search.sync="query"
+        @row-update="rowUpdate"
+        @row-save="rowSave"
+        @row-del="rowDel"
+        @search-change="searchChange"
+        @search-reset="searchReset"
+        @selection-change="selectionChange"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+        @refresh-change="refreshChange"
+        @on-load="onLoad"
+        @resetColumn="resetColumnTwo('crud', 'option', 'optionBack', 485)"
+        @saveColumn="saveColumnTwo('crud', 'option', 'optionBack', 485)"
+      >
+        <template slot="menu" slot-scope="{ row }">
+          <el-button type="text" size="small" @click="allClick('出纳', row)">收款</el-button>
+        </template>
+        <template slot="menuLeft">
+          <span style="font-size: 24px;font-weight: 600;">
+            <el-button type="primary" size="small" @click="allClick('合并')" :disabled="selectionList.length == 0">合并收费</el-button>
+            <span style="color: #67C23A;margin-right: 10px;"> CNY:¥{{ amountSubSum.toFixed(2) }}元 </span>
+            <span style="color: #E6A23C;"> USD:${{ amountSubUsdSum.toFixed(2) }}元 </span>
+          </span>
+        </template>
+        <tempalte slot="feeCnNameSearch">
+          <dic-select
+            v-model="query.feeCnName"
+            placeholder="费用名称"
+            key="id"
+            label="cnName"
+            res="records"
+            url="/blade-los/bfees/list"
+            :filterable="true"
+            :remote="true"
+            dataName="cnName"
+          ></dic-select>
+        </tempalte>
+        <template slot="billNo" slot-scope="{ row }">
+          <span class="pointerClick" @click="editfun(row)">{{ row.billNo }} </span>
+        </template>
+        <template slot="amountSub" slot-scope="{ row }">
+          <span v-if="tabsValue == '对账收费'">{{ row.amountDr }} </span>
+          <span v-if="tabsValue == '销项发票'">{{ row.amountSub }} </span>
+        </template>
+        <template slot="amountSubUsd" slot-scope="{ row }">
+          <span v-if="tabsValue == '对账收费'">{{ row.amountDrUsd }} </span>
+          <span v-if="tabsValue == '销项发票'">{{ row.amountSubUsd }} </span>
+        </template>
+        <template slot="cashierStatusSearch">
+          <el-checkbox v-model="query.cashierStatus" :true-label="2" :false-label="1"></el-checkbox>
+        </template>
+      </avue-crud>
+    </basic-container>
+    <cashier-item ref="cashier"></cashier-item>
+  </div>
+</template>
+
+<script>
+import { finstlbillsList, finstlbillsRemove, revokeOffset } from "@/api/iosBasicData/finstlbills";
+import { getBcorpslistByType } from "@/api/iosBasicData/bcorps";
+import { bbusinesstypeList } from "@/api/iosBasicData/bbusinesstype";
+import { fininvoicesList } from "@/api/iosBasicData/fininvoices";
+import dicSelect from "@/components/dicSelect/main";
+import cashierItem from "./components/cashierItem.vue";
+export default {
+  components: { dicSelect, cashierItem },
+  data() {
+    return {
+      pageIds: [],
+      amountSubSum: 0,
+      amountSubUsdSum: 0,
+      datekey: Date.now(),
+      selectionList: [], // 多选的数据
+      isShow: true,
+      editSave: false, // 详情是否禁用
+      tabsValue: "对账收费", // tabs切换
+      // 动画
+      loading: false,
+      // 分页
+      page: {
+        pageSize: 10,
+        currentPage: 1,
+        total: 0
+      },
+      query: {}, // 检索条件
+      data: [], // 数据
+      form: {},
+      option: {},
+      optionBack: {
+        height: "auto",
+        calcHeight: 30,
+        tip: false,
+        searchShow: true,
+        searchMenuSpan: 24,
+        searchLabelWidth: "100",
+        border: true,
+        index: true,
+        selection: true,
+        dialogClickModal: false,
+        stripe: true,
+        addBtn: false,
+        viewBtn: false,
+        delBtn: false,
+        editBtn: false,
+        searchIcon: true,
+        searchIndex: 3,
+        menuWidth: "100",
+        column: [
+          {
+            label: "往来单位",
+            prop: "corpCnName",
+            search: true,
+            overHidden: true,
+            type: "select",
+            filterable: true,
+            remote: true,
+            dicUrl: "/api/blade-los/bcorps/listByType?cnName={{key}}",
+            dicData: [],
+            searchOrder: 1,
+            props: {
+              label: "cnName",
+              value: "cnName",
+              res: "data.records"
+            }
+          },
+          {
+            label: "MB/L NO",
+            prop: "mblno",
+            search: true,
+            searchOrder: 2,
+            overHidden: true
+          },
+          {
+            label: "JOB NO",
+            prop: "businessNo",
+            width: "120",
+            search: true,
+            searchOrder: 3,
+            overHidden: true
+          },
+          {
+            label: "HB/L NO",
+            prop: "hblno",
+            search: true,
+            searchOrder: 4,
+            overHidden: true
+          },
+          {
+            label: "ACCT NO",
+            prop: "accountNo",
+            width: "100",
+            search: true,
+            searchOrder: 5,
+            overHidden: true
+          },
+          {
+            label: "业务类型",
+            prop: "businessType",
+            hide: false,
+            overHidden: true,
+            type: "select",
+            dicData: [],
+            props: {
+              label: "cnName",
+              value: "code"
+            }
+          },
+          {
+            label: "来源类型",
+            prop: "srcType",
+            overHidden: true
+          },
+          {
+            label: "业务类型",
+            prop: "type",
+            hide: true,
+            overHidden: true
+          },
+          {
+            label: "单据编号",
+            prop: "billNo",
+            search: true,
+            overHidden: true
+          },
+          {
+            label: "来源单号",
+            prop: "requestNo",
+            search: true,
+            overHidden: true
+          },
+          {
+            label: "发票抬头",
+            prop: "invCorpCnName",
+            hide: true,
+            overHidden: true
+          },
+          {
+            label: "费用名称",
+            prop: "feeCnName",
+            search: true,
+            overHidden: true
+          },
+          {
+            label: "申请人",
+            prop: "createUserName",
+            overHidden: true
+          },
+          {
+            label: "结算日期",
+            prop: "billDate",
+            overHidden: true,
+            width: "150"
+          },
+
+          {
+            label: "结算日期起",
+            prop: "billDateStart",
+            search: true,
+            overHidden: true,
+            hide: true,
+            searchLabelWidth: "100",
+            type: "date",
+            format: "yyyy-MM-dd",
+            valueFormat: "yyyy-MM-dd HH:mm:ss"
+          },
+          {
+            label: "结算日期止",
+            prop: "billDateEnd",
+            search: true,
+            overHidden: true,
+            hide: true,
+            searchLabelWidth: "100",
+            type: "date",
+            format: "yyyy-MM-dd",
+            valueFormat: "yyyy-MM-dd HH:mm:ss"
+          },
+          {
+            label: "单据开始日期",
+            prop: "businessDateStart",
+            search: true,
+            overHidden: true,
+            hide: true,
+            searchLabelWidth: "100",
+            type: "date",
+            format: "yyyy-MM-dd",
+            valueFormat: "yyyy-MM-dd HH:mm:ss"
+          },
+          {
+            label: "单据结束日期",
+            prop: "businessDateEnd",
+            search: true,
+            overHidden: true,
+            hide: true,
+            searchLabelWidth: "100",
+            type: "date",
+            format: "yyyy-MM-dd",
+            valueFormat: "yyyy-MM-dd HH:mm:ss"
+          },
+          // {
+          //     label: "单据日期",
+          //     prop: "billDate",
+          //     search:true,
+          //     overHidden:true,
+          //     searchProp: 'billDateList',
+          //     type: "daterange",
+          //     searchRange: true,
+          //     searchDefaultTime: ["00:00:00", "23:59:59"],
+          //     format: "yyyy-MM-dd",
+          //     valueFormat: "yyyy-MM-dd HH:mm:ss"
+          // },
+          {
+            label: "提交日期",
+            prop: "auditDateFrom",
+            width: "140",
+            overHidden: true
+          },
+          {
+            label: "审核日期",
+            prop: "auditDateTo",
+            width: "140",
+            overHidden: true
+          },
+          {
+            label: "收/付",
+            prop: "dc",
+            width: "140",
+            // search: true,
+            type: "select",
+            dicData: [
+              {
+                id: "C",
+                name: "付款"
+              },
+              {
+                id: "D",
+                name: "收款"
+              }
+            ],
+            props: {
+              label: "name",
+              value: "id"
+            },
+            overHidden: true
+          },
+          {
+            label: "对账单号",
+            prop: "checkNo",
+            search: true,
+            width: "100",
+            searchOrder: 6,
+            overHidden: true
+          },
+          {
+            label: "船名",
+            prop: "vesselCnName",
+            search: true,
+            searchOrder: 7,
+            overHidden: true
+          },
+          {
+            label: "航次",
+            prop: "voyageNo",
+            search: true,
+            searchOrder: 8,
+            overHidden: true
+          },
+          {
+            label: "CNY",
+            prop: "amountSub",
+            overHidden: true
+          },
+          {
+            label: "USD",
+            prop: "amountSubUsd",
+            overHidden: true
+          },
+          {
+            label: "事由",
+            prop: "remarks",
+            overHidden: true
+          },
+          {
+            label: "已完成",
+            prop: "cashierStatus",
+            search: true,
+            hide: true,
+            overHidden: true
+          }
+        ]
+      },
+      saberUserInfo: {} // 当前登录人个人信息
+    };
+  },
+  async created() {
+    // 获取当前登录人个人信息
+    this.saberUserInfo = JSON.parse(localStorage.getItem("saber-userInfo")).content;
+    this.option = await this.getColumnData(this.getColumnName(485), this.optionBack);
+    if (this.$route.query.billId) {
+      // 从审批里查看跳进来的
+      this.editFun({ id: this.$route.query.billId });
+    }
+    this.$store.commit("JSZX_IN_DETAIL");
+    this.getBcorpslistByTypefun();
+    this.bbusinesstypeListfun();
+  },
+  activated() {
+    setTimeout(() => {
+      if (this.$route.query.billNo) {
+        this.isShow = false;
+        this.$nextTick(() => {
+          this.$refs.settlementDetailsRef.finstlbillsDetailfun(this.$route.query.billNo);
+        });
+        this.$store.commit("JSZX_IN_DETAIL");
+      }
+    }, 100);
+  },
+  methods: {
+    allClick(name, row) {
+      if (name == "出纳") {
+        this.$refs.cashier.openDialog(row);
+      }
+      if (name == "合并") {
+        let ids = [];
+        for (let item of this.selectionList) {
+          if (this.selectionList[0].corpId != item.corpId) {
+            return this.$message.error("请选择相同的往来单位");
+          }
+          ids.push(item.id);
+        }
+        let obj = {
+          id: ids.join(",")
+        };
+        this.$refs.cashier.openDialog(obj);
+      }
+    },
+    // 获取业务类型
+    bbusinesstypeListfun() {
+      bbusinesstypeList(1, 50).then(res => {
+        this.findObject(this.option.column, "businessType").dicData = res.data.data.records;
+      });
+    },
+    // 获取往来单位数据
+    getBcorpslistByTypefun() {
+      getBcorpslistByType(1, 10).then(res => {
+        this.findObject(this.option.column, "corpCnName").dicData = res.data.data.records;
+      });
+    },
+    revoke(row) {
+      this.$confirm("是否撤销对抵?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        let obj = {
+          ...row,
+          billDate: row.billDate ? row.billDate.slice(0, 10) + " 00:00:00" : null
+        };
+        revokeOffset(obj).then(res => {
+          this.$message.success("操作成功");
+          this.onLoad(this.page, this.search);
+        });
+      });
+    },
+    // 添加
+    addfun() {
+      this.pageIds = [];
+      this.isShow = false;
+      this.editSave = false;
+    },
+    toAddEdit() {
+      this.datekey = Date.now();
+      this.isShow = false;
+      this.editSave = false;
+    },
+    // 编辑
+    editfun(row) {
+      if (this.tabsValue == "对账收费") {
+        this.$router.push({
+          path: `/iosBasicData/finstlbills/index`,
+          query: {
+            id: row.id
+          }
+        });
+      } else if (this.tabsValue == "销项发票") {
+        this.$router.push({
+          path: `/iosBasicData/fininvoicesOutput/index`,
+          query: {
+            id: row.id
+          }
+        });
+      }
+    },
+    // tabs 切换
+    handleClick() {
+      this.amountSubSum = 0;
+      this.amountSubUsdSum = 0;
+      // this.query = {};
+      this.page.currentPage = 1;
+      this.query.cashierStatus = 1;
+      this.selectionList = [];
+      this.$set(this.query, "billNo", "");
+      this.$set(this.query, "corpCnName", "");
+      this.$set(this.query, "businessDateStart", "");
+      this.$set(this.query, "businessDateEnd", "");
+      this.onLoad(this.page);
+    },
+    // 刷新回调
+    refreshChange() {
+      console.log("刷新回调");
+      this.onLoad(this.page);
+    },
+    // 分页回调
+    currentChange(currentPage) {
+      console.log(currentPage, "分页回调");
+      this.page.currentPage = currentPage;
+    },
+    sizeChange(pageSize) {
+      console.log(pageSize, "分条回调");
+      this.page.pageSize = pageSize;
+    },
+    // 多选回调
+    selectionChange(list) {
+      this.amountSubSum = 0;
+      this.amountSubUsdSum = 0;
+      if (list.length) {
+        list.forEach(e => {
+          if (this.tabsValue == "对账收费") {
+            this.amountSubSum += Number(e.amountDr);
+            this.amountSubUsdSum += Number(e.amountDrUsd);
+          }
+          if (this.tabsValue == "销项发票") {
+            this.amountSubSum += Number(e.amountSub);
+            this.amountSubUsdSum += Number(e.amountSubUsd);
+          }
+        });
+      }
+      this.selectionList = list;
+    },
+    // 清空回调
+    searchReset() {
+      console.log("清空回调");
+      this.query = {};
+      this.query.cashierStatus = 1;
+      this.onLoad(this.page);
+    },
+    // 搜索回调
+    searchChange(params, done) {
+      console.log(params, "搜索回调");
+      this.query = params;
+      this.page.currentPage = 1;
+      this.onLoad(this.page, params);
+      done();
+    },
+    // 一键删除
+    handleDelete() {
+      if (this.selectionList.length === 0) {
+        this.$message.warning("请选择至少一条数据");
+        return;
+      }
+      // 判断是否可以编辑别人业务 true 就没有权限
+      if (this.ModifyOthersfun()) return;
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        let arrId = this.selectionList.map(item => {
+          return item.id;
+        });
+        finstlbillsRemove(arrId.join(",")).then(res => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        });
+      });
+    },
+    // 行删除回调
+    rowDel(row) {
+      console.log("行删除回调");
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        finstlbillsRemove(row.id).then(res => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        });
+      });
+    },
+    // 判断是否可以编辑别人业务
+    ModifyOthersfun() {
+      let sumArr = [];
+      const h = this.$createElement;
+      // 判断是否有权限
+      if (this.saberUserInfo.role_name.indexOf("允许修改他人业务") != -1) return false;
+      // 当前登录人和选择的创建人对比是不是一个人
+      for (let item of this.selectionList) {
+        if (this.saberUserInfo.user_id != item.createUser) {
+          sumArr.push(h("p", `你没有"允许修改他人业务"权限,请重新选择数据`));
+        }
+      }
+      if (sumArr.length != 0) {
+        this.$confirm("提示", {
+          message: h("div", sumArr),
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).catch(err => {});
+        return true;
+      }
+    },
+    // 新增弹窗确认回调
+    rowSave(row, done, loading) {
+      console.log("新增弹窗确认回调");
+    },
+    // 编辑弹窗确认回调
+    rowUpdate(row, index, done, loading) {
+      console.log("编辑弹窗确认回调");
+      done();
+      loading();
+    },
+    // 打开弹窗的回调
+    beforeOpen(done, type) {
+      console.log(type, "打开弹窗的回调");
+      done();
+    },
+    // 列表获取数据
+    async onLoad(page, params = {}) {
+      this.loading = true;
+      let res = {};
+      if (this.tabsValue == "对账收费") {
+        // 调用 付费申请数据
+        res = await finstlbillsList(page.currentPage, page.pageSize, {
+          ...Object.assign(params, this.query),
+          businessType: "CHK",
+          dc: "D",
+          cashierStatus: this.query.cashierStatus ? this.query.cashierStatus : 1
+        });
+      } else if (this.tabsValue == "销项发票") {
+        // 应收应付 业务数据
+        res = await fininvoicesList(page.currentPage, page.pageSize, {
+          ...Object.assign(params, this.query),
+          type: "销项",
+          billNoFormat: "XXFP",
+          businessTypeCode: "XXFP",
+          cashierStatus: this.query.cashierStatus ? this.query.cashierStatus : 1
+        });
+      }
+      const data = res.data.data;
+      this.page.total = data.total;
+      this.data = data.records;
+      this.loading = false;
+      this.$refs.crud.toggleSelection();
+      this.amountSubSum = 0;
+      this.amountSubUsdSum = 0;
+      this.$refs.crud.refreshTable();
+    },
+    //自定义列保存
+    async saveColumnTwo(ref, option, optionBack, code) {
+      /**
+       * 已定义全局方法,直接使用,saveColumnData保存列数据方法,参数传值(表格名称,当前表格的option数据)
+       * 已定义全局方法,直接使用,getColumnName方法用来获取枚举值,参数根据自己定义的code值获取中文名
+       * 一定要执行异步操作,要等接口成功返回,才能执行下一行代码
+       */
+      const inSave = await this.saveColumnData(this.getColumnName(code), this[option]);
+      if (inSave) {
+        this.$message.success("保存成功");
+        //关闭窗口
+        this.$refs[ref].$refs.dialogColumn.columnBox = false;
+      }
+    },
+    //自定义列重置
+    async resetColumnTwo(ref, option, optionBack, code) {
+      this[option] = this[optionBack];
+      const inSave = await this.delColumnData(this.getColumnName(code), this[optionBack]);
+      if (inSave) {
+        this.$message.success("重置成功");
+        this.$refs[ref].$refs.dialogColumn.columnBox = false;
+      }
+    },
+
+    // 更改表格颜色
+    headerClassName(tab) {
+      //颜色间隔
+      let back = "";
+      if (tab.columnIndex >= 0 && tab.column.level === 1) {
+        if (tab.columnIndex % 2 === 0) {
+          back = "back-one";
+        } else if (tab.columnIndex % 2 === 1) {
+          back = "back-two";
+        }
+      }
+      return back;
+    }
+  }
+};
+</script>
+
+<style scoped>
+::v-deep#out-table .back-one {
+  background: #ecf5ff !important;
+  text-align: center;
+}
+
+::v-deep#out-table .back-two {
+  background: #ecf5ff !important;
+  text-align: center;
+}
+
+::v-deep .el-col-md-8 {
+  width: 24.33333%;
+}
+
+.pointerClick {
+  cursor: pointer;
+  color: #1e9fff;
+}
+</style>

+ 1 - 1
src/views/iosBasicData/fininvoices/fininvoicesDetails.vue

@@ -641,7 +641,7 @@
               <!-- <el-checkbox v-model="appendType" :disabled="editSave" false-label="检索" true-label="追加">追加</el-checkbox> -->
               <el-button type="primary" size="small" :disabled="editSave" plain @click="retrievalfun(appendType)">提取费用 </el-button>
               <el-button size="small" :disabled="tableData.length > 0" @click="ResetFilter">重置条件 </el-button>
-              <el-button icon="el-icon-arrow-down" type="text" size="small" v-if="!showForm" @click="showForm = true">展</el-button>
+              <el-button icon="el-icon-arrow-down" type="text" size="small" v-if="!showForm" @click="showForm = true">展</el-button>
               <el-button icon="el-icon-arrow-up" type="text" size="small" v-if="showForm" @click="showForm = false">收缩</el-button>
             </div>
           </div>

+ 8 - 4
src/views/iosBasicData/fininvoicesApplyfor/assembly/fininvoiceitemdetail.vue

@@ -100,7 +100,7 @@
           <span v-else>{{ row.amountRate }}</span>
         </template>
       </el-table-column>
-      <el-table-column prop="remarks" label="税额" />
+      <el-table-column prop="amountTax" label="税额" />
       <el-table-column prop="remarks" label="备注">
         <template slot-scope="{ row }">
           <el-input v-if="row.edit" style="width: 100%;" v-model="row.remarks" size="mini" autocomplete="off" clearable placeholder="请输入税率">
@@ -110,9 +110,9 @@
       </el-table-column>
       <el-table-column fixed="right" label="操作" width="100">
         <template slot-scope="scope">
-          <el-button v-if="scope.row.edit" :disabled="editSave" type="text" size="small" @click="savefun(scope.row, scope.index)">保存</el-button>
-          <el-button v-else type="text" :disabled="editSave" size="small" @click="editfun(scope.row, scope.index)">编辑</el-button>
-          <el-button type="text" :disabled="editSave" size="small" @click="deletefun(scope.row, scope.index)">删除</el-button>
+          <el-button v-if="scope.row.edit" :disabled="editSave||disabled" type="text" size="small" @click="savefun(scope.row, scope.index)">保存</el-button>
+          <el-button v-else type="text" :disabled="editSave||disabled" size="small" @click="editfun(scope.row, scope.index)">编辑</el-button>
+          <el-button type="text" :disabled="editSave||disabled" size="small" @click="deletefun(scope.row, scope.index)">删除</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -138,6 +138,10 @@ export default {
     editSave: {
       type: Boolean,
       default: false
+    },
+    disabled: {
+      type: Boolean,
+      default: false
     }
   },
   data() {

+ 12 - 8
src/views/iosBasicData/fininvoicesApplyfor/fininvoicesDetails.vue

@@ -450,7 +450,7 @@
                       v-model="form.exrate"
                       size="small"
                       autocomplete="off"
-                      :disabled="editSave||InvoicingList.length"
+                      :disabled="editSave || InvoicingList.length"
                       clearable
                       placeholder="请输入发票汇率"
                     >
@@ -636,7 +636,7 @@
               </el-checkbox>
               <el-button type="primary" size="small" :disabled="statusType" plain @click="retrievalfun(appendType)">提取费用 </el-button>
               <el-button size="small" :disabled="tableData.length > 0" @click="ResetFilter">重置条件 </el-button>
-              <el-button icon="el-icon-arrow-down" type="text" size="small" v-if="!showForm" @click="showForm = true">展</el-button>
+              <el-button icon="el-icon-arrow-down" type="text" size="small" v-if="!showForm" @click="showForm = true">展</el-button>
               <el-button icon="el-icon-arrow-up" type="text" size="small" v-if="showForm" @click="showForm = false">收缩</el-button>
             </div>
           </div>
@@ -1257,7 +1257,7 @@ export default {
       row.amountTax = ((row.amount / (1 + Number(row.amountRate) / 100)) * (Number(row.amountRate) / 100)).toFixed(2);
       fininvoiceitemdetailSubmit(row).then(res => {
         this.$message.success("操作成功");
-        this.fininvoicesDetailfun(this.form.id);
+        this.fininvoicesDetailfun(this.form.id, "finstlbills");
       });
     },
     // 确认开票信息
@@ -1748,7 +1748,7 @@ export default {
         }
       });
       this.retrievePopupsType = false;
-      this.finstlbillslistAccBillV1fun('检索');
+      this.finstlbillslistAccBillV1fun("检索");
     },
     finstlbillslistAccBillByCorpfun() {
       let obj = {};
@@ -1775,7 +1775,7 @@ export default {
     retrievalfun(type) {
       this.activeName = "1";
       // 判断是否有对账单位
-      this.finstlbillslistAccBillV1fun('检索');
+      this.finstlbillslistAccBillV1fun("检索");
     },
     // 检索
     finstlbillslistAccBillV1fun(type) {
@@ -1869,7 +1869,7 @@ export default {
                 this.queryData.push(item);
               }
             }
-             if (this.queryData.length == 0&&type=='检索') {
+            if (this.queryData.length == 0 && type == "检索") {
               this.$message.warning("当前检索暂无数据!");
             }
           }
@@ -1934,7 +1934,7 @@ export default {
                 this.queryData.push(item);
               }
             }
-             if (this.queryData.length == 0&&type=='检索') {
+            if (this.queryData.length == 0 && type == "检索") {
               this.$message.warning("当前检索暂无数据!");
             }
           }
@@ -1954,7 +1954,11 @@ export default {
     },
     // 详情接口
     fininvoicesDetailfun(id, type) {
-      this.activeName = "2";
+      if (type == "finstlbills") {
+        this.activeName = "3";
+      } else {
+        this.activeName = "2";
+      }
       this.pageLoading = true;
       fininvoicesDetail(id)
         .then(res => {

+ 14 - 8
src/views/iosBasicData/fininvoicesOutput/fininvoicesDetails.vue

@@ -479,7 +479,7 @@
                         v-model="form.exrate"
                         size="small"
                         autocomplete="off"
-                        :disabled="editSave||InvoicingList.length"
+                        :disabled="editSave || InvoicingList.length"
                         clearable
                         placeholder="请输入发票汇率"
                       >
@@ -680,7 +680,7 @@
               <!-- <el-checkbox v-model="appendType" :disabled="editSave" false-label="检索" true-label="追加">追加</el-checkbox> -->
               <el-button type="primary" size="small" :disabled="editSave" plain @click="retrievalfun(appendType)">提取费用 </el-button>
               <el-button size="small" :disabled="tableData.length > 0" @click="ResetFilter">重置条件 </el-button>
-              <el-button icon="el-icon-arrow-down" type="text" size="small" v-if="!showForm" @click="showForm = true">展</el-button>
+              <el-button icon="el-icon-arrow-down" type="text" size="small" v-if="!showForm" @click="showForm = true">展</el-button>
               <el-button icon="el-icon-arrow-up" type="text" size="small" v-if="showForm" @click="showForm = false">收缩</el-button>
             </div>
           </div>
@@ -780,7 +780,7 @@
             </el-tab-pane>
             <el-tab-pane label="开票明细" name="3">
               <div style="margin-bottom: 10px;display: flex;">
-                <el-button size="small" :disabled="editSave" type="danger" @click="invoicingBatchDelete">一键删除</el-button>
+                <el-button size="small" :disabled="editSave||form.srcType=='对账'" type="danger" @click="invoicingBatchDelete">一键删除</el-button>
                 <span style="font-size: 18px;font-weight: 600;margin-left: 100px;">
                   <span style="color: #67C23A;"> CNY:¥{{ amountSubSum }}元 </span>
                 </span>
@@ -791,6 +791,7 @@
                 @handleSelectionChange="invoicingCheckboxChange"
                 @deletefun="invoiceDeletionfun"
                 @savefun="invoiceSavefun"
+                :disabled="form.srcType=='对账'" 
               >
               </fininvoiceitemdetail>
             </el-tab-pane>
@@ -807,7 +808,8 @@
                   autocomplete="off"
                   :disabled="true"
                   clearable
-                  placeholder="请输入业务编号">
+                  placeholder="请输入业务编号"
+                >
                 </el-input>
               </el-form-item>
             </el-col>
@@ -1914,10 +1916,14 @@ export default {
     },
     // 保存接口
     fininvoicesSubmitfun(obj, type) {
-      fininvoicesSubmit(obj).then(res => {
-        this.$message.success("操作成功");
-        this.fininvoicesDetailfun(res.data.data.id, type);
-      });
+      fininvoicesSubmit(obj)
+        .then(res => {
+          this.$message.success("操作成功");
+          this.fininvoicesDetailfun(res.data.data.id, type);
+        })
+        .catch(() => {
+          this.saveLoading = false;
+        });
     },
     // 详情接口
     fininvoicesDetailfun(id, type) {

+ 385 - 0
src/views/iosBasicData/finstlbills/assembly/fininvoiceitemdetail.vue

@@ -0,0 +1,385 @@
+<template>
+  <div>
+    <el-table
+      ref="tableRef"
+      :cell-style="{ padding: '0px', fontSize: '12px' }"
+      :header-cell-style="tableHeaderCellStyle"
+      :data="tableData"
+      border
+      style="width: 100%"
+      @selection-change="handleSelectionChange"
+      @row-click="rowClick"
+      :row-style="rowStyle"
+      :row-class-name="rowClassName"
+    >
+      <el-table-column fixed="left" type="selection" width="55" />
+      <el-table-column prop="index" label="行号" width="50px">
+        <template slot-scope="scope">
+          <span>{{ Number(scope.$index) + 1 }}</span>
+        </template>
+      </el-table-column>
+            <el-table-column prop="invoiceStatus" label="开票状态" width="70px" align="center">
+        <template slot-scope="{ row }">
+          <span v-if="row.invoiceStatus==0">未开</span>
+          <span v-if="row.invoiceStatus==1">已开</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="invoiceCompanyName" label="开票单位" width="120px" align="center">
+        <template slot-scope="{ row }">
+          <dic-select
+            v-if="row.edit"
+            v-model="row.invoiceCompanyName"
+            placeholder="开票单位"
+            label="invoiceHeader"
+            res="records"
+            :slotRight="true"
+            rightLabel="code"
+            :url="'/blade-los/corpsinvoiceheader/list?current=1&size=20&pid=' + form.corpId"
+            :filterable="true"
+            :remote="true"
+            dataName="cnName"
+            @selectChange="rowDicChange('invoiceCompanyName', $event, row)"
+          ></dic-select>
+          <span v-else>{{ row.invoiceCompanyName }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="serverName" label="项目名称" width="120px" align="center">
+        <template slot-scope="{ row }">
+          <search-query
+            v-if="row.edit"
+            :datalist="serverData"
+            :selectValue="row.serverName"
+            :clearable="true"
+            :buttonIf="false"
+            :filterable="true"
+            size="mini"
+            :forParameter="{ key: 'dictKey', label: 'dictValue', value: 'dictValue' }"
+            placeholder="请选择项目名称"
+            @corpChange="corpChange($event, 'serverName', row)"
+            @corpFocus="serverWorkDictsfun"
+          >
+          </search-query>
+          <span v-else>{{ row.serverName }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="typeno" label="规格型号" align="center">
+        <template slot-scope="{ row }">
+          <el-input v-if="row.edit" style="width: 100%;" v-model="row.typeno" size="mini" autocomplete="off" clearable placeholder="请输入规格型号">
+          </el-input>
+          <span v-else>{{ row.typeno }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="unit" label="单位" width="80px" align="center">
+        <template slot-scope="{ row }">
+          <search-query
+            v-if="row.edit"
+            :datalist="unitData"
+            :selectValue="row.unit"
+            :clearable="true"
+            :buttonIf="false"
+            :filterable="true"
+            size="mini"
+            :forParameter="{ key: 'dictKey', label: 'dictValue', value: 'dictValue' }"
+            placeholder="请选择单位"
+            @corpChange="corpChange($event, 'unit', row)"
+            @corpFocus="unitWorkDictsfun"
+          >
+          </search-query>
+          <span v-else>{{ row.unit }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="curCode" label="币别" width="100px" align="center">
+        <template slot-scope="{ row }">
+          <dic-select
+            v-if="row.edit"
+            v-model="row.curCode"
+            placeholder="币别"
+            key="id"
+            label="code"
+            :url="'/blade-los/bcurrency/getExrate?date=' + form.billDate + '00:00:00' + '&dc=' + form.dc"
+            :filterable="true"
+            @selectChange="rowDicChange('curCode', $event, row)"
+          ></dic-select>
+          <span v-else>{{ row.curCode }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="exrate" label="汇率" width="80px" align="center">
+        <tempalte slot-scope="{ row }">
+          <el-input-number
+            v-if="row.edit"
+            v-model="row.exrate"
+            :controls="false"
+            placeholder="请输入 汇率"
+            size="small"
+            style="width: 100%;"
+          ></el-input-number>
+          <span v-else>{{ row.exrate }}</span>
+        </tempalte>
+      </el-table-column>
+
+      <el-table-column prop="number" label="数量" width="60px" align="center"> </el-table-column>
+      <el-table-column prop="price" label="单价(含税)" align="center">
+        <template slot-scope="{ row }">
+          <el-input-number
+            v-if="row.edit"
+            style="width: 100%;"
+            v-model="row.price"
+            size="mini"
+            :controls="false"
+            clearable
+            placeholder="请输入单价"
+            @change="calculate(row)"
+          >
+          </el-input-number>
+          <span v-else>{{ row.price }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="amount" label="金额(含税)" align="center"> </el-table-column>
+      <el-table-column prop="amountRate" label="税率(%)" align="center">
+        <template slot-scope="{ row }">
+          <el-input-number
+            v-if="row.edit"
+            style="width: 100%;"
+            v-model="row.amountRate"
+            :controls="false"
+            size="mini"
+            clearable
+            @change="calculate(row)"
+            placeholder="请输入税率"
+          >
+          </el-input-number>
+          <span v-else>{{ row.amountRate }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="amountTax" label="税额" align="center" />
+      <el-table-column prop="remarks" label="备注" align="center">
+        <template slot-scope="{ row }">
+          <el-input v-if="row.edit" style="width: 100%;" v-model="row.remarks" size="mini" autocomplete="off" clearable placeholder="请输入税率">
+          </el-input>
+          <span v-else>{{ row.remarks }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column fixed="right" label="操作" width="100">
+        <template slot-scope="scope">
+          <el-button v-if="scope.row.edit" :disabled="scope.row.invoiceStatus==1" type="text" size="small" @click="savefun(scope.row, scope.index)">保存</el-button>
+          <el-button v-else type="text" :disabled="scope.row.invoiceStatus==1" size="small" @click="editfun(scope.row, scope.index)">编辑</el-button>
+          <el-button type="text" :disabled="scope.row.invoiceStatus==1" size="small" @click="deletefun(scope.row, scope.index)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import SearchQuery from "@/components/iosbasic-data/searchquery.vue";
+import { getWorkDicts } from "@/api/system/dictbiz";
+import { fininvoiceitemdetailSubmit } from "@/api/iosBasicData/fininvoices";
+import dicSelect from "@/components/dicSelect/main";
+
+export default {
+  components: { SearchQuery, dicSelect },
+  props: {
+    tableData: {
+      type: Array,
+      default: []
+    },
+    handleSelectionData: {
+      type: Array,
+      default: []
+    },
+    editSave: {
+      type: Boolean,
+      default: false
+    },
+    form: {
+      type: Object,
+      default: {}
+    },
+    disabled: {
+      type: Boolean,
+      default: false
+    },
+  },
+  data() {
+    return {
+      serverData: [], // 项目名称字典数据
+      unitData: [] // 单位字典数据
+    };
+  },
+  methods: {
+    calculate(row) {
+      row.amount = Number(Number(row.number ? row.number : 0) * Number(row.price ? row.price : 0)).toFixed(2);
+      // 税额 = 含税金额 × 税率 / (1 + 税率)
+      row.amountTax = Number(
+        (Number(row.amount ? row.amount : 0) * Number(Number(row.amountRate ? row.amountRate : 0) / 100)) /
+          Number(1 + Number(row.amountRate ? row.amountRate : 0) / 100)
+      ).toFixed(2);
+    },
+    rowDicChange(name, row, el) {
+      if (name == "invoiceCompanyName") {
+        if (row) {
+          el.invoiceCompanyId = row.id;
+        } else {
+          el.invoiceCompanyId = null;
+          el.invoiceCompanyName = null;
+        }
+      }
+      if (name == "curCode") {
+        if (row) {
+          el.exrate = row.exrate;
+        } else {
+          el.exrate = 0;
+        }
+      }
+    },
+    // 下拉回调
+    corpChange(value, name, row) {
+      this.$set(row, name, value);
+    },
+    // 保存
+    savefun(row) {
+      this.$emit("savefun", row);
+    },
+    // 编辑
+    editfun(row) {
+      this.$set(row, "edit", true);
+    },
+    // 删除
+    deletefun(row, index) {
+      this.$emit("deletefun", row.id, index);
+    },
+    // 项目名称字典数据
+    serverWorkDictsfun() {
+      getWorkDicts("Invoice_information_los").then(res => {
+        this.serverData = res.data.data;
+      });
+    },
+    // 获取单位字典数据
+    unitWorkDictsfun() {
+      getWorkDicts("Invoice_Items_unit_los").then(res => {
+        this.unitData = res.data.data;
+      });
+    },
+    // 表头样式
+    tableHeaderCellStyle({ row, column, rowIndex, columnIndex }) {
+      return "padding:4px 0px;fontSize:12px;color:#000;background:#ecf5ff";
+    },
+    // 多选选择的数据
+    handleSelectionChange(arr) {
+      this.$emit("handleSelectionChange", arr);
+    },
+    // 监听点击表格事件
+    rowClick(row, column, event) {
+      let refsElTable = this.$refs.tableRef; // 获取表格对象
+      if (this.CtrlDown) {
+        refsElTable.toggleRowSelection(row); // ctrl多选 如果点击两次同样会取消选中
+        return;
+      }
+      if (this.shiftOrAltDown && this.handleSelectionData.length > 0) {
+        // 通过rowIndex判断已选择的行中最上面和最下面的是哪行,再对比按住shift/alt点击的当前行得到新的最上面和最下面的行,把这两行中间的行进行循环选中。
+        let topAndBottom = this.getTopAndBottom(row, this.bottomSelectionRow, this.topSelectionRow);
+        refsElTable.clearSelection(); //先清空 不然会导致在这两行中间之外的行状态不变
+        for (let index = topAndBottom.top; index <= topAndBottom.bottom; index++) {
+          //选中两行之间的所有行
+          refsElTable.toggleRowSelection(this.tableData[index], true);
+        }
+      } else {
+        let findRow = this.handleSelectionData.find(c => c.rowIndex == row.rowIndex); //找出当前选中行
+        //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
+        if (findRow && this.handleSelectionData.length === 1) {
+          refsElTable.toggleRowSelection(row, false);
+          return;
+        }
+        // refsElTable.clearSelection(); // 清空之前选择的数据(如果放开,选择之前会变成单选)
+        refsElTable.toggleRowSelection(row); // 调用选中行方法
+      }
+    },
+    // 行的 style 的回调方法
+    rowStyle({ row, rowIndex }) {
+      // 直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
+      // object: 要添加或者修改属性的目标对象;prop: 要定义或修改属性的名称;descript: 是一个对象,里面是我们上述的对象属性的特性;
+      Object.defineProperty(row, "rowIndex", {
+        //给每一行添加不可枚举属性rowIndex来标识当前行
+        value: rowIndex, // 设置age的值,不设置的话默认为undefined
+        writable: true, // 表示属性的值true可以修改,false不可以被修改
+        enumerable: false // 设置为false表示不能通过 for-in 循环返回
+        // configurable: false, // configurable 设置为 false,意味着这个属性不能从对象上删除
+      });
+    },
+    keyDown(event) {
+      let key = event.keyCode;
+      if (key == 17) this.CtrlDown = true;
+      if (key == 16 || key == 18) this.shiftOrAltDown = true;
+    },
+    keyUp(event) {
+      let key = event.keyCode;
+      if (key == 17) this.CtrlDown = false;
+      if (key == 16 || key == 18) this.shiftOrAltDown = false;
+    },
+    // 文章说明 https://www.jianshu.com/p/48f2c522d2a2
+    getTopAndBottom(row, bottom, top) {
+      let n = row.rowIndex,
+        mx = bottom.rowIndex,
+        mi = top.rowIndex;
+      if (n > mx) {
+        return {
+          top: mi,
+          bottom: n
+        };
+      } else if (n < mx && n > mi) {
+        return {
+          top: mi,
+          bottom: n
+        };
+      } else if (n < mi) {
+        return {
+          top: n,
+          bottom: mx
+        };
+      } else if (n == mi || n == mx) {
+        return {
+          top: mi,
+          bottom: mx
+        };
+      }
+    },
+    // 给选中行加上current-row这个class类,所以要使用row-class-name这个属性(其实给每一行添加rowIndex也可以用这个属性),
+    // 判断方式也是通过判断rowIndex对比
+    rowClassName({ row, rowIndex }) {
+      let rowName = "",
+        findRow = this.handleSelectionData.find(c => c.rowIndex === row.rowIndex);
+      if (findRow) {
+        rowName = "current-row "; // elementUI 默认高亮行的class类 不用再样式了^-^,也可通过css覆盖改变背景颜色
+      }
+      return rowName; //也可以再加上其他类名 如果有需求的话
+    }
+  },
+  mounted() {
+    // 按住ctrl实现多选 设置监听keydown事件,以及keyup事件,
+    addEventListener("keydown", this.keyDown, false);
+    addEventListener("keyup", this.keyUp, false);
+  },
+  beforeDestroy() {
+    //解绑
+    removeEventListener("keydown", this.keyDown);
+    removeEventListener("keyup", this.keyUp);
+  },
+  computed: {
+    //实时得到最上行和最下行
+    bottomSelectionRow() {
+      if (this.handleSelectionData.length == 0) return null;
+      return this.handleSelectionData.reduce((start, end) => {
+        return start.rowIndex > end.rowIndex ? start : end;
+      });
+    },
+    topSelectionRow() {
+      if (this.handleSelectionData.length == 0) return null;
+      return this.handleSelectionData.reduce((start, end) => {
+        return start.rowIndex < end.rowIndex ? start : end;
+      });
+    }
+  }
+};
+</script>
+
+<style scoped></style>

+ 247 - 6
src/views/iosBasicData/finstlbills/finstlbillsDetails.vue

@@ -699,6 +699,39 @@
               </template>
             </finstlbillsitems>
           </el-tab-pane>
+          <el-tab-pane label="开票明细" name="3">
+            <div style="margin-bottom: 10px;display: flex;">
+              <el-button style="margin-left: 10px" :disabled="!form.id" size="small" type="primary" @click="addRow">新增</el-button>
+              <el-button
+                style="margin-left: 10px"
+                :disabled="!form.id || invoicingCheckboxData.length == 0"
+                size="small"
+                type="success"
+                @click="invoicingfun"
+                >生成发票单</el-button
+              >
+              <el-button
+                style="margin-left: 10px"
+                :disabled="!form.id || invoicingCheckboxData.length == 0"
+                size="small"
+                type="danger"
+                @click="invoicingRevokefun"
+                >撤销生成发票单</el-button
+              >
+              <el-button :disabled="!form.id || invoicingCheckboxData.length == 0" size="small" type="danger" @click="invoicingBatchDelete"
+                >一键删除</el-button
+              >
+            </div>
+            <fininvoiceitemdetail
+              :form="form"
+              :tableData="InvoicingList"
+              :handleSelectionData="invoicingCheckboxData"
+              @handleSelectionChange="invoicingCheckboxChange"
+              @deletefun="invoiceDeletionfun"
+              @savefun="invoiceSavefun"
+            >
+            </fininvoiceitemdetail>
+          </el-tab-pane>
         </el-tabs>
       </el-card>
     </div>
@@ -755,6 +788,7 @@
 </template>
 
 <script>
+import fininvoiceitemdetail from "@/views/iosBasicData/finstlbills/assembly/fininvoiceitemdetail.vue";
 import SearchQuery from "@/components/iosbasic-data/searchquery.vue";
 import { getWorkDicts } from "@/api/system/dictbiz";
 import { getRateList } from "@/api/iosBasicData/rateManagement";
@@ -775,7 +809,9 @@ import {
   finstlbillsConfirmInvoicing,
   finstlbillsRevokeInvoicing,
   batchConfirmReconciliation,
-  batchRevokeReconciliation
+  batchRevokeReconciliation,
+  generateInvoice,
+  revokeInvoice
 } from "@/api/iosBasicData/finstlbills";
 import expand from "@/components/basic-container/expand.vue";
 import queryfinstlbillsitems from "@/views/iosBasicData/finstlbills/assembly/finstlbillsitems.vue";
@@ -788,8 +824,20 @@ import { getList as getreportsList, reportsGetReportData } from "@/api/iosBasicD
 import dicSelect from "@/components/dicSelect/main";
 import cashierItem from "./assembly/cashierItem.vue";
 import { getListAllDetail } from "@/api/iosBasicData/cashier.js";
+import { fininvoiceitemdetailRemove, fininvoiceitemdetailSubmit } from "@/api/iosBasicData/fininvoices";
 export default {
-  components: { reportContainer, reportformsList, reports, SearchQuery, expand, finstlbillsitems, dicSelect, queryfinstlbillsitems, cashierItem },
+  components: {
+    reportContainer,
+    reportformsList,
+    reports,
+    SearchQuery,
+    expand,
+    finstlbillsitems,
+    dicSelect,
+    queryfinstlbillsitems,
+    cashierItem,
+    fininvoiceitemdetail
+  },
   props: {
     // 编辑还是保存
     editSave: {
@@ -803,6 +851,8 @@ export default {
   },
   data() {
     return {
+      InvoicingList: [], // 开票明细数据
+      invoicingCheckboxData: [],
       amountDSubSum: 0,
       amountDSubUsdSum: 0,
       amountCSubSum: 0,
@@ -915,6 +965,15 @@ export default {
     this.invoiceWorkDictsfun(); // 获取 发票的数据
   },
   methods: {
+    addRow() {
+      this.InvoicingList.push({
+        pid: this.form.id,
+        number: 1,
+        price: 0,
+        amountRate: 0,
+        edit: true
+      });
+    },
     lastPage() {
       if (this.pageIds.length) {
         const index = this.pageIds.indexOf(this.form.id);
@@ -1072,6 +1131,165 @@ export default {
         this.$set(this.form, name, value);
       }
     },
+    invoicingCheckboxChange(arr) {
+      this.invoicingCheckboxData = arr;
+    },
+    // 开票明细单个删除
+    invoiceDeletionfun(id, index) {
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        if (id) {
+          fininvoiceitemdetailRemove(id).then(res => {
+            this.$message.success("操作成功");
+            this.InvoicingList.splice(index, 1);
+          });
+        }
+      });
+    },
+    // 开票明细编辑完成保存
+    invoiceSavefun(row) {
+      if (!row.invoiceCompanyId) {
+        return this.$message.error("开票单位不能为空");
+      }
+      if (!row.curCode) {
+        return this.$message.error("币别不能为空");
+      }
+      if (!Number(row.exrate)) {
+        return this.$message.error("汇率不能为空或0");
+      }
+      if (Number(row.price ? row.price : 0) <= 0) {
+        return this.$message.error("单价不能为非正数");
+      }
+      fininvoiceitemdetailSubmit(row).then(res => {
+        this.$message.success("操作成功");
+        this.finstlbillsDetailfun(this.form.id, "finstlbills");
+      });
+    },
+    // 开票一键删除
+    invoicingBatchDelete() {
+      if (this.invoicingCheckboxData.length == 0) {
+        return this.$message.warning("请选择要删除的数据");
+      }
+      for (let item of this.invoicingCheckboxData) {
+        if (item.invoiceStatus == 1) {
+          return this.$message.error("请选择未开开票明细");
+        }
+      }
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        // 获取有id 的数据
+        const itemsWithId = this.invoicingCheckboxData.filter(item => item.hasOwnProperty("id"));
+        let arrIds = itemsWithId.map(item => item.id); // 获取id 数据
+        // 把选中的删除掉
+        this.invoicingCheckboxData.forEach(item => {
+          for (let index in this.InvoicingList) {
+            if (item.id == this.InvoicingList[index].id) {
+              this.InvoicingList.splice(Number(index), 1);
+            }
+          }
+        });
+        // 有id 的处理
+        if (itemsWithId.length != 0) {
+          fininvoiceitemdetailRemove(arrIds.join(",")).then(res => {
+            this.$message.success("操作成功");
+          });
+        }
+      });
+    },
+    // 确认开票信息
+    invoicingfun() {
+      if (this.invoicingCheckboxData.length == 0) {
+        this.$message.error("请选择数据");
+        return;
+      }
+      for (let item of this.invoicingCheckboxData) {
+        if (!item.id) {
+          return this.$message.error("请保存开票明细");
+        }
+        if (item.invoiceStatus == 1) {
+          return this.$message.error("请选择未开开票明细");
+        }
+      }
+      this.form.billNoFormat = "HYDZ";
+      this.form.businessTypeCode = "HYDZ";
+      this.form.businessType = "CHK"; // 对账单
+      this.form.accountDateFrom = this.form.accountDateFrom ? this.form.accountDateFrom.slice(0, 10) + " 00:00:00" : null; // 财务开始日期
+      this.form.accountDateTo = this.form.accountDateTo ? this.form.accountDateTo.slice(0, 10) + " 00:00:00" : null; // 财务开始日期
+      this.form.auditDateFrom = this.form.auditDateFrom ? this.form.auditDateFrom.slice(0, 10) + " 00:00:00" : null;
+      this.form.auditDateTo = this.form.auditDateTo ? this.form.auditDateTo.slice(0, 10) + " 00:00:00" : null;
+      this.form.businessDateEnd = this.form.businessDateEnd ? this.form.businessDateEnd.slice(0, 10) + " 00:00:00" : null;
+      this.form.businessDateStart = this.form.businessDateStart ? this.form.businessDateStart.slice(0, 10) + " 00:00:00" : null;
+      this.form.billDate = this.form.billDate ? this.form.billDate.slice(0, 10) + " 00:00:00" : null;
+      // 保留id
+      this.form.finStlBillsItemsList = this.tableData;
+      let obj = {
+        ...this.form,
+        finInvoiceItemDetailList: this.invoicingCheckboxData
+      };
+      this.$confirm("是否生成发票单?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        // 开票项目
+        generateInvoice(obj).then(res => {
+          this.$message.warning("操作成功");
+          this.finstlbillsDetailfun(this.form.id, "finstlbills");
+        });
+      });
+    },
+    // 撤销开票信息
+    invoicingRevokefun() {
+      if (this.invoicingCheckboxData.length == 0) {
+        this.$message.warning("请选择数据");
+        return;
+      }
+      if (this.invoicingCheckboxData.length == 0) {
+        this.$message.error("请选择数据");
+        return;
+      }
+      for (let item of this.invoicingCheckboxData) {
+        if (!item.id) {
+          return this.$message.error("请保存开票明细");
+        }
+        if (item.invoiceStatus == 0) {
+          return this.$message.error("请选择已开开票明细");
+        }
+      }
+      this.form.billNoFormat = "HYDZ";
+      this.form.businessTypeCode = "HYDZ";
+      this.form.businessType = "CHK"; // 对账单
+      this.form.accountDateFrom = this.form.accountDateFrom ? this.form.accountDateFrom.slice(0, 10) + " 00:00:00" : null; // 财务开始日期
+      this.form.accountDateTo = this.form.accountDateTo ? this.form.accountDateTo.slice(0, 10) + " 00:00:00" : null; // 财务开始日期
+      this.form.auditDateFrom = this.form.auditDateFrom ? this.form.auditDateFrom.slice(0, 10) + " 00:00:00" : null;
+      this.form.auditDateTo = this.form.auditDateTo ? this.form.auditDateTo.slice(0, 10) + " 00:00:00" : null;
+      this.form.businessDateEnd = this.form.businessDateEnd ? this.form.businessDateEnd.slice(0, 10) + " 00:00:00" : null;
+      this.form.businessDateStart = this.form.businessDateStart ? this.form.businessDateStart.slice(0, 10) + " 00:00:00" : null;
+      this.form.billDate = this.form.billDate ? this.form.billDate.slice(0, 10) + " 00:00:00" : null;
+      // 保留id
+      this.form.finStlBillsItemsList = this.tableData;
+      let obj = {
+        ...this.form,
+        finInvoiceItemDetailList: this.invoicingCheckboxData
+      };
+      this.$confirm("是否撤销生成发票单?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        // 撤销开票项目
+        revokeInvoice(this.form).then(res => {
+          this.$message.warning("操作成功");
+          this.finstlbillsDetailfun(this.form.id, "finstlbills");
+        });
+      });
+    },
     // 编辑
     editHandle() {
       if (this.form.status != 3) {
@@ -1131,6 +1349,21 @@ export default {
         }
         return item;
       });
+      for (let row of this.InvoicingList) {
+        if (!row.invoiceCompanyId) {
+          return this.$message.error("开票单位不能为空");
+        }
+        if (!row.curCode) {
+          return this.$message.error("币别不能为空");
+        }
+        if (!Number(row.exrate)) {
+          return this.$message.error("汇率不能为空或0");
+        }
+        if (Number(row.price ? row.price : 0) <= 0) {
+          return this.$message.error("单价不能为非正数");
+        }
+      }
+      this.form.finInvoiceItemDetailList = this.InvoicingList;
       this.saveLoading = true; // 加载动画
       this.pageLoading = true;
       // 判断是单独点击保存还是点击确认对账
@@ -1251,7 +1484,11 @@ export default {
     },
     // 详情接口
     finstlbillsDetailfun(id, type) {
-      this.activeName = "2";
+      if (type == "finstlbills") {
+        this.activeName = "3";
+      } else {
+        this.activeName = "2";
+      }
       this.pageLoading = true;
       finstlbillsDetail(id)
         .then(res => {
@@ -1293,6 +1530,10 @@ export default {
             this.$set(item, "costDate", []);
             return item;
           });
+          this.InvoicingList = this.form.finInvoiceItemDetailList.map(item => {
+            item.edit = false;
+            return item;
+          });
           this.form.isSignfor = this.form.isSignfor + "";
           this.form.isApproved = this.form.isApproved + "";
           this.form.isCleared = this.form.isCleared + "";
@@ -1328,7 +1569,7 @@ export default {
       this.$set(this.form, "corpEnName", row.enName);
       this.$set(this.form, "corpArgreementNo", row.enName);
       this.retrievePopupsType = false;
-      this.finstlbillslistAccBillV1fun('检索');
+      this.finstlbillslistAccBillV1fun("检索");
     },
     // 检索
     retrievalfun() {
@@ -1342,7 +1583,7 @@ export default {
           return this.$message.warning("请填写对账单位");
         }
         console.log("原来的接口");
-        this.finstlbillslistAccBillV1fun('检索');
+        this.finstlbillslistAccBillV1fun("检索");
       }
     },
     // 检索出的弹窗
@@ -1455,7 +1696,7 @@ export default {
             this.queryData.push(item);
           }
         }
-        if (this.queryData.length == 0&&type=='检索') {
+        if (this.queryData.length == 0 && type == "检索") {
           this.$message.warning("当前检索暂无数据!");
         }
       });