lizhenhao 2 年 前
コミット
eb62132b55

+ 7 - 2
src/views/common/UpLoadComponent.vue

@@ -86,7 +86,7 @@
         directory: 'public',
         maxValue: 300,
         tableKey: '',
-        fileLoading: false
+        fileLoading: true
       }
     },
     watch: {
@@ -133,9 +133,14 @@
             item.size = data.data.size
             this.dataList.push(item)
             this.dataListNew.push(item)
+            if (this.dataList.length === fileList.length) {
+              this.fileLoading = true
+            }
           })
         }
-        this.fileLoading = true
+        if (this.commonJS.isEmpty(fileList)) {
+          this.fileLoading = true
+        }
         // this.dataList = JSON.parse(JSON.stringify(fileList))
         // this.dataListNew = JSON.parse(JSON.stringify(fileList))
       },

+ 284 - 139
src/views/modules/finance/invoice/InvoiceForm.vue

@@ -278,38 +278,39 @@
               <el-input :disabled="true" v-model="inputForm.billingPeople" placeholder="请选择开票人" clearable></el-input>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item label="开票时间" prop="billingDate"
-                          :rules="[
+          <el-form size="middle" :model="inputForm" ref="inputForm" v-loading="loading" :class="method==='view'?'readonly':''"  :disabled="detailFlag!==true"
+                   label-width="160px" @submit.native.prevent>
+            <el-col :span="12">
+              <el-form-item label="开票时间" prop="billingDate"
+                            :rules="[
                  ]">
-              <el-date-picker
-                :disabled="true"
-                v-model="inputForm.billingDate"
-                type="date"
-                value-format="yyyy-MM-dd"
-                placeholder="选择开票时间"
-                style="width:100%"
-                placement="bottom-start"
-                clearable>
-              </el-date-picker>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="领票时间" prop="collectDate"
-                          :rules="[
+                <el-date-picker
+                  v-model="inputForm.billingDate"
+                  type="date"
+                  value-format="yyyy-MM-dd"
+                  placeholder="选择开票时间"
+                  style="width:100%"
+                  placement="bottom-start"
+                  clearable>
+                </el-date-picker>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="领票时间" prop="collectDate"
+                            :rules="[
                  ]">
-              <el-date-picker
-                :disabled="true"
-                v-model="inputForm.collectDate"
-                type="date"
-                value-format="yyyy-MM-dd"
-                placeholder="选择领票时间"
-                style="width:100%"
-                placement="bottom-start"
-                clearable>
-              </el-date-picker>
-            </el-form-item>
-          </el-col>
+                <el-date-picker
+                  v-model="inputForm.collectDate"
+                  type="date"
+                  value-format="yyyy-MM-dd"
+                  placeholder="选择领票时间"
+                  style="width:100%"
+                  placement="bottom-start"
+                  clearable>
+                </el-date-picker>
+              </el-form-item>
+            </el-col>
+          </el-form>
           <el-col :span="12">
             <el-form-item label="实际开票人" prop="billingPeopleReal"
                           :rules="[
