<template>
  <a-modal
    v-model="opened"
    :title="title"
    centered
    :maskClosable="false"
    width="80%"
    :footer="null"
    @cancel="cancel"
  >
    <a-spin :spinning="spinning" tip="Loading...">
      <a-card size="small" :bordered="false" class="searchBoxNormal">
        <!-- 搜索条件 -->
        <div ref="tableSearch" class="table-page-search-wrapper">
          <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
            <a-row :gutter="15">
              <a-col :md="6" :sm="24">
                <a-form-item label="时间">
                  <rangeDate id="conFrontModal-rangeDate" ref="rangeDate" :value="creatDate" @change="dateChange" />
                </a-form-item>
              </a-col>
              <a-col :md="4" :sm="24">
                <a-form-item label="业务单号">
                  <a-input id="conFrontModal-bizNo" v-model.trim="queryParam.bizNo" allowClear placeholder="请输入业务单号"/>
                </a-form-item>
              </a-col>
              <a-col :md="4" :sm="24">
                <a-form-item label="借贷类型">
                  <v-select
                    v-model="queryParam.changeType"
                    ref="changeType"
                    id="conFrontModal-changeType"
                    code="VERIFY_ACCOUNT_CHANGE_TYPE"
                    placeholder="请选择状态"
                    allowClear></v-select>
                </a-form-item>
              </a-col>
              <a-col :md="4" :sm="24">
                <a-form-item label="业务类型">
                  <v-select
                    v-model="queryParam.bizType"
                    ref="bizType"
                    id="conFrontModal-bizType"
                    code="VERIFY_ACCOUNT_BIZ_TYPE"
                    placeholder="请选择业务类型"
                    allowClear></v-select>
                </a-form-item>
              </a-col>
              <a-col :md="6" :sm="24">
                <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="conFrontModal-search">查询</a-button>
                <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="conFrontModal-reset">重置</a-button>
                <a-button
                  style="margin-left: 10px"
                  type="primary"
                  v-if="$hasPermissions('B_as_detail_export')"
                  id="conFrontModal-export"
                  class="button-warning"
                  @click="handleExport"
                  :disabled="disabled"
                  :loading="exportLoading"
                >导出</a-button>
              </a-col>
            </a-row>
          </a-form>
        </div>
      </a-card>
      <a-card size="small" :bordered="false" class="conFrontModal-wrap">
        <div class="action-bar">
          列显示
          <a-popover title="勾选显示列" trigger="click">
            <template slot="content">
              <div style="width:150px;">
                <a-checkbox-group v-model="showCols">
                  <a-row>
                    <a-col :span="24" v-for="item in showColsOptions" :key="item.value">
                      <a-checkbox v-show="item.show" :value="item.value">{{ item.label }}</a-checkbox>
                    </a-col>
                  </a-row>
                </a-checkbox-group>
              </div>
            </template>
            <a-button type="link" size="small">
              设置 <a-icon type="setting" />
            </a-button>
          </a-popover>
        </div>
        <!-- 列表 -->
        <s-table
          class="sTable"
          ref="table"
          size="small"
          :rowKey="(record) => record.id"
          :columns="columns"
          :data="loadData"
          :showPagination="false"
          :defaultLoadData="false"
          bordered>
        </s-table>
        <div class="conFrontModal-info" v-if="detailData">
          备注：{{ detailData.remarks }}
        </div>
        <div class="conFrontModal-flex" v-if="detailData">
          <div class="conFrontModal-subTitle">
            <div><span>公司名称：</span> 东莞市箭冠汽车配件制造有限公司</div>
            <div><span>签名：</span>{{ detailData.signName }}</div>
            <div><span>盖章</span></div>
          </div>
          <div class="conFrontModal-subTitle">
            <div><span>公司名称：</span>{{ dealear.dealerAlias }}</div>
            <div><span>签名：</span></div>
            <div><span>盖章</span></div>
          </div>
        </div>
        <div class="conFrontModal-footer-bar" v-if="detailData">
          <a-button @click="cancel" style="margin-right: 15px" id="conFrontModal-btn-back">取消</a-button>
          <a-button type="primary" v-if="orderType==1" :loading="confirmLoading" @click="handleSubmit(0)" id="conFrontModal-btn-submit">对单</a-button>
          <a-button
            type="primary"
            class="button-success"
            v-if="orderType==1"
            :loading="confirmLoading"
            @click="handleSubmit(1)"
            id="conFrontModal-btn-submit-sync">对单并同步</a-button>
        </div>
      </a-card>
    </a-spin>
  </a-modal>
</template>

<script>
import { commonMixin } from '@/utils/mixin'
import XLSX from 'xlsx-js-style'
import moment from 'moment'
import { STable, VSelect } from '@/components'
import rangeDate from '@/views/common/rangeDate.vue'
import {
  verifyAcountBillDetailQueryList,
  verifyAcountBillDetail,
  verifyAcountBillConfirmCheck,
  verifyAcountBillConfirm
} from '@/api/verifyAccount'

