|
@@ -0,0 +1,264 @@
|
|
|
+<template>
|
|
|
+ <div style="padding:10px">
|
|
|
+ <ul style="width:100%;margin-bottom:10px;display:flex;justify-content:flex-end;margin-top:10px;align-items:center;">
|
|
|
+ <li style="line-height:30px;margin-right:20px">
|
|
|
+ <span>非税总报价 : </span>
|
|
|
+ <span>{{tableData.assess_price}}</span>
|
|
|
+ </li>
|
|
|
+
|
|
|
+ <li style="line-height:30px;margin-right:20px">
|
|
|
+ <span>含税总报价 : </span>
|
|
|
+ <span>{{tableData.assess_total_price}}</span>
|
|
|
+ </li>
|
|
|
+
|
|
|
+ <li style="line-height:30px;margin-right:20px">
|
|
|
+ <span>总税额 : </span>
|
|
|
+ <span>{{tableData.assess_price}}</span>
|
|
|
+ </li>
|
|
|
+
|
|
|
+
|
|
|
+ <!-- <li style="margin-right: 10px">
|
|
|
+ <el-button size="mini" type="primary" @click="downloadTemplate">下载模板</el-button>
|
|
|
+ </li> -->
|
|
|
+
|
|
|
+ <li>
|
|
|
+ <el-button size="mini" type="primary" @click="onSubmit">保存</el-button>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+
|
|
|
+ <!-- <div v-if="tableData && tableData.length > 0" class="tr" style="padding: 10px 0 0 0">
|
|
|
+ <el-button :size="'mini'" @click="() => tableData = []">取消</el-button>
|
|
|
+ <el-button type="primary" :size="'mini'" @click="onSubmit">提交</el-button>
|
|
|
+ </div> -->
|
|
|
+ <!-- <upload-excel :on-success="onSuccess" :before-upload="beforeUpload" /> -->
|
|
|
+
|
|
|
+ <ex-table
|
|
|
+ :columns="[ ...columns,{ _slot_: 'action', label: '操作', width: '160px' } ]"
|
|
|
+ :table="table"
|
|
|
+ :data="tableData.assessinfo"
|
|
|
+ style="margin: 15px 0 0 0"
|
|
|
+ >
|
|
|
+ <template #action={scope}>
|
|
|
+ <el-button size="mini" type="text" @click="copyItem(scope.row)">复制</el-button>
|
|
|
+ <el-button size="mini" type="text">编辑</el-button>
|
|
|
+ <el-button size="mini" type="text" @click="deleteItem(scope.row)">删除</el-button>
|
|
|
+ <!-- <el-button size="mini" type="text">保存</el-button> -->
|
|
|
+ </template>
|
|
|
+ </ex-table>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import asyncRequest from "@/apis/service/customerService/workbench";
|
|
|
+import companyHelper from '@/mixins/companyHelper'
|
|
|
+import { MessageBox } from 'element-ui'
|
|
|
+import { template } from "./_template"
|
|
|
+import { utils, writeFile } from "xlsx"
|
|
|
+// import dayjs from 'dayjs'
|
|
|
+
|
|
|
+import {
|
|
|
+ helper,
|
|
|
+ columns,
|
|
|
+ getTableProperty,
|
|
|
+ createErrorMessage,
|
|
|
+ createFieldVerification,
|
|
|
+ requiredFields,
|
|
|
+} from './_template'
|
|
|
+
|
|
|
+export default {
|
|
|
+ mixins: [companyHelper],
|
|
|
+ props: ['visible'],
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ columns,
|
|
|
+ loading: false,
|
|
|
+ tableData: [],
|
|
|
+ table: {
|
|
|
+ stripe: true,
|
|
|
+ border: true,
|
|
|
+ 'max-height': '800px'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ total:{
|
|
|
+ handler(newVal){
|
|
|
+ newVal.reduce(item => ({
|
|
|
+
|
|
|
+ }),{
|
|
|
+ total:0,
|
|
|
+ includeTaxTotal: 0,
|
|
|
+ notTaxTotal: 0
|
|
|
+ })
|
|
|
+ },
|
|
|
+ deep: true,
|
|
|
+ immediate: true
|
|
|
+ },
|
|
|
+ innerVisible: {
|
|
|
+ get() {
|
|
|
+ return this.visible
|
|
|
+ },
|
|
|
+ set(newVal) {
|
|
|
+ this.$emit('update:visible', newVal)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted(){
|
|
|
+ this.onSearch()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async onSearch(){
|
|
|
+ this.loading = true
|
|
|
+
|
|
|
+ const { code, data } = await asyncRequest.planDetail({
|
|
|
+ id: this.$route.query.id
|
|
|
+ });
|
|
|
+
|
|
|
+ this.loading = false
|
|
|
+ if(code !== 1) return
|
|
|
+
|
|
|
+ this.tableData = data
|
|
|
+ },
|
|
|
+ async copyItem(row){
|
|
|
+ this.loading = true
|
|
|
+ const { code } = await asyncRequest.planCreate({
|
|
|
+ req_id: this.tableData.req_id,
|
|
|
+ plan_info: [ row ],
|
|
|
+ store_id: 3
|
|
|
+ })
|
|
|
+ this.loading = false
|
|
|
+
|
|
|
+ if(code !== 1) return
|
|
|
+ this.onSearch()
|
|
|
+ },
|
|
|
+ async deleteItem(row){
|
|
|
+ this.loading = true
|
|
|
+ const { code } = await asyncRequest.planDelete({id: row.id})
|
|
|
+ this.loading = false
|
|
|
+ if(code !== 1) return
|
|
|
+ this.onSearch()
|
|
|
+ },
|
|
|
+ downloadTemplate(){
|
|
|
+ const workBook = utils.book_new()
|
|
|
+ const workSheet = utils.json_to_sheet(template)
|
|
|
+ utils.book_append_sheet(workBook,workSheet,"sheet")
|
|
|
+
|
|
|
+ writeFile(workBook,"预算函模板.xlsx",{
|
|
|
+ bookType:'xlsx'
|
|
|
+ })
|
|
|
+ },
|
|
|
+ validateTableHeader(header, importHeader) {
|
|
|
+ let isHeaderOk = true
|
|
|
+ if (header.length !== importHeader.length) return false
|
|
|
+ for (const index in header) {
|
|
|
+ const field = header[index]
|
|
|
+ const importField = importHeader[index]
|
|
|
+ if (field !== importField) {
|
|
|
+ console.log(field, importField)
|
|
|
+ isHeaderOk = false
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return isHeaderOk
|
|
|
+ },
|
|
|
+ validateRequiredField(requiredFields) {
|
|
|
+ const verification = createFieldVerification('发票申请编号、发票类型、发票号码、开票日期、税后金额不能为空')
|
|
|
+ const fields = helper.fields(requiredFields)
|
|
|
+ requiredFields[fields[0]].forEach((_, index) => {
|
|
|
+ if (!helper.values(requiredFields, fields, index).every(value => value && String(value).trim() !== '')) {
|
|
|
+ verification.isValid = false
|
|
|
+ verification.notValidRows.push(index + 1)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return verification
|
|
|
+ },
|
|
|
+ /* 处理不合法的值,提示错误信息,并返回最终的验证状态 **/
|
|
|
+ handleNotValidFields(...validStates) {
|
|
|
+ const messages = {}
|
|
|
+ let isFinalValid = true
|
|
|
+
|
|
|
+ for (const validState of validStates) {
|
|
|
+ const { message, isValid, notValidRows } = validState
|
|
|
+ if (isValid) continue
|
|
|
+ isFinalValid = false
|
|
|
+
|
|
|
+ notValidRows.forEach(row => {
|
|
|
+ if (!messages[row]) messages[row] = []
|
|
|
+ messages[row].push(message)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ isFinalValid,
|
|
|
+ message: () => !isFinalValid && MessageBox({
|
|
|
+ type: 'warning',
|
|
|
+ title: '数据填写错误',
|
|
|
+ dangerouslyUseHTMLString: true,
|
|
|
+ message: createErrorMessage(messages),
|
|
|
+ customClass: 'error-message__wrapper'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /* 校验导入的数据 **/
|
|
|
+ validateFields(tableData = []) {
|
|
|
+ const mapTableFieldToTableData = {}
|
|
|
+ for (const tableItem of tableData) {
|
|
|
+ const propertys = Object.keys(tableItem)
|
|
|
+ for (const property of propertys) {
|
|
|
+ const value = tableItem[property]
|
|
|
+ if (!mapTableFieldToTableData[property]) mapTableFieldToTableData[property] = []
|
|
|
+ mapTableFieldToTableData[property].push(value)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return this.handleNotValidFields(
|
|
|
+ this.validateRequiredField(helper.write(mapTableFieldToTableData, requiredFields))
|
|
|
+ )
|
|
|
+ },
|
|
|
+ mapTemplateItemToTableItem(templateItem) {
|
|
|
+ const tableItem = {}
|
|
|
+ const templatePropertys = Object.keys(templateItem)
|
|
|
+ templatePropertys.forEach(templateProperty => {
|
|
|
+ const tableproperty = getTableProperty(templateProperty)
|
|
|
+ tableItem[tableproperty] = templateItem[templateProperty]
|
|
|
+ })
|
|
|
+ return tableItem
|
|
|
+ },
|
|
|
+ onSuccess({ results: templateItems, header: templateHeader }) {
|
|
|
+ const isHeaderValid = this.validateTableHeader(
|
|
|
+ this.columns.map(({ label }) => label).slice(1),
|
|
|
+ templateHeader
|
|
|
+ )
|
|
|
+ if (!isHeaderValid) {
|
|
|
+ this.$message.warning('表格与导入的表头不一致!')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (templateItems.length === 0) {
|
|
|
+ this.$message.warning('导入的表格没有数据!')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ templateItems.forEach(templateItem => {
|
|
|
+ const tableItem = this.mapTemplateItemToTableItem(templateItem)
|
|
|
+ this.tableData.push(tableItem)
|
|
|
+ })
|
|
|
+ this.validateFields(this.tableData).message()
|
|
|
+ },
|
|
|
+ async onSubmit() {
|
|
|
+ this.loading = true
|
|
|
+ const param = {
|
|
|
+ plan_info:[],
|
|
|
+ plan_id:7,
|
|
|
+ }
|
|
|
+ this.loading = false
|
|
|
+ const { code } = await asyncRequest.planUpdate(param)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.error-message__wrapper{
|
|
|
+ width: 1024px;
|
|
|
+}
|
|
|
+</style>
|