@@ -374,112 +375,144 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-divider content-position="left"><i class="el-icon-document"></i>
-          发票明细
-          <el-button style="margin-left: 20px" type="primary" :disabled="method==='view'" size="mini" @click="insertEvent('detail')" plain>
-            新增
-          </el-button>
-        </el-divider>
-        <el-row  :gutter="15">
-          <vxe-table
-            border
-            show-overflow
-            show-footer
-            ref="detailTable"
-            class="vxe-table-element"
-            :data="inputForm.financeInvoiceDetailDTOList"
-            style="margin-left: 5em"
-            @cell-click=""
-            @edit-closed=""
-            highlight-current-row
-            :edit-config="{trigger: 'click', mode: 'cell', showStatus: true, autoClear: true}"
-          >
-            <vxe-table-column field="code" title="发票代码" :edit-render="{}">
-              <template v-slot:edit="scope">
-                <el-input v-model="scope.row.code" placeholder="请填写发票代码"/>
-              </template>
-            </vxe-table-column>
-            <vxe-table-column field="number" title="发票号" :edit-render="{}">
-              <template v-slot:edit="scope">
-                <el-input-number
-                  @blur="checkNumber(scope.row,scope.$rowIndex)"
-                  v-model="scope.row.number"
-                  controls-position="right"
-                  :controls="false"
-                  style="width:100%;"
-                  :precision="0"
-                  placeholder="请填写发票号"
-                  :step="1"
-                  :min="0"
-                  clearable>
-                </el-input-number>
-              </template>
-            </vxe-table-column>
-            <vxe-table-column field="account" title="开票金额(元)" :edit-render="{}">
-              <template v-slot:edit="scope">
-                <el-input-number
-                  @blur="checkAccount(scope.row,scope.$rowIndex)"
-                  v-model="scope.row.account"
-                  controls-position="right"
-                  :controls="false"
-                  style="width:100%;"
-                  :max="999999999999999"
-                  :precision="2"
-                  placeholder="请填写开票金额"
-                  :step="0.01"
-                  :min="0"
-                  clearable>
-                </el-input-number>
-              </template>
-            </vxe-table-column>
-            <vxe-table-column field="rate" title="税率(%)" :edit-render="{}">
-              <template v-slot:edit="scope">
-                <el-input-number
-                  @blur="checkRate(scope.row, scope.$rowIndex)"
-                  v-model="scope.row.rate"
-                  controls-position="right"
-                  :controls="false"
-                  style="width:100%;"
-                  :precision="2"
-                  placeholder="请填写税率"
-                  :step="0.01"
-                  :min="0"
-                  clearable>
-                </el-input-number>
-              </template>
-            </vxe-table-column>
-            <vxe-table-column field="amount" title="金额" :edit-render="{}">
-              <template v-slot:edit="scope">
-                <el-input :readonly="true" v-model="scope.row.amount" placeholder="请填写金额"/>
-              </template>
-            </vxe-table-column>
-            <vxe-table-column field="tax" title="税额" :edit-render="{}">
-              <template v-slot:edit="scope">
-                <el-input :readonly="true" v-model="scope.row.tax" placeholder="请填写税额"/>
-              </template>
-            </vxe-table-column>
-            <vxe-table-column field="allAmount" title="累计登记金额" :edit-render="{}">
-              <template v-slot:edit="scope">
-                <el-input-number
-                  v-model="scope.row.allAmount"
-                  controls-position="right"
-                  :controls="false"
-                  style="width:100%;"
-                  :precision="2"
-                  placeholder="请填写累计登记金额"
-                  :step="0.01"
-                  :min="0"
-                  clearable>
-                </el-input-number>
-              </template>
-            </vxe-table-column>
-            <vxe-table-column title="操作" width="100">
-              <template v-slot="scope">
-                <el-button size="mini" type="danger" @click="removeEvent(scope.row,scope.$rowIndex,'detail')">删除</el-button>
-              </template>
-            </vxe-table-column>
-          </vxe-table>
-        </el-row>
+        <el-form :disabled="detailFlag!==true">
+          <el-divider content-position="left"><i class="el-icon-document"></i>
+            发票明细
+            <el-button style="margin-left: 20px" type="primary" :disabled="detailFlag!==true" size="mini" @click="insertEvent('detail')" plain>
+              新增
+            </el-button>
+            <el-popover
+              placement="top"
+              width="400"
+              v-model="importVisible">
+              <p>请先下载模板,然后再进行导入操作</p>
+              <el-row :gutter="1">
+                <el-col :span="6">
+                  <el-button :disabled="detailFlag!==true" type="success" size="small" @click="downloadTpl">下载模板</el-button>
+                </el-col>
+                <el-col :span="6">
+                  <el-upload
+                    action=""
+                    :auto-upload="false"
+                    :on-change="beforeUploadDetail"
+                    :show-file-list="false">
+                    <el-button :disabled="detailFlag!==true" size="small" type="primary">导入全部</el-button>
+                  </el-upload>
+                </el-col>
+                <el-col :span="6">
+                  <el-upload
+                    action=""
+                    :auto-upload="false"
+                    :on-change="beforeUploadDetailCode"
+                    :show-file-list="false">
+                    <el-button :disabled="detailFlag!==true" size="small" type="primary" >仅导入当前纳税人识别号</el-button>
+                  </el-upload>
+                </el-col>
+              </el-row>
+              <div style="text-align: right; margin-top: 10px;margin-right: 10px;">
+                <el-button size="mini" :disabled="detailFlag!==true" type="default" @click="importVisible = false" plain>取消</el-button>
+                <!--            <el-button type="primary" size="mini" @click="importVisible = false">确定</el-button>-->
+              </div>
+              <el-button style="margin-left: 20px" slot="reference" :disabled="detailFlag!==true" type="warning" size="mini" plain>导入</el-button>
+            </el-popover>
+          </el-divider>
+          <el-row  :gutter="15">
+            <vxe-table
+              border
+              show-overflow
+              show-footer
+              ref="detailTable"
+              class="vxe-table-element"
+              :data="inputForm.financeInvoiceDetailDTOList"
+              style="margin-left: 5em"
+              @cell-click=""
+              @edit-closed=""
+              highlight-current-row
+              :edit-config="{trigger: 'click', mode: 'cell', showStatus: true, autoClear: true}"
+            >
+              <vxe-table-column field="code" title="发票代码" :edit-render="{}">
+                <template v-slot:edit="scope">
+                  <el-input v-model="scope.row.code" placeholder="请填写发票代码"/>
+                </template>
+              </vxe-table-column>
+              <vxe-table-column field="number" title="发票号" :edit-render="{}">
+                <template v-slot:edit="scope">
+                  <el-input
+                    oninput ="value=value.replace(/\D|^/g,'')"
+                    placeholder="请填写发票号"
+                    maxlength="8"
+                    @blur="checkNumber(scope.row,scope.$rowIndex)"
+                    v-model="scope.row.number"
+                    clearable>
+                  </el-input>
+                </template>
+              </vxe-table-column>
+              <vxe-table-column field="account" title="开票金额(元)" :edit-render="{}">
+                <template v-slot:edit="scope">
+                  <el-input-number
+                    @blur="checkAccount(scope.row,scope.$rowIndex)"
+                    v-model="scope.row.account"
+                    controls-position="right"
+                    :controls="false"
+                    style="width:100%;"
+                    :max="999999999999999"
+                    :precision="2"
+                    placeholder="请填写开票金额"
+                    :step="0.01"
+                    :min="0"
+                    clearable>
+                  </el-input-number>
+                </template>
+              </vxe-table-column>
+              <vxe-table-column field="rate" title="税率(%)" :edit-render="{}">
+                <template v-slot:edit="scope">
+                  <el-input-number
+                    @blur="checkRate(scope.row, scope.$rowIndex)"
+                    v-model="scope.row.rate"
+                    controls-position="right"
+                    :controls="false"
+                    style="width:100%;"
+                    :precision="2"
+                    placeholder="请填写税率"
+                    :step="0.01"
+                    :min="0"
+                    clearable>
+                  </el-input-number>
+                </template>
+              </vxe-table-column>
+              <vxe-table-column field="amount" title="金额" :edit-render="{}">
+                <template v-slot:edit="scope">
+                  <el-input :readonly="true" v-model="scope.row.amount" placeholder="请填写金额"/>
+                </template>
+              </vxe-table-column>
+              <vxe-table-column field="tax" title="税额" :edit-render="{}">
+                <template v-slot:edit="scope">
+                  <el-input :readonly="true" v-model="scope.row.tax" placeholder="请填写税额"/>
+                </template>
+              </vxe-table-column>
+              <vxe-table-column field="allAmount" title="累计登记金额" :edit-render="{}">
+                <template v-slot:edit="scope">
+                  <el-input-number
+                    v-model="scope.row.allAmount"
+                    controls-position="right"
+                    :controls="false"
+                    style="width:100%;"
+                    :precision="2"
+                    placeholder="请填写累计登记金额"
+                    :step="0.01"
+                    :min="0"
+                    clearable>
+                  </el-input-number>
+                </template>
+              </vxe-table-column>
+              <vxe-table-column title="操作" width="100">
+                <template v-slot="scope">
+                  <el-button size="mini" type="danger" @click="removeEvent(scope.row,scope.$rowIndex,'detail')">删除</el-button>
+                </template>
+              </vxe-table-column>
+            </vxe-table>
+          </el-row>
+        </el-form>
         <el-divider content-position="left"><i class="el-icon-document"></i>
           收款明细
           <el-button style="margin-left: 20px" :disabled="receivablesFlag!==true" type="primary" size="mini" @click="insertEvent('receivables')" plain>
@@ -540,7 +573,7 @@
       <UpLoadComponent ref="uploadComponent"></UpLoadComponent>
       <span slot="footer" class="dialog-footer">
       <el-button size="small" @click="close()" icon="el-icon-circle-close">关闭</el-button>
-      <el-button size="small" type="primary" v-if="method != 'view'||receivablesFlag!==true" @click="doSubmit()" icon="el-icon-circle-check" v-noMoreClick>确定</el-button>
+      <el-button size="small" type="primary" v-if="detailFlag===true" @click="doSubmit()" icon="el-icon-circle-check" v-noMoreClick>确定</el-button>
       <el-button size="small" type="primary" v-if="receivablesFlag===true" @click="doSubmit()" icon="el-icon-circle-check" v-noMoreClick>保留</el-button>
     </span>
     </el-dialog>
@@ -608,7 +641,9 @@
         programRow: '',
         bankList: [],
         err: '',
-        receivablesFlag: '' // true为收款,false为非收款
+        receivablesFlag: '', // true为收款,false为非收款
+        detailFlag: '', // true为修改发票明细
+        importVisible: false
       }
     },
     financeInvoiceService: null,