export default {
  name: 'ConFrontModal',
  mixins: [commonMixin],
  components: { STable, VSelect, rangeDate },
  props: {
    show: [Boolean]
  },
  data () {
    return {
      opened: this.show,
      spinning: false,
      disabled: false,
      confirmLoading: false,
      title: '',
      exportLoading: false,
      queryParam: {
        beginDate: '',
        endDate: '',
        bizNo: '',
        changeType: undefined,
        bizType: undefined
      },
      creatDate: [],
      // 加载数据方法 必须为 Promise 对象
      loadData: parameter => {
        this.disabled = true
        this.spinning = true
        const params = Object.assign(parameter, this.queryParam)
        params.verifyAccountBillSn = this.verifyAccountBillSn
        const beginFlag = (!!params.beginDate && !!params.endDate)
        const a = !params.bizNo && !params.changeType && !params.bizType
        const b = !params.beginDate && !params.endDate
        params.beginFlag = beginFlag && a || a && b ? 1 : 0
        return verifyAcountBillDetailQueryList(params).then(res => {
          let data
          if (res.status == 200) {
            data = res.data
            const no = 0
            let prevTotalAmount = 0
            for (var i = 0; i < data.length; i++) {
              data[i].no = no + i + 1
              if (data[i].bizDate) {
                const dates = data[i].bizDate.split('-')
                data[i].year = dates[0]
                data[i].month = dates[1]
                data[i].day = dates[2].split(' ')[0]
              }
              if (data[i].bizAmount) {
                // 正为借方， 负数为贷方
                if (data[i].bizAmount > 0) {
                  data[i].debitAmount = Number(data[i].bizAmount).toFixed(2)
                } else {
                  data[i].creditorAmount = Number(data[i].bizAmount * -1).toFixed(2)
                }
                data[i].totalAmount = Number(Number(prevTotalAmount || 0) + Number(data[i].debitAmount || 0) - Number(data[i].creditorAmount || 0)).toFixed(2)
                prevTotalAmount = data[i].totalAmount
              }
            }
            this.total = data.length || 0 + 1
            this.disabled = false
          }
          this.spinning = false
          return data
        })
      },
      total: 0, // 合计
      detailData: null,
      dealear: null,
      verifyAccountBillSn: undefined,
      orderType: 0,
      showCols: []
    }
  },
  computed: {
    showColsOptions () {
      return [
        { label: '序号', value: 'no', show: false },
        { label: '年', value: 'year', show: false },
        { label: '月', value: 'month', show: false },
        { label: '日', value: 'day', show: false },
        { label: '业务单号', value: 'bizNo', show: false },
        { label: '业务类型', value: 'bizTypeDictValue', show: false },
        { label: '费用/调拨类型', value: 'expenseAllocateType', show: true },
        { label: '摘要', value: 'digestInfo', show: true },
        { label: '客诉索赔编码', value: 'productCode', show: true },
        { label: '借方金额', value: 'debitAmount', show: false },
        { label: '贷方金额', value: 'creditorAmount', show: false },
        { label: '余额', value: 'totalAmount', show: true },
        { label: '备注', value: 'remarks', show: true }
      ]
    },
    columns () {
      const renderContent = (value, row, index) => {
        const obj = {
          children: value || value === 0 ? value : '--',
          attrs: {}
        }
        return obj
      }
      return [
        {
          title: '箭冠汽配 应收账款明细表',
          children: [
            {
              title: '营业执照名称',
              children: [
                {
                  title: '财务编码',
                  children: [
                    { title: '序号',
                      dataIndex: 'no',
                      width: '4%',
                      align: 'center',
                      customRender: renderContent
                    },
                    { title: '年', dataIndex: 'year', width: '4%', align: 'center', customRender: renderContent },
                    { title: '月', dataIndex: 'month', width: '4%', align: 'center', customRender: renderContent },
                    { title: '日', dataIndex: 'day', width: '4%', align: 'center', customRender: renderContent },
                    { title: '业务单号', dataIndex: 'bizNo', width: '8%', align: 'center', customRender: renderContent }
                  ].filter(item => this.showCols.includes(item.dataIndex))
                }
              ]
            },
            {
              title: this.dealear ? this.dealear.dealerAlias : '--',
              children: [
                {
                  title: this.dealear ? this.dealear.kdMidCustomerFnumber : '--',
                  children: [
                    { title: '业务类型', dataIndex: 'bizTypeDictValue', width: '8%', align: 'center', customRender: renderContent },
                    { title: '费用/调拨类型',
                      dataIndex: 'expenseAllocateType',
                      width: '8%',
                      align: 'center',
                      customRender: renderContent
                    }
                  ].filter(item => this.showCols.includes(item.dataIndex))
                }
              ]
            },
            {
              title: '系统名称',
              children: [
                {
                  title: '',
                  children: [
                    { title: '摘要', dataIndex: 'digestInfo', width: '10%', align: 'center', customRender: renderContent },
                    { title: '客诉索赔编码', dataIndex: 'productCode', width: '8%', align: 'center', customRender: renderContent },
                    { title: '借方', dataIndex: 'debitAmount', width: '6%', align: 'right', customRender: renderContent }
                  ].filter(item => this.showCols.includes(item.dataIndex))
                }
              ]
            },
            {
              title: this.dealear ? this.dealear.dealerName : '--',
              children: [
                {
                  title: '',
                  children: [
                    { title: '贷方', dataIndex: 'creditorAmount', width: '6%', align: 'right', customRender: renderContent },
                    { title: '余额', dataIndex: 'totalAmount', width: '6%', align: 'right', customRender: renderContent },
                    { title: '备注', dataIndex: 'remarks', width: '15%', align: 'center', customRender: renderContent }
                  ].filter(item => this.showCols.includes(item.dataIndex))
                }
              ]
            }
          ]
        }
      ]
    }
  },
  methods: {
    //  创建时间  change
    dateChange (date) {
      this.queryParam.beginDate = date[0] ? date[0] : ''
      this.queryParam.endDate = date[1] ? date[1] : ''
    },
    //  重置
    resetSearchForm () {
      this.creatDate = []
      if (this.$refs.rangeDate) {
        this.$refs.rangeDate.resetDate(this.creatDate)
      }
      this.queryParam.beginDate = ''
      this.queryParam.endDate = ''
      this.queryParam.bizNo = ''
      this.queryParam.changeType = undefined
      this.queryParam.bizType = undefined
      this.$refs.table.refresh(true)
    },
    //  详情
    getDetail () {
      this.spinning = true
      verifyAcountBillDetail({ sn: this.verifyAccountBillSn }).then(res => {
        this.detailData = res.data
        this.spinning = false
        this.resetSearchForm()
      })
    },
    // 关闭弹框
    cancel () {
      this.opened = false
      this.$emit('cancel')
    },
    appendSplitMergedRow (ws, firstValue, secondValue) {
      const colsLen = this.showCols.length
      const s = Math.floor((colsLen % 2 == 0) ? (colsLen / 2) : ((colsLen - 1) / 2))
      // 1. 获取当前数据范围
      const range = XLSX.utils.decode_range(ws['!ref'])
      const newRowNum = range.e.r + 1

      // 2. 填充基础数据（仅设置有效单元格）
      ws[XLSX.utils.encode_cell({ r: newRowNum, c: 0 })] = { v: firstValue, t: 's' } // 前7列合并值
      ws[XLSX.utils.encode_cell({ r: newRowNum, c: s + 1 })] = { v: secondValue, t: 's' } // 后6列合并值

      // 3. 设置合并区域
      if (!ws['!merges']) ws['!merges'] = []
      // 前7列合并（0-6列）
      ws['!merges'].push(XLSX.utils.decode_range(
        `${XLSX.utils.encode_cell({ r: newRowNum, c: 0 })}:${XLSX.utils.encode_cell({ r: newRowNum, c: s })}`
      ))
      // 后6列合并（7-12列）
      ws['!merges'].push(XLSX.utils.decode_range(
        `${XLSX.utils.encode_cell({ r: newRowNum, c: s + 1 })}:${XLSX.utils.encode_cell({ r: newRowNum, c: colsLen - 1 })}`
      ))

      // 4. 更新数据范围
      range.e.r = newRowNum
      ws['!ref'] = XLSX.utils.encode_range(range)
      return ws
    },
    // 导出表格excel，dom 表格对象，title 导出表格名称
    exportTable (dom, title) {
      var ws = XLSX.utils.table_to_sheet(dom)
      // console.log(ws)

      // 4. 设置列宽
      const colsLen = this.showCols.length
      ws['!cols'] = Array(colsLen).fill().map((item, index) => ({ wch: index < 4 ? 6 : 20 }))

      // 追加备注
      const range = XLSX.utils.decode_range(ws['!ref'])
      const newRowNum = range.e.r + 1

      // 填充数据（首列填值，其余留空）
      const mergedValue = '备注：' + this.detailData.remarks
      for (let col = 0; col < colsLen; col++) {
        const cellRef = XLSX.utils.encode_cell({ r: newRowNum, c: col })
        ws[cellRef] = { v: col === 0 ? mergedValue : '', t: 's' }
      }

      // 设置全列合并（0-12列）
      if (!ws['!merges']) ws['!merges'] = []
      ws['!merges'].push(XLSX.utils.decode_range(
        `${XLSX.utils.encode_cell({ r: newRowNum, c: 0 })}:${XLSX.utils.encode_cell({ r: newRowNum, c: colsLen - 1 })}`
      ))

      // 4. 更新数据范围
      range.e.r = newRowNum
      ws['!ref'] = XLSX.utils.encode_range(range)
      ws['!rows'][0] = { hpt: 30 }
      ws['!rows'][newRowNum] = { hpt: 30 }

      // 追加表尾
      const newWs = this.appendSplitMergedRow(ws, '公司名称：东莞市箭冠汽车配件制造有限公司', '公司名称：' + (this.dealear.dealerAlias || ''))
      const newWs1 = this.appendSplitMergedRow(newWs, '签名：' + (this.detailData.signName || ''), '签名：')
      const newWs2 = this.appendSplitMergedRow(newWs1, '盖章：', '盖章：')
      // 设置单元格样式
      Object.keys(newWs2).forEach(cell => {
        if (!cell.startsWith('!')) {
          const rowNum = parseInt(cell.match(/\d+/)[0])
          newWs2[cell].s = cell === 'A1' ? {
            font: { bold: true, color: { rgb: '000000' } },
            alignment: { horizontal: 'center', vertical: 'center' }
          } : rowNum === 4 ? {
            font: { bold: true },
            fill: { fgColor: { rgb: 'ffdd8d' } },
            alignment: { horizontal: rowNum < newRowNum + 1 ? 'center' : 'left', vertical: 'center' }
          } : {
            alignment: { horizontal: rowNum < newRowNum + 1 ? 'center' : 'left', vertical: 'center' }
          }
        }
      })
      // 创建工作簿并导出
      var wb = XLSX.utils.book_new()
      // 5. 写入文件
      XLSX.utils.book_append_sheet(wb, newWs2, 'Sheet1')
      const timeStr = moment().format('YYYYMMDDHHmmss')
      XLSX.writeFile(wb, title + '-' + timeStr + '.xlsx')
    },
    //  点击导出
    handleExport () {
      const excelTitle = '（' + this.detailData.dealerName + '）应收账款明细表'
      this.exportTable(this.$refs.table.$el.querySelector('table'), excelTitle)
    },
    // 对单， type 0 对单 1 对单且同步
    async handleSubmit (type) {
      const _this = this
      this.confirmLoading = true
      const ret = await verifyAcountBillConfirmCheck({ sn: this.verifyAccountBillSn })
      this.confirmLoading = false
      console.log(ret)
      const snList = ret.data.length ? ret.data.map(item => item.bizNo) : []
      if (snList.length) {
        this.$info({
          title: '提示（' + _this.dealear.dealerName + '）',
          content: <div style="font-size:14px;">{snList.toString()}不可对单</div>,
          centered: true,
          closable: true,
          onOk () {
          }
        })
      } else {
        this.confirmLoading = true
        verifyAcountBillConfirm({ verifyAccountBillSn: this.verifyAccountBillSn, syncFlag: type }).then(res => {
          this.confirmLoading = false
          this.$message.success(type == 0 ? '对单成功' : '对单同步成功')
          this.$emit('confirm')
          this.cancel()
        })
      }
    },
    // 初始化
    async pageInit (row, dealear, type) {
      // console.log(row, dealear, type)
      this.orderType = type
      this.verifyAccountBillSn = row.verifyAccountBillSn
      this.dealear = dealear
      this.title = type ? '对单' : '单据详情' + `（对账单号：${row.verifyAccountBillNo} 客户名称：${row.dealerName}）`
      this.getDetail()
    }
  },
  watch: {
    show (newValue, oldValue) {
      this.opened = newValue
      if (newValue) {
        this.showCols = ['no', 'year', 'month', 'day', 'bizNo', 'bizTypeDictValue', 'expenseAllocateType', 'digestInfo', 'productCode', 'debitAmount', 'creditorAmount', 'totalAmount', 'remarks']
      }
    }
  }
}
</script>
<style lang="less">
  .conFrontModal-title{
    font-size: 16px;
    font-weight: bold;
    text-align: center;
    margin-bottom: 10px;
  }
  .action-bar{
    text-align: right;
  }
  .conFrontModal-flex{
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
  }
  .conFrontModal-subTitle{
    width: 50%;
    padding: 5px;
    > span{
      display: block;
      font-size: 14px;
      width: 100px;
    }
    > div{
      display: block;
      font-size: 14px;
      width: 100%;
      word-break: break-all;
      margin: 5px 0;
    }
  }
  .conFrontModal-info{
    font-size: 14px;
    padding: 15px 5px 10px;
    line-height: 20px;
    color: #333;
  }
  .conFrontModal-footer-bar{
    text-align: center;
    padding: 30px 0 20px;
  }
</style>