@@ -626,12 +661,19 @@
       UpLoadComponent
     },
     methods: {
-      init (receivablesFlag, id) {
+      init (receivablesFlag, id, meth) {
+        this.importVisible = false
         this.method = 'view'
         let method = this.method
         if (receivablesFlag !== true) {
           this.receivablesFlag = false
           this.title = '查看发票信息'
+          if (meth === true || meth === 'true') {
+            this.title = '修改发票明细'
+            this.detailFlag = true
+          } else {
+            this.detailFlag = false
+          }
         } else {
           this.receivablesFlag = true
           this.title = '收款'
@@ -834,6 +876,7 @@
           financeInvoiceInvalidDTO: {}
         }
         this.bankList = []
+        this.detailFlag = false
         this.visible = false
       },
       insertEvent (type) {
@@ -1023,6 +1066,108 @@
         } else {
           row.tax = undefined
         }
+      },
+      // 下载模板
+      downloadTpl () {
+        this.loading = true
+        this.financeInvoiceService.exportTemplate().then((res) => {
+          // 将二进制流文件写入excel表,以下为重要步骤
+          this.$utils.downloadExcel(res.data, '发票明细导入模板')
+          this.loading = false
+        }).catch(function (err) {
+          this.loading = false
+          if (err.response) {
+            console.log(err.response)
+          }
+        })
+      },
+      async detailPush (data) {
+        if (this.commonJS.isNotEmpty(data)) {
+          await data.forEach(item => {
+            this.getAmount(item)
+            this.getTax(item)
+            this.inputForm.financeInvoiceDetailDTOList.push(item)
+          })
+        }
+        this.$message.success('导入完成')
+      },
+      beforeUploadDetail (file) {
+        const formBody = new FormData()
+        formBody.append('file', file.raw)
+        this.loading = true
+        this.financeInvoiceService.importDetail(formBody).then(async (result) => {
+          if (this.commonJS.isEmpty(result.data)) {
+            this.importVisible = false
+            this.loading = false
+            throw new Error()
+          }
+          for await (let item of result.data) {
+            this.inputForm.financeInvoiceDetailDTOList.forEach(detail => {
+              if (item.number === detail.number) {
+                this.$message.error('上传的文件中存在与页面重复的发票号,请重新填写后上传')
+                this.importVisible = false
+                this.loading = false
+                throw new Error()
+              }
+            })
+          }
+          await this.detailPush(result.data)
+          this.importVisible = false
+          this.loading = false
+        }).catch(() => {
+          this.importVisible = false
+          this.loading = false
+        })
+      },
+      checkIdentificationNo () {
+        if (this.commonJS.isEmpty(this.inputForm.taxpayerIdentificationNo)) {
+          this.$message.error('当前纳税人识别号为空,导入失败')
+          throw new Error()
+        }
+      },
+      async beforeUploadDetailCode (file) {
+        console.log('110', this.inputForm.taxpayerIdentificationNo)
+        await this.checkIdentificationNo()
+        const formBody = new FormData()
+        formBody.append('file', file.raw)
+        this.loading = true
+        this.financeInvoiceService.importDetail(formBody).then(async result => {
+          if (this.commonJS.isEmpty(result.data)) {
+            this.importVisible = false
+            this.loading = false
+            throw new Error()
+          }
+          for await (let item of result.data) {
+            await this.inputForm.financeInvoiceDetailDTOList.forEach(detail => {
+              if (item.number === detail.number) {
+                this.$message.error('上传的文件中存在与页面重复的发票号,请重新填写后上传')
+                this.importVisible = false
+                this.loading = false
+                throw new Error()
+              }
+            })
+          }
+          this.detailPushCode(result.data)
+          this.importVisible = false
+          this.loading = false
+        }).catch(() => {
+          this.importVisible = false
+          this.loading = false
+        })
+      },
+      detailPushCode (data) {
+        if (this.commonJS.isNotEmpty(data)) {
+          data.forEach(item => {
+            if (this.commonJS.isNotEmpty(item.taxpayerIdentificationNo)) {
+              if (item.taxpayerIdentificationNo === this.inputForm.taxpayerIdentificationNo) {
+                this.getAmount(item)
+                this.getTax(item)
+                this.inputForm.financeInvoiceDetailDTOList.push(item)
+              }
+            }
+          })
+        }
+        this.$message.success('导入完成')
       }
     }
   }

+ 50 - 49
src/views/modules/finance/invoice/InvoiceFormTask.vue

@@ -367,46 +367,51 @@
           </el-form-item>
         </el-col>
       </el-row>
-      <el-divider content-position="left"><i class="el-icon-document"></i>
-        发票明细
-        <el-button style="margin-left: 20px" type="primary" :disabled="status === 'audit'?false:true" size="mini" @click="insertEvent('detail')" plain>
-          新增
-        </el-button>
-        <el-popover
-          placement="top"
-          width="400"
-          v-model="importVisible">
-          <p>请先下载模板,然后再进行导入操作</p>
-          <el-row :gutter="1">
-            <el-col :span="6">
-              <el-button type="success" size="small" @click="downloadTpl">下载模板</el-button>
-            </el-col>
-            <el-col :span="6">
-              <el-upload
-                action=""
-                :auto-upload="false"
-                :on-change="beforeUploadDetail"
-                :show-file-list="false">
-                <el-button size="small" type="primary">导入全部</el-button>
-              </el-upload>
-            </el-col>
-            <el-col :span="6">
-              <el-upload
-                action=""
-                :auto-upload="false"
-                :on-change="beforeUploadDetailCode"
-                :show-file-list="false">
-                <el-button size="small" type="primary">仅导入当前纳税人识别号</el-button>
-              </el-upload>
-            </el-col>
-          </el-row>
-          <div style="text-align: right; margin-top: 10px;margin-right: 10px;">
-            <el-button size="mini" type="default" @click="importVisible = false" plain>取消</el-button>
-<!--            <el-button type="primary" size="mini" @click="importVisible = false">确定</el-button>-->
-          </div>
-          <el-button style="margin-left: 20px" slot="reference" :disabled="status === 'audit'?false:true" type="warning" size="mini" plain>导入</el-button>
-        </el-popover>
-      </el-divider>
+
+
+        <el-form :disabled="status === 'audit'?false:true">
+          <el-divider content-position="left"><i class="el-icon-document"></i>
+            发票明细
+          <el-button style="margin-left: 20px" type="primary" :disabled="status === 'audit'?false:true" size="mini" @click="insertEvent('detail')" plain>
+            新增
+          </el-button>
+          <el-popover
+            placement="top"
+            width="400"
+            v-model="importVisible">
+            <p>请先下载模板,然后再进行导入操作</p>
+            <el-row :gutter="1">
+              <el-col :span="6">
+                <el-button :disabled="status === 'audit'?false:true" type="success" size="small" @click="downloadTpl">下载模板</el-button>
+              </el-col>
+              <el-col :span="6">
+                <el-upload
+                  action=""
+                  :auto-upload="false"
+                  :on-change="beforeUploadDetail"
+                  :show-file-list="false">
+                  <el-button :disabled="status === 'audit'?false:true" size="small" type="primary">导入全部</el-button>
+                </el-upload>
+              </el-col>
+              <el-col :span="6">
+                <el-upload
+                  action=""
+                  :auto-upload="false"
+                  :on-change="beforeUploadDetailCode"
+                  :show-file-list="false">
+                  <el-button :disabled="status === 'audit'?false:true" size="small" type="primary" >仅导入当前纳税人识别号</el-button>
+                </el-upload>
+              </el-col>
+            </el-row>
+            <div style="text-align: right; margin-top: 10px;margin-right: 10px;">
+              <el-button size="mini" :disabled="status === 'audit'?false:true" type="default" @click="importVisible = false" plain>取消</el-button>
+              <!--            <el-button type="primary" size="mini" @click="importVisible = false">确定</el-button>-->
+            </div>
+            <el-button style="margin-left: 20px" slot="reference" :disabled="status === 'audit'?false:true" type="warning" size="mini" plain>导入</el-button>
+          </el-popover>
+          </el-divider>
+        </el-form>
+
       <el-form size="middle" :model="inputForm" ref="inputForm" v-loading="loading" :class="method==='view'?'readonly':''"  :disabled="status !== 'audit'"
                label-width="160px" @submit.native.prevent>
       <el-row  :gutter="15">
@@ -430,18 +435,14 @@
           </vxe-table-column>
           <vxe-table-column field="number" title="发票号" :edit-render="{}">
             <template v-slot:edit="scope">
-              <el-input-number
+              <el-input
+                oninput ="value=value.replace(/\D|^/g,'')"
+                placeholder="请填写发票号"
+                maxlength="8"
                 @blur="checkNumber(scope.row,scope.$rowIndex)"
                 v-model="scope.row.number"
-                controls-position="right"
-                :controls="false"
-                style="width:100%;"
-                :precision="0"
-                placeholder="请填写发票号"
-                :step="1"
-                :min="0"
                 clearable>
-              </el-input-number>
+              </el-input>
             </template>
           </vxe-table-column>
           <vxe-table-column field="account" title="开票金额(元)" :edit-render="{}">

+ 5 - 9
src/views/modules/finance/invoice/InvoiceFormTaskInvalid.vue

@@ -396,18 +396,14 @@
           </vxe-table-column>
           <vxe-table-column field="number" title="发票号" :edit-render="{}">
             <template v-slot:edit="scope">
-              <el-input-number
+              <el-input
+                oninput ="value=value.replace(/\D|^/g,'')"
+                placeholder="请填写发票号"
+                maxlength="8"
                 @blur="checkNumber(scope.row,scope.$rowIndex)"
                 v-model="scope.row.number"
-                controls-position="right"
-                :controls="false"
-                style="width:100%;"
-                :precision="0"
-                placeholder="请填写发票号"
-                :step="1"
-                :min="0"
                 clearable>
-              </el-input-number>
+              </el-input>
             </template>
           </vxe-table-column>
           <vxe-table-column field="account" title="开票金额(元)" :edit-render="{}">

+ 59 - 44
src/views/modules/finance/invoice/InvoiceList.vue

@@ -14,6 +14,12 @@
             <el-button slot="append" @click="openProgramPageForm()" icon="el-icon-search"></el-button>
           </el-input>
         </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="refreshList()" size="small" icon="el-icon-search">查询</el-button>
+          <el-button @click="resetSearch()" size="small" icon="el-icon-refresh-right">重置</el-button>
+        </el-form-item>
+      </el-row>
+      <el-row :gutter="0">
         <el-form-item prop="reconciliationPeople" label="对账人">
           <UserSelect :limit='1' :readonly="true" :value="searchForm.reconciliationPeople" @getValue='(value) => {searchForm.reconciliationPeople = value}'></UserSelect>
         </el-form-item>
@@ -70,40 +76,7 @@
             :accordion="true"
             @getValue="(value) => {searchForm.reconciliationArea=value}"/>
         </el-form-item>
-        <el-form-item>
-          <el-button type="primary" @click="refreshList()" size="small" icon="el-icon-search">查询</el-button>
-          <el-button @click="resetSearch()" size="small" icon="el-icon-refresh-right">重置</el-button>
-        </el-form-item>
-      </el-row>
-      <el-row :gutter="0">
-        <el-form-item prop="accountBegin" label="开票总金额">
-          <el-input-number
-            size="small"
-            v-model="searchForm.accountBegin"
-            controls-position="right"
-            :controls="false"
-            style="width:100%;"
-            :precision="2"
-            placeholder="请填写开票总金额"
-            :step="0.01"
-            :min="0"
-            clearable>
-          </el-input-number>
-        </el-form-item>
-        <el-form-item prop="accountEnd" label="-">
-          <el-input-number
-            size="small"
-            v-model="searchForm.accountEnd"
-            controls-position="right"
-            :controls="false"
-            style="width:100%;"
-            :precision="2"
-            placeholder="请填写开票总金额"
-            :step="0.01"
-            :min="0"
-            clearable>
-          </el-input-number>
-        </el-form-item>
+
       </el-row>
       <el-row :gutter="0">
         <el-form-item prop="billingDateList" label="开票日期">
@@ -136,6 +109,36 @@
           </el-date-picker>
         </el-form-item>
       </el-row>
+      <el-row :gutter="0">
+        <el-form-item prop="accountBegin" label="开票总金额">
+          <el-input-number
+            size="small"
+            v-model="searchForm.accountBegin"
+            controls-position="right"
+            :controls="false"
+            style="width:100%;"
+            :precision="2"
+            placeholder="请填写开票总金额"
+            :step="0.01"
+            :min="0"
+            clearable>
+          </el-input-number>
+        </el-form-item>
+        <el-form-item prop="accountEnd" label="-">
+          <el-input-number
+            size="small"
+            v-model="searchForm.accountEnd"
+            controls-position="right"
+            :controls="false"
+            style="width:100%;"
+            :precision="2"
+            placeholder="请填写开票总金额"
+            :step="0.01"
+            :min="0"
+            clearable>
+          </el-input-number>
+        </el-form-item>
+      </el-row>
     </el-form>
     <div class="bg-white top" style="">
       <vxe-toolbar :refresh="{query: refreshList}" custom>
@@ -163,7 +166,11 @@
           :checkbox-config="{}">
           <vxe-column type="seq" width="40"></vxe-column>
           <vxe-column type="checkbox" width="40" ></vxe-column>
-          <vxe-column width="150" title="项目名称"align="center" field="programName"></vxe-column>
+          <vxe-column width="150" title="项目名称"align="center" field="programName">
+            <template slot-scope="scope">
+              <el-link  type="primary" :underline="false" @click="viewProject(scope.row.id)">{{scope.row.programName}}</el-link>
+            </template>
+          </vxe-column>
           <vxe-column width="150" title="发票申请编号"align="center" field="no">
             <template slot-scope="scope">
               <el-link  type="primary" :underline="false" @click="view(false, scope.row.id)">{{scope.row.no}}</el-link>
@@ -205,14 +212,15 @@
               <el-button  type="text" @click="invoiceDetail(scope.row)" :type="$dictUtils.getDictLabel('invoice_status_info', scope.row.status, '-')" effect="dark" size="mini">{{$dictUtils.getDictLabel("invoice_status", scope.row.status, '-')}} </el-button>
             </template>
           </vxe-column>
-          <vxe-column width="220" title="操作"  fixed="right" align="center">
+          <vxe-column width="300" title="操作"  fixed="right" align="center">
             <template  slot-scope="scope">
               <el-button v-if="hasPermission('finance:invoice:edit')&&scope.row.status === '1'||scope.row.status === '3'||scope.row.status === '4'" type="text" icon="el-icon-edit" size="small" @click="invoicePush(scope.row)">修改</el-button>
               <el-button v-if="hasPermission('finance:invoice:edit')&&scope.row.status === '2'" type="text"  icon="el-icon-delete" size="small" @click="invoiceReback(scope.row)">撤回</el-button>
-              <el-button v-if="hasPermission('finance:invoice:edit')&&scope.row.status === '5'&&scope.row.receivablesStatus !== '1'" type="text"  icon="el-icon-finished" size="small" @click="view(true, scope.row.id)">收款</el-button>
-              <el-button v-if="hasPermission('finance:invoice:edit')&&scope.row.status === '5'&&scope.row.receivablesStatus !== '1'" type="text"  icon="el-icon-document-checked" size="small" @click="isReceivables(scope.row)">确认收款</el-button>
-              <el-button v-if="hasPermission('finance:invoice:edit')&&scope.row.status === '5'||scope.row.status === '7'||scope.row.status === '8'" type="text" icon="el-icon-document-delete" size="small" @click="invoiceInvalidPush(scope.row)">作废</el-button>
-              <el-button v-if="hasPermission('finance:invoice:edit')&&scope.row.status === '6'" type="text" icon="el-icon-document-delete" size="small" @click="invoiceInvalidReBack(scope.row)">作废撤回</el-button>
+              <el-button v-if="hasPermission('finance:invoice:edit:detail')&&scope.row.status === '5'&&scope.row.receivablesStatus !== '1'" type="text" icon="el-icon-edit" size="small" @click="editDetail(scope.row.id)">修改发票明细</el-button>
+              <el-button v-if="hasPermission('finance:invoice:edit:receivables')&&scope.row.status === '5'&&scope.row.receivablesStatus !== '1'" type="text"  icon="el-icon-finished" size="small" @click="view(true, scope.row.id)">收款</el-button>
+              <el-button v-if="hasPermission('finance:invoice:edit:is_receivables')&&scope.row.status === '5'&&scope.row.receivablesStatus !== '1'" type="text"  icon="el-icon-document-checked" size="small" @click="isReceivables(scope.row)">确认收款</el-button>
+              <el-button v-if="hasPermission('finance:invoice:edit:invalid')&&scope.row.status === '5'||scope.row.status === '7'||scope.row.status === '8'" type="text" icon="el-icon-document-delete" size="small" @click="invoiceInvalidPush(scope.row)">作废</el-button>
+              <el-button v-if="hasPermission('finance:invoice:edit:invalid')&&scope.row.status === '6'" type="text" icon="el-icon-document-delete" size="small" @click="invoiceInvalidReBack(scope.row)">作废撤回</el-button>
               <el-button v-if="hasPermission('finance:invoice:edit')&&scope.row.status === '1'||scope.row.status === '3'||scope.row.status === '4'" type="text"  icon="el-icon-delete" size="small" @click="del(scope.row.id)">删除</el-button>
             </template>
           </vxe-column>
@@ -231,11 +239,13 @@
     </div>
     <InvoiceForm  ref="invoiceForm" @refreshDataList="refreshList"></InvoiceForm>
     <ProgramPageForm ref="programPageForm" @getProgram="getProgram"></ProgramPageForm>
+    <ProgramForm ref="programForm"></ProgramForm>
   </div>
 </template>
 
 <script>
   import FinanceInvoiceService from '@/api/finance/invoice/FinanceInvoiceService'
+  import ProgramForm from './ProgramForm'
   import InvoiceForm from './InvoiceForm'
   import pick from 'lodash.pick'
   import TaskService from '@/api/flowable/TaskService'
@@ -296,7 +306,8 @@
       UserSelect,
       SelectUserTree,
       SelectTree,
-      ProgramPageForm
+      ProgramPageForm,
+      ProgramForm
     },
     mounted () {
       this.refreshList()
@@ -309,17 +320,21 @@
       add () {
         this.$refs.invoiceForm.init('add', '')
       },
-      // 修改
-      edit (id) {
+      // 修改发票明细
+      editDetail (id) {
         id = id || this.$refs.invoiceTable.getCheckboxRecords().map(item => {
           return item.id
         })[0]
-        this.$refs.invoiceForm.init('edit', id)
+        this.$refs.invoiceForm.init(false, id, true)
       },
       // 查看 flag为true时,弹窗为收款,其他值为查看发票详情
       view (flag, id) {
         this.$refs.invoiceForm.init(flag, id)
       },
+      // 查看项目数据
+      viewProject (id) {
+        this.$refs.programForm.init(id)
+      },
       // 获取数据列表
       refreshList () {
         this.loading = true

+ 668 - 0
src/views/modules/finance/invoice/ProgramForm.vue

@@ -0,0 +1,668 @@
+<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
+  <div>
+    <el-dialog
+      :title="title"
+      :close-on-click-modal="false"
+      v-dialogDrag
+      width="1300px"
+      @close="close"
+      @keyup.enter.native="doSubmit"
+      :visible.sync="visible">
+      <el-form size="middle" :model="inputForm" ref="inputForm" v-loading="loading" :class="method==='view'?'readonly':''"
+               label-width="160px" @submit.native.prevent>
+        <el-row  :gutter="15" v-if="baseFlag !== true">
+          <vxe-table
+            border
+            show-overflow
+            show-footer
+            ref="baseTable"
+            class="vxe-table-element"
+            :data="inputForm.financeInvoiceBaseDTOList"
+            style="margin-left: 5em"
+            @cell-click=""
+            @edit-closed=""
+            highlight-current-row
+            :edit-config="{trigger: 'click', mode: 'cell', showStatus: true, autoClear: true}"
+          >
+            <vxe-table-column field="programName" title="项目名称" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input @focus="openProjectForm(scope.row.programId)" placeholder="请填写项目名称" :readonly="true" v-model="scope.row.programName"/>
+              </template>
+            </vxe-table-column>
+            <vxe-table-column field="contractName" title="合同名称" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input placeholder="请填写合同名称" :readonly="true" v-model="scope.row.contractName"/>
+              </template>
+            </vxe-table-column>
+            <vxe-table-column field="programNo" title="项目编号" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input :readonly="true" placeholder="请填写项目编号" v-model="scope.row.programNo"/>
+              </template>
+            </vxe-table-column>
+            <vxe-table-column field="clientName" title="委托方" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input :readonly="true" placeholder="请填写委托方" v-model="scope.row.clientName"/>
+              </template>
+            </vxe-table-column>
+<!--            <vxe-table-column field="reportNo" title="报告号" :edit-render="{}">-->
+<!--              <template v-slot:edit="scope">-->
+<!--                <el-input v-model="scope.row.reportNo" placeholder="请填写报告号"/>-->
+<!--              </template>-->
+<!--            </vxe-table-column>-->
+<!--            <vxe-table-column title="操作" width="100">-->
+<!--              <template v-slot="scope">-->
+<!--                <el-button size="mini" type="danger" @click="removeEvent(scope.row,scope.$rowIndex,'base')">删除</el-button>-->
+<!--              </template>-->
+<!--            </vxe-table-column>-->
+          </vxe-table>
+        </el-row>
+        <el-row :gutter="15" v-if="baseFlag === true">
+          <el-form-item label="开票详情" prop="">
+          <el-input :readonly="true" type="textarea" maxlength="500" v-model="programName"></el-input>
+          </el-form-item>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="close()" icon="el-icon-circle-close">关闭</el-button>
+<!--      <el-button size="small" type="primary" v-if="method != 'view'||receivablesFlag!==true" @click="doSubmit()" icon="el-icon-circle-check" v-noMoreClick>确定</el-button>-->
+<!--      <el-button size="small" type="primary" v-if="receivablesFlag===true" @click="doSubmit()" icon="el-icon-circle-check" v-noMoreClick>保留</el-button>-->
+    </span>
+    </el-dialog>
+    <ProgramPageForm ref="programPageForm" @getProgram="getProgram"></ProgramPageForm>
+    <ContractForm  ref="contractForm" @getContract="getContract"></ContractForm>
+    <WorkClientForm  ref="workClientForm" @getWorkClient="getWorkClient"></WorkClientForm>
+    <ProjectForm ref="projectForm"></ProjectForm>
+  </div>
+</template>
+
+<script>
+  import FinanceInvoiceService from '@/api/finance/invoice/FinanceInvoiceService'
+  import WorkClientService from '@/api/sys/WorkClientService'
+  import ProjectForm from '@/views/modules/program/registered/ProjectForm'
+  import ProgramPageForm from '@/views/modules/finance/invoice/ProgramPageForm'
+  import UpLoadComponent from '@/views/common/UpLoadComponent'
+  import ContractForm from '@/views/modules/program/registered/ContractForm'
+  import WorkClientForm from '@/views/modules/program/registered/WorkClientForm'
+  import SelectUserTree from '@/views/modules/utils/treeUserSelect'
+  import SelectTree from '@/components/treeSelect/treeSelect.vue'
+  export default {
+    data () {
+      return {
+        title: '',
+        method: '',
+        visible: false,
+        loading: false,
+        inputForm: {
+          id: '',
+          financeInvoiceBaseDTOList: [],
+          programName: '',
+          contractName: '',
+          programNo: '',
+          clientName: '',
+          reportNo: '',
+          type: '1',
+          no: '',
+          billingType: '1',
+          billingWorkplaceReal: '',
+          billingWorkplaceRealId: '',
+          taxpayerIdentificationNo: '',
+          address: '',
+          telPhone: '',
+          openBank: '',
+          bankAccount: '',
+          receivablesType: '2',
+          billingContent: '',
+          account: '',
+          billingContentTerms: '',
+          billingPeople: JSON.parse(localStorage.getItem('user')).name,
+          billingPeopleId: JSON.parse(localStorage.getItem('user')).id,
+          billingDate: '',
+          collectDate: '',
+          billingPeopleReal: JSON.parse(localStorage.getItem('user')).id,
+          reconciliationPeople: '',
+          reconciliationArea: '',
+          remarks: '',
+          name: '',
+          status: '',
+          procInsId: '',
+          processDefinitionId: '',
+          workAttachmentDtoList: [],
+          financeInvoiceDetailDTOList: [],
+          financeInvoiceReceivablesDTOList: [],
+          financeInvoiceInvalidDTO: {}
+        },
+        programRow: '',
+        bankList: [],
+        err: '',
+        receivablesFlag: '', // true为收款,false为非收款
+        detailFlag: '', // true为修改发票明细
+        importVisible: false,
+        baseFlag: false,
+        programName: ''
+      }
+    },
+    financeInvoiceService: null,
+    workClientService: null,
+    created () {
+      this.financeInvoiceService = new FinanceInvoiceService()
+      this.workClientService = new WorkClientService()
+    },
+    components: {
+      ProgramPageForm,
+      ContractForm,
+      WorkClientForm,
+      SelectUserTree,
+      SelectTree,
+      UpLoadComponent,
+      ProjectForm
+    },
+    methods: {
+      init (id) {
+        this.method = 'view'
+        this.title = '查看项目信息'
+        this.inputForm = {
+          id: '',
+          financeInvoiceBaseDTOList: [],
+          programName: '',
+          contractName: '',
+          programNo: '',
+          clientName: '',
+          reportNo: '',
+          type: '1',
+          no: '',
+          billingType: '1',
+          billingWorkplaceReal: '',
+          billingWorkplaceRealId: '',
+          taxpayerIdentificationNo: '',
+          address: '',
+          telPhone: '',
+          openBank: '',
+          bankAccount: '',
+          receivablesType: '2',
+          billingContent: '',
+          account: '',
+          billingContentTerms: '',
+          billingPeople: JSON.parse(localStorage.getItem('user')).name,
+          billingPeopleId: JSON.parse(localStorage.getItem('user')).id,
+          billingDate: '',
+          collectDate: '',
+          billingPeopleReal: JSON.parse(localStorage.getItem('user')).id,
+          reconciliationPeople: '',
+          reconciliationArea: '',
+          remarks: '',
+          name: '',
+          status: '',
+          procInsId: '',
+          processDefinitionId: '',
+          workAttachmentDtoList: [],
+          financeInvoiceDetailDTOList: [],
+          financeInvoiceReceivablesDTOList: [],
+          financeInvoiceInvalidDTO: {
+            id: '',
+            invalidStatus: '',
+            invoiceId: '',
+            remarks: ''
+          }
+        }
+        this.baseFlag = false
+        this.inputForm.id = id
+        this.visible = true
+        this.loading = false
+        this.$nextTick(() => {
+          this.$refs.inputForm.resetFields()
+          this.loading = true
+          this.financeInvoiceService.queryById(this.inputForm.id).then(({data}) => {
+            this.inputForm = this.recover(this.inputForm, data)
+            this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+            if (!this.commonJS.isEmpty(this.inputForm.billingWorkplaceRealId)) {
+              this.workClientService.findById(this.inputForm.billingWorkplaceRealId).then((data) => {
+                this.bankList = data.data.workClientBank
+              })
+            }
+            if (this.commonJS.isEmpty(this.inputForm.financeInvoiceReceivablesDTOList) || this.inputForm.financeInvoiceReceivablesDTOList.length === 0) {
+              this.inputForm.financeInvoiceReceivablesDTOList = []
+            }
+            if (this.commonJS.isEmpty(this.inputForm.workAttachmentDtoList)) {
+              this.inputForm.workAttachmentDtoList = []
+            }
+            if (this.commonJS.isNotEmpty(this.inputForm.financeInvoiceBaseDTOList)) {
+              if (this.inputForm.financeInvoiceBaseDTOList.length === 1 && this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0].programId)) {
+                this.baseFlag = true
+                this.programName = this.inputForm.financeInvoiceBaseDTOList[0].programName
+              }
+            }
+            this.loading = false
+          })
+        })
+      },
+      openProjectForm (id) {
+        this.$refs.projectForm.init('view', id)
+      },
+      // 表单提交
+      async doSubmit () {
+        if (this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList)) {
+          this.$message.error('至少新增一条基本信息')
+          return
+        } else {
+          if (this.inputForm.financeInvoiceBaseDTOList.length === 0) {
+            this.$message.error('至少新增一条基本信息')
+            return
+          }
+        }
+        let acc = 0
+        this.inputForm.financeInvoiceDetailDTOList.forEach((item, index) => {
+          if (this.commonJS.isEmpty(item.number)) {
+            this.$message.warning('发票明细中第 ' + (index + 1) + ' 条数据的 “发票号” 为空')
+            throw new Error()
+          }
+          if (this.commonJS.isEmpty(item.account)) {
+            this.$message.warning('发票明细中第 ' + (index + 1) + ' 条数据的 “开票金额” 为空')
+            throw new Error()
+          }
+          acc = (acc + parseFloat(parseFloat(item.account).toFixed(2)))
+        })
+        if (acc !== this.inputForm.account) {
+          this.$message.warning('发票明细中 “开票金额”总和 与发票详情中 “发票金额” 不等')
+          return
+        }
+        this.inputForm.financeInvoiceDetailDTOList.forEach((item, index) => {
+          this.inputForm.financeInvoiceDetailDTOList.forEach((item2, index2) => {
+            if (index !== index2) {
+              if (item.number === item2.number) {
+                this.$message.warning('发票明细中第 ' + (index + 1) + ' 条数据的 “发票号” 存在重复')
+                throw new Error()
+              }
+            }
+          })
+        })
+        for await (let [index, item] of this.inputForm.financeInvoiceDetailDTOList.entries()) {
+          if (this.commonJS.isEmpty(item.number)) {
+            this.$message.warning('发票明细中第 ' + (index + 1) + ' 条数据的 “发票号” 为空')
+            this.err = true
+          }
+          await this.financeInvoiceService.queryByNumber(item.number, item.id).then(({data}) => {
+            if (data === true) {
+              this.$message.warning('发票明细中第 ' + (index + 1) + ' 条数据的 “发票号” 存在重复')
+              this.err = data
+            }
+          })
+        }
+        if (this.err === true) {
+          this.err = ''
+          return
+        }
+        if (this.receivablesFlag === true) {
+          this.inputForm.financeInvoiceReceivablesDTOList.forEach((item, index) => {
+            if (this.commonJS.isEmpty(item.remittanceUnit)) {
+              this.$message.warning('收款明细中第 ' + (index + 1) + ' 条数据的 “汇款单位” 为空,请重新输入')
+              throw new Error()
+            }
+            if (this.commonJS.isEmpty(item.remittanceAmount) || item.remittanceAmount === 0 || item.remittanceAmount === '0') {
+              this.$message.warning('收款明细中第 ' + (index + 1) + ' 条数据的 “汇款金额” 为空,请重新输入')
+              throw new Error()
+            }
+            if (this.commonJS.isEmpty(item.remittanceDate)) {
+              this.$message.warning('收款明细中第 ' + (index + 1) + ' 条数据的 “汇款时间” 为空,请重新输入')
+              throw new Error()
+            }
+          })
+        }
+        this.$refs['inputForm'].validate((valid) => {
+          if (valid) {
+            this.loading = true
+            if (this.$refs.uploadComponent.checkProgress()) {
+              this.loading = false
+              return
+            }
+            this.inputForm.workAttachmentDtoList = this.$refs.uploadComponent.getDataList()
+            this.financeInvoiceService.save(this.inputForm).then(({data}) => {
+              this.close()
+              this.$message.success(data)
+              this.$emit('refreshDataList')
+              this.loading = false
+            }).catch(() => {
+              this.loading = false
+            })
+          }
+        })
+      },
+      close () {
+        this.$refs.inputForm.resetFields()
+        this.inputForm = {
+          id: '',
+          financeInvoiceBaseDTOList: [],
+          programName: '',
+          contractName: '',
+          programNo: '',
+          clientName: '',
+          reportNo: '',
+          type: '1',
+          no: '',
+          billingType: '1',
+          billingWorkplaceReal: '',
+          billingWorkplaceRealId: '',
+          taxpayerIdentificationNo: '',
+          address: '',
+          telPhone: '',
+          openBank: '',
+          bankAccount: '',
+          receivablesType: '2',
+          billingContent: '',
+          account: '',
+          billingContentTerms: '',
+          billingPeople: '',
+          billingPeopleId: '',
+          billingDate: '',
+          collectDate: '',
+          billingPeopleReal: '',
+          reconciliationPeople: '',
+          reconciliationArea: '',
+          remarks: '',
+          name: '',
+          workAttachmentDtoList: [],
+          financeInvoiceDetailDTOList: [],
+          financeInvoiceReceivablesDTOList: [],
+          financeInvoiceInvalidDTO: {}
+        }
+        this.bankList = []
+        this.detailFlag = false
+        this.visible = false
+      },
+      insertEvent (type) {
+        if (type === 'base') {
+          if (this.inputForm.financeInvoiceBaseDTOList.length >= 1) {
+            if (this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0].programId)) {
+              this.$message.warning('非项目,只能有一条非项目数据')
+              return
+            }
+          }
+          this.$refs.baseTable.insert().then((data) => {
+            this.inputForm.financeInvoiceBaseDTOList.push(data)
+          })
+        }
+        if (type === 'detail') {
+          this.$refs.detailTable.insert().then((data) => {
+            this.inputForm.financeInvoiceDetailDTOList.push(data)
+          })
+        }
+        if (type === 'receivables') {
+          this.$refs.receivablesTable.insert().then((data) => {
+            this.inputForm.financeInvoiceReceivablesDTOList.push(data)
+          })
+        }
+      },
+      // 删除
+      removeEvent (row, rowIndex, type) {
+        if (type === 'base') {
+          this.$refs.baseTable.remove(row)
+          this.inputForm.financeInvoiceBaseDTOList.splice(rowIndex, 1)
+        }
+        if (type === 'detail') {
+          this.$refs.detailTable.remove(row)
+          this.inputForm.financeInvoiceDetailDTOList.splice(rowIndex, 1)
+        }
+        if (type === 'receivables') {
+          this.$refs.receivablesTable.remove(row)
+          this.inputForm.financeInvoiceReceivablesDTOList.splice(rowIndex, 1)
+        }
+      },
+      openProgramPageForm (rowIndex) {
+        if (this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0].programName) || this.inputForm.financeInvoiceBaseDTOList.length === 1) {
+          this.$refs.programPageForm.init()
+        } else {
+          if (this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0].programId)) {
+            this.$refs.programPageForm.init('s')
+          } else {
+            this.$refs.programPageForm.init(false)
+          }
+        }
+        this.programRow = rowIndex
+      },
+      getProgram (rows) {
+        rows.forEach((item, index) => {
+          if (index === 0) {
+            let r = this.inputForm.financeInvoiceBaseDTOList[this.programRow]
+            r.programName = item.name
+            r.contractName = item.contractName
+            r.programNo = item.no
+            r.clientName = item.clientName
+            r.client = item.client
+            r.programId = item.id
+            r.location = item.location // 项目所在地
+            this.inputForm.financeInvoiceBaseDTOList[this.programRow] = r
+          } else {
+            let r = {
+              programName: item.name,
+              contractName: item.contractName,
+              programNo: item.no,
+              clientName: item.clientName,
+              client: item.client,
+              programId: item.id,
+              location: item.location // 项目所在地
+            }
+            this.inputForm.financeInvoiceBaseDTOList.push(r)
+          }
+        })
+        this.$forceUpdate()
+        this.programRow = ''
+        this.inputForm.reconciliationArea = this.inputForm.financeInvoiceBaseDTOList[0].location
+      },
+      openContractForm () {
+        if (!this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0])) {
+          if (this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0].programId) && this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0].programName)) {
+            this.$message.warning('请先选择项目')
+          } else if (this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0].programId) && !this.commonJS.isEmpty(this.inputForm.financeInvoiceBaseDTOList[0].programName)) {
+            this.$refs.contractForm.init()
+          } else {
+            this.$message.warning('只有非项目开票可选择合同信息')
+          }
+        } else {
+          this.$message.warning('请选择项目信息')
+        }
+      },
+      getContract (row) {
+        this.inputForm.financeInvoiceBaseDTOList[0].contractName = row.name // 合同名称
+        this.inputForm.financeInvoiceBaseDTOList[0].client = row.clientId // 委托方
+        this.inputForm.financeInvoiceBaseDTOList[0].clientName = row.clientName // 委托方名称
+        this.$forceUpdate()
+      },
+      changeRadio () {
+        this.inputForm.address = ''
+        this.inputForm.telPhone = ''
+        this.inputForm.billingWorkplaceReal = ''
+        this.inputForm.billingWorkplaceRealId = ''
+        this.inputForm.taxpayerIdentificationNo = ''
+        this.bankList = []
+        this.inputForm.bankAccount = ''
+        this.inputForm.openBank = ''
+        this.inputForm.name = ''
+        this.$forceUpdate()
+      },
+      openWorkClientForm () {
+        this.$refs.workClientForm.init(null, '')
+      },
+      getWorkClient (row) {
+        this.inputForm.billingWorkplaceReal = row.name // 实际开票单位姓名
+        this.inputForm.billingWorkplaceRealId = row.id // 实际开票单位id ‘客户id’
+        this.inputForm.taxpayerIdentificationNo = row.uscCode // 纳税人识别号 ‘统一社会信用代码’
+        this.inputForm.address = row.registerAddress // 地址 ‘注册地址’
+        this.inputForm.telPhone = row.telephone // 电话
+        this.bankList = row.backs
+        this.inputForm.bankAccount = ''
+        this.inputForm.openBank = ''
+        this.$forceUpdate()
+      },
+      changeBank (value) {
+        this.bankList.forEach(item => {
+          if (item.id === value) {
+            this.inputForm.bankAccount = item.bankNumber
+          }
+        })
+      },
+      checkNumber (row, rowIndex) {
+        if (!this.commonJS.isEmpty(row.number)) {
+          if (parseInt(row.number) > 99999999) {
+            this.$message.warning('“发票号” 不可以大于 8 位,请重新输入')
+            row.number = undefined
+            return
+          }
+          this.inputForm.financeInvoiceDetailDTOList.forEach((item, index) => {
+            if (rowIndex !== index) {
+              if (row.number === item.number) {
+                row.number = ''
+                this.$message.warning('“发票号” 已存在,请重新输入')
+                throw new Error()
+              }
+            }
+          })
+          this.financeInvoiceService.queryByNumber(row.number, row.id).then(({data}) => {
+            if (data === true) {
+              row.number = ''
+              this.$message.warning('“发票号” 已存在,请重新输入')
+            }
+          })
+        }
+      },
+      checkAccount (row, rowIndex) {
+        if (this.commonJS.isEmpty(row.account)) {
+          row.account = undefined
+        }
+        this.getAmount(row)
+        this.getTax(row)
+      },
+      checkRate (row, rowIndex) {
+        if (!this.commonJS.isEmpty(row.rate)) {
+          if (parseFloat(row.rate) < 1 || parseFloat(row.rate) > 100) {
+            this.$message.warning('“税率” 请填写 1 到 100 之间的数字,请重新输入')
+            row.rate = undefined
+          }
+        }
+        this.getAmount(row)
+        this.getTax(row)
+      },
+      // 根据开票金额和税率计算出金额: 开票金额-税率*开票金额
+      getAmount (row) {
+        if (!this.commonJS.isEmpty(row.account) && !this.commonJS.isEmpty(row.rate)) {
+          row.amount = parseFloat((parseFloat(row.account) - parseFloat((parseFloat(row.account) * parseFloat((parseFloat(row.rate) / 100).toFixed(4))).toFixed(4))).toFixed(2))
+        } else {
+          row.amount = undefined
+        }
+      },
+      // 根据开票金额和税率计算出税额: 税率*开票金额
+      getTax (row) {
+        if (!this.commonJS.isEmpty(row.account) && !this.commonJS.isEmpty(row.rate)) {
+          row.tax = parseFloat((parseFloat(row.account) * parseFloat((parseFloat(row.rate) / 100).toFixed(4))).toFixed(2))
+        } else {
+          row.tax = undefined
+        }
+      },
+      // 下载模板
+      downloadTpl () {
+        this.loading = true
+        this.financeInvoiceService.exportTemplate().then((res) => {
+          // 将二进制流文件写入excel表,以下为重要步骤
+          this.$utils.downloadExcel(res.data, '发票明细导入模板')
+          this.loading = false
+        }).catch(function (err) {
+          this.loading = false
+          if (err.response) {
+            console.log(err.response)
+          }
+        })
+      },
+      async detailPush (data) {
+        if (this.commonJS.isNotEmpty(data)) {
+          await data.forEach(item => {
+            this.getAmount(item)
+            this.getTax(item)
+            this.inputForm.financeInvoiceDetailDTOList.push(item)
+          })
+        }
+        this.$message.success('导入完成')
+      },
+      beforeUploadDetail (file) {
+        const formBody = new FormData()
+        formBody.append('file', file.raw)
+        this.loading = true
+        this.financeInvoiceService.importDetail(formBody).then(async (result) => {
+          if (this.commonJS.isEmpty(result.data)) {
+            this.importVisible = false
+            this.loading = false
+            throw new Error()
+          }
+          for await (let item of result.data) {
+            this.inputForm.financeInvoiceDetailDTOList.forEach(detail => {
+              if (item.number === detail.number) {
+                this.$message.error('上传的文件中存在与页面重复的发票号,请重新填写后上传')
+                this.importVisible = false
+                this.loading = false
+                throw new Error()
+              }
+            })
+          }
+          await this.detailPush(result.data)
+          this.importVisible = false
+          this.loading = false
+        }).catch(() => {
+          this.importVisible = false
+          this.loading = false
+        })
+      },
+      checkIdentificationNo () {
+        if (this.commonJS.isEmpty(this.inputForm.taxpayerIdentificationNo)) {
+          this.$message.error('当前纳税人识别号为空,导入失败')
+          throw new Error()
+        }
+      },
+      async beforeUploadDetailCode (file) {
+        console.log('110', this.inputForm.taxpayerIdentificationNo)
+        await this.checkIdentificationNo()
+        const formBody = new FormData()
+        formBody.append('file', file.raw)
+        this.loading = true
+        this.financeInvoiceService.importDetail(formBody).then(async result => {
+          if (this.commonJS.isEmpty(result.data)) {
+            this.importVisible = false
+            this.loading = false
+            throw new Error()
+          }
+          for await (let item of result.data) {
+            await this.inputForm.financeInvoiceDetailDTOList.forEach(detail => {
+              if (item.number === detail.number) {
+                this.$message.error('上传的文件中存在与页面重复的发票号,请重新填写后上传')
+                this.importVisible = false
+                this.loading = false
+                throw new Error()
+              }
+            })
+          }
+          this.detailPushCode(result.data)
+          this.importVisible = false
+          this.loading = false
+        }).catch(() => {
+          this.importVisible = false
+          this.loading = false
+        })
+      },
+      detailPushCode (data) {
+        if (this.commonJS.isNotEmpty(data)) {
+          data.forEach(item => {
+            if (this.commonJS.isNotEmpty(item.taxpayerIdentificationNo)) {
+              if (item.taxpayerIdentificationNo === this.inputForm.taxpayerIdentificationNo) {
+                this.getAmount(item)
+                this.getTax(item)
+                this.inputForm.financeInvoiceDetailDTOList.push(item)
+              }
+            }
+          })
+        }
+        this.$message.success('导入完成')
+      }
+    }
+  }
+</script>
+<style scoped>
+  /deep/ .el-input-number .el-input__inner {
+    text-align: left;
+  }
+</style>

+ 1 - 1
src/views/modules/finance/invoice/ProgramPageForm.vue

@@ -54,7 +54,7 @@
           <vxe-column width="150px" title="登记人" field="createBy"></vxe-column>
 <!--          <vxe-column width="150px" title="责任人" field="createDate"></vxe-column>-->
           <vxe-column width="100px" title="委托方" field="clientName"></vxe-column>
-<!--          <vxe-column width="100px" title="是否开票" field="createBy"></vxe-column>-->
+          <vxe-column width="100px" title="是否开票" field="isInvoice"></vxe-column>
 
         </vxe-table>
         <vxe-pager