<!--
 * @Author: wanglj wanglijie@dashoo.cn
 * @Date: 2025-03-24 09:17:15
 * @LastEditors: wanglj wanglijie@dashoo.cn
 * @LastEditTime: 2025-04-14 09:30:11
 * @FilePath: \labsop_h5\src\view\instr\detail.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div class="entry-container">
    <van-form ref="formRef" required="auto" label-width="100">
      <h4>项目信息</h4>
      <van-cell-group>
        <van-field v-model="state.form.projectName" label="项目名称" readonly />
        <van-field v-model="state.form.projectSource" label="项目来源" readonly />
        <van-field v-model="state.form.projectIncharge" label="项目负责人" readonly />
        <van-field v-model="state.form.deptName" label="所属科室" readonly />
        <van-field v-model="state.form.subjName" label="费用科目" readonly />
        <van-field v-model="state.form.subSubjName" label="费用类型" readonly />
        <van-field v-model="showAmount" label="入账金额" readonly />
        <van-field v-model="showBalanceAmount" label="可用金额" readonly />
        <van-field v-model="state.form.purpose" label="事项" :rules="[{ required: true, message: '请输入事项' }]" />
      </van-cell-group>
      <h4>报销经费</h4>
      <van-cell-group>
        <van-field
          v-model="state.form.expendTime"
          label="支出日期"
          readonly
          is-link
          @click="openExpandTimePicker"
          :rules="[{ required: true, message: '请选择支出日期' }]"
        />
        <van-field v-model="state.form.handle" label="申请人" />
        <van-field v-model="state.form.expend" label="出纳" />
        <van-field v-model.number="state.form.amount" type="number" label="支出金额">
          <template #extra>元</template>
        </van-field>
      </van-cell-group>
      <h4>发票信息</h4>
      <van-cell-group v-for="(item, index) in state.form.invoice" :key="index" :class="{ mt10: index != 0 }">
        <van-field v-model="item.invoiceNo" label="发票号码" :rules="[{ required: true, message: '请输入发票号码' }]" />
        <van-field v-model.number="item.amount" type="number" label="金额" :rules="[{ required: true, message: '请输入金额' }]" />
        <van-field
          v-model="item.invoiceBy"
          label="开票日期"
          readonly
          is-link
          @click="openInvoiceByPicker(item, index)"
          :rules="[{ required: true, message: '请选择开票日期' }]"
        />
        <div class="file-card">
          <van-uploader v-model="item.fileList" :after-read="afterRead" preview-size="60" :preview-full-image="false" />
        </div>
        <van-cell v-if="index > 0" center>
          <template #default>
            <van-button class="w100" size="small" plain round type="danger" @click="deleteInvoice(index)">删除</van-button>
          </template>
        </van-cell>
      </van-cell-group>
      <van-button class="w100 mt10 mb10" size="small" plain round icon="plus" type="primary" @click="addInvoice"> 添加发票 </van-button>
      <h4>支付信息</h4>
      <van-cell-group v-for="(item, index) in state.form.payment" :key="index" :class="{ mt10: index != 0 }">
        <van-field v-model="item.payType" label="支付方式" readonly is-link @click="openPicker(item, index)">
          <template #input>
            <template v-if="item.payType == '10'">现金</template>
            <template v-else-if="item.payType == '20'">银行转账</template>
            <template v-else-if="item.payType == '30'">国库集中支付</template>
          </template>
        </van-field>
        <van-field v-model="item.receiver" label="收款人/单位" />
        <van-field v-model="item.receiverType" label="个人/单位类型" :rules="[{ required: true, message: '请输入个人/单位类型' }]">
          <template #input>
            <van-radio-group v-model="item.receiverType" direction="horizontal">
              <van-radio v-for="(item, index) in receiverTypeOptions" :key="index" :name="item.dictValue">{{ item.dictLabel }}</van-radio>
            </van-radio-group>
          </template>
        </van-field>
        <van-field v-model.number="item.amount" type="number" label="金额" :rules="[{ required: true, message: '请输入金额' }]" />
        <!-- <van-field v-model="item.purpose" label="用途" :rules="[{ required: true, message: '请输入用途' }]" />
        <van-field v-model="item.bankName" label="具体开户行" /> -->
        <van-cell v-if="index > 0" center>
          <template #default>
            <van-button class="w100" size="small" plain round type="danger" @click="deletePayment(index)">删除</van-button>
          </template>
        </van-cell>
      </van-cell-group>
      <van-button class="w100 mt10 mb10" size="small" plain round icon="plus" type="primary" @click="addPayment">添加支付信息</van-button>
      <h4>附件信息</h4>
      <div class="file-card">
        <van-uploader v-model="state.form.fileList" accept="image/*,.pdf"  :after-read="afterRead" multiple preview-size="60" :preview-full-image="false" />
      </div>
    </van-form>
    <!-- 支出日期选择 -->
    <van-popup v-model:show="showExpandTimePicker" destroy-on-close position="bottom">
      <van-date-picker v-model="state.expendTime" title="选择日期" @confirm="onExpandTimeConfirm" @cancel="showExpandTimePicker = false" />
    </van-popup>
    <!-- 支付方式选择 -->
    <van-popup v-model:show="showPicker" destroy-on-close position="bottom">
      <van-picker :columns="columns" :model-value="state.pickerPayment" @confirm="onConfirm" @cancel="showPicker = false" />
    </van-popup>
    <!-- 开票日期选择 -->
    <van-popup v-model:show="showPickerInvoice" destroy-on-close position="bottom">
      <van-date-picker v-model="state.invoiceBy" title="选择日期" @confirm="onPaymentConfirm" @cancel="showPickerInvoice = false" />
    </van-popup>
  </div>
  <van-action-bar placeholder>
    <van-action-bar-icon icon="wap-home-o" text="首页" @click="onRouterPush('/home')" />
    <van-action-bar-icon icon="info-o" text="报销提醒" @click="onRouterPush('/fund/reimbursement-remind')" />
    <van-action-bar-button class="w100" type="primary" text="提交" @click="onClickButton" />
  </van-action-bar>
</template>

<script lang="ts" setup>
  import to from 'await-to-js'
  import { useRoute, useRouter } from 'vue-router'
  import { computed, onMounted, reactive, ref } from 'vue'
  import { formatDate } from '/@/utils/formatTime'
  import { showConfirmDialog, showNotify } from 'vant'
  import { useUserInfo } from '/@/stores/userInfo'
  import { storeToRefs } from 'pinia'
  import instAppoint from '/@/api/instr/instAppoint'
  import { useConfigApi } from '/@/api/system/config'
  import { useFundApi } from '/@/api/fund'
  import { useDictApi } from '/@/api/system/dict'
  import { getDictLabel, formatAmount, formatAmountYuan, formatInteger } from '/@/utils/other'
  import { useClaimApi } from '/@/api/fund/claim'
  import { useExpenseRemindApi } from '/@/api/fund/reimbursement-remind'
  import { handleUpload } from '/@/utils/upload'
  import { useExpenseApi } from '/@/api/base/expense'
  import { useFundCardApi } from '/@/api/fund/card'
  import { useBaseReimburseApi } from '/@/api/fund/reimburse'
  import { useLoginApi } from '/@/api/login'
  import { Local, Session } from '/@/utils/storage'
  const storesUseUserInfo = useUserInfo()
  const { userInfos, openId, unionId } = storeToRefs(storesUseUserInfo)
  const route = useRoute()
  const router = useRouter()
  const expenseRemindApi = useExpenseRemindApi()
  const fundApi = useFundApi()
  const loginApi = useLoginApi()
  const dictApi = useDictApi()
  const expenseApi = useExpenseApi()
  const configApi = useConfigApi()
  const fundCardApi = useFundCardApi()
  const baseReimburseApi = useBaseReimburseApi()
  const formRef = ref()
  const paymentReceivedTypeOptions = ref<RowDicDataType[]>([])
  const receiverTypeOptions = ref<RowDicDataType[]>([])
  const showPicker = ref(false)
  const columns = [
    {
      text: '现金',
      value: '10'
    },
    {
      text: '银行转账',
      value: '20'
    },
    {
      text: '国库集中支付',
      value: '30'
    }
  ]
  const showPickerInvoice = ref(false)
  const showExpandTimePicker = ref(false)
  const state = reactive({
    loading: false,
    isActiveService: false,
    showProject: false,
    shwoService: false,
    showExpenseCard: false,
    showAppointUser: false,
    isInstrHead: false,
    fundDetail: {} as any,
    detail: [] as any,
    form: {
      id: 0,
      orderNo: '',
      price: 0,
      buyerName: '',
      createdTime: '',
      status: '',
      fileList: [],
      amount: 0,
      noticeId: null,
      projectType: '',
      allotId: null,
      handle: '', //经办人
      projectId: 0, //项目Id
      projectIncharge: '', //项目负责人
      projectCode: '',
      projectName: '', //项目名称
      projectSource: '',
      deptName: '',
      startDate: '',
      endDate: '',
      purpose: '', //事项
      detail: [],
      invoice: [
        {
          fileList: [],
          fileName: '',
          fileUrl: '',
          invoiceNo: '',
          amount: null,
          invoiceBy: '',
          invoiceType: ''
        }
      ],
      payment: [
        {
          payType: '10',
          receiver: '',
          receiverType: '',
          amount: '',
          purpose: '',
          bankName: ''
        }
      ],
      deptId: null,
      subjCode: '',
      subjName: '',
      subSubjCode: '',
      subSubjName: '',
      expendTime: '',
      expend: ''
    },
    pickerPayment: [],
    pickerIndex: -1,
    invoiceBy: [],
    pickerPaymentIndex: -1,
    expendTime: []
  })
  const costSourceList = ref<RowDicDataType[]>([])
  const expenseSubjectList = ref<RowDicDataType[]>([])
  const subList = ref([])
  const subChildrenList = ref<any>([])
  const sysParamsConfig = ref()
  const showAmount = ref(0) //根据项目和费用类型查询入账和剩余入账
  const showBalanceAmount = ref(0) //根据项目和费用类型查询入账和剩余入账
  const getDict = async () => {
    await Promise.all([dictApi.getDictDataByType('PaymentReceivedType'), fundApi.getAllFirstSubj()]).then(([type, parList]) => {
      paymentReceivedTypeOptions.value = type?.data?.values || []
      state.detail =
        parList?.data.map((item: any) => ({
          ...item,
          amount: 0
        })) || []
    })
    await Promise.all([
      dictApi.getDictDataByType('sci_cost_source'),
      expenseApi.GetListNoPage(),
      fundApi.getAllFirstSubj(),
      configApi.getEntityMapByKeys({ configKeys: ['sci_fund_expense_notice_business_code', 'sci_fund_expense_notice_material_code'] }), // 获取系统参数
      dictApi.getDictDataByType('sci_receiver_type')
    ]).then(([source, subj, sub, sysParams, recevied]) => {
      costSourceList.value = source.data?.values
      expenseSubjectList.value = subj?.data?.list

      subList.value = sub?.data
      sysParamsConfig.value = sysParams?.data
      // 费用科目
      const find = subList.value.find((item: any) => item.subjCode == sysParamsConfig.value.sci_fund_expense_notice_business_code)
      subChildrenList.value = find?.children
      state.form.subjCode = find?.subjCode
      state.form.subjName = find?.subjName
      // 二级费用科目
      const subFind = subChildrenList.value.find((item: any) => item.subjCode == sysParamsConfig.value.sci_fund_expense_notice_material_code)
      state.form.subSubjCode = subFind?.subjCode
      state.form.subSubjName = subFind?.subjName
      receiverTypeOptions.value = recevied?.data?.values || []
    })
  }
  // 获取入账信息
  const getAmountInfo = async () => {
    if (!state.form.projectId || !state.form.subjCode) return
    const params = {
      projectId: state.form.projectId,
      projectType: state.form.projectType,
      subjCode: state.form.subjCode
    }
    showAmount.value = 0
    showBalanceAmount.value = 0
    const [err, res]: ToResponse = await to(fundCardApi.getSubjAmount(params))
    if (err) return
    showAmount.value = res?.data?.amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
    showBalanceAmount.value = res?.data?.balanceAmount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  }
  const getFundDetail = async (id: number) => {
    const [err, res]: ToResponse = await to(expenseRemindApi.getDetails({ id }))
    if (err) return
    const row = res.data
    state.form = {
      ...state.form,
      ...row
    }
    state.form.noticeId = row.id
    state.form.amount = row.price
    state.form.deptName = row.projectDeptName
    state.form.handle = userInfos.value.nickName
  }
  // 获取上传附件信息
  const getUploadFileList = async () => {
    if (!state.form.subjCode) {
      state.form.fileList = []
      return
    }
    const find = subList.value.find((item: any) => item.subjCode == state.form.subSubjCode)
    const subjId = find?.id
    const [err, res]: ToResponse = await to(baseReimburseApi.getList({ subjId: subjId }))
    if (err) return
    const arr = res?.data?.list || []
    state.form.fileList = arr.map((item: any) => {
      return {
        fileName: '',
        fileUrl: '',
        fileList: [],
        required: item.isRequired === '10',
        fileType: item.fileName,
        accept: item.fileType,
        fileTempUrl: item.fileTempUrl
      }
    })
  }
  const onRouterPush = (val: string, params?: any) => {
    router.push({
      path: val,
      query: { ...params }
    })
  }
  const afterRead = async (files: any) => {
    if (files.length) {
      for (const file of files) {
        file.status = 'uploading'
        const [err, res]: ToResponse = await to(handleUpload(file.file))
        if (err) {
          file.status = 'failed'
          return
        }
        file.status = 'success'
        file.url = res
        file.fileName = file.file.name
        file.fileUrl = res
        file.fileSize = file.file.size
        file.invoiceType = file.file.type
      }
    } else {
      const file = files
      file.status = 'uploading'
      const [err, res]: ToResponse = await to(handleUpload(file.file))
      if (err) {
        file.status = 'failed'
        return
      }
      file.status = 'success'
      file.url = res
      file.fileName = file.file.name
      file.fileUrl = res
      file.fileSize = file.file.size
      file.invoiceType = file.file.type
    }
  }
  const addInvoice = () => {
    state.form.invoice.push({
      fileList: [],
      fileName: '',
      fileUrl: '',
      invoiceNo: '',
      amount: null,
      invoiceBy: '',
      invoiceType: ''
    })
  }
  const deleteInvoice = (idx: number) => {
    showConfirmDialog({
      title: '提示',
      message: '确认删除？'
    })
      .then(() => {
        state.form.invoice.splice(idx, 1)
      })
      .catch(() => {
        // on cancel
      })
  }
  const addPayment = () => {
    state.form.payment.push({
      payType: '10',
      receiver: '',
      receiverType: '',
      amount: '',
      purpose: '',
      bankName: ''
    })
  }
  const deletePayment = (idx: number) => {
    showConfirmDialog({
      title: '提示',
      message: '确认删除？'
    })
      .then(() => {
        state.form.payment.splice(idx, 1)
      })
      .catch(() => {
        // on cancel
      })
  }
  const openExpandTimePicker = () => {
    const now = new Date()
    state.expendTime = [formatDate(now, 'YYYY'), formatDate(now, 'mm'), formatDate(now, 'dd')]
    showExpandTimePicker.value = true
  }
  const onExpandTimeConfirm = ({ selectedValues }) => {
    state.form.expendTime = selectedValues.join('-')
    showExpandTimePicker.value = false
  }
  const openInvoiceByPicker = (item: any, idx: number) => {
    const now = new Date()
    state.invoiceBy = item.invoiceBy ? item.invoiceBy.split('-') : [formatDate(now, 'YYYY'), formatDate(now, 'mm'), formatDate(now, 'dd')]
    showPickerInvoice.value = true
    state.pickerPaymentIndex = idx
  }
  const onPaymentConfirm = ({ selectedValues }) => {
    state.form.invoice[state.pickerPaymentIndex].invoiceBy = selectedValues.join('-')
    showPickerInvoice.value = false
  }
  const openPicker = (item: any, idx: number) => {
    state.pickerPayment = [item.payType]
    state.pickerIndex = idx
    showPicker.value = true
  }
  const onConfirm = ({ selectedValues }) => {
    state.form.payment[state.pickerIndex].payType = selectedValues[0]
    showPicker.value = false
  }
  const onClickButton = async () => {
    state.loading = true
    if (state.form.invoice.length == 0) {
      showNotify({
        type: 'warning',
        message: '发票信息不能为空'
      })
      return
    }
    if (state.form.payment.length == 0) {
      showNotify({
        type: 'warning',
        message: '支付信息不能为空'
      })
      return
    }
    const [errValid] = await to(formRef.value.validate())
    if (errValid) {
      state.loading = false
      return
    }
    const params = JSON.parse(JSON.stringify(state.form))
    params.fileList = params.fileList.map((item: any) => {
      return {
        fileName: item.fileName,
        fileSize: item.fileSize,
        invoiceType: item.invoiceType,
        fileUrl: item.fileUrl
      }
    })
    params.fileUrl = JSON.stringify(params.fileList)
    params.invoice = params.invoice.map((item: any) => {
      return {
        amount: item.amount,
        invoiceBy: item.invoiceBy,
        invoiceNo: item.invoiceNo,
        fileName: item.fileList[0].fileName,
        fileUrl: item.fileList[0].url,
        invoiceType: item.fileList[0].invoiceType
      }
    })
    const [err]: ToResponse = await to(expenseRemindApi.create(params))
    state.loading = false
    if (err) return
    showNotify({
      type: 'success',
      message: '操作成功'
    })
    router.push({
      path: '/fund/reimbursement-remind'
    })
  }
  onMounted(async () => {
    // 进行openId登录
    const code: string = route.query.code ? route.query.code.toString() : ''
    console.log('11111111111111111111111')
    let param = {
      code: code,
      unionId: unionId.value,
      user_name: userInfos.value?.userName,
      tenant: Local.get('Tenant'),
    }

    if (code) {
      console.log('2222222222222222222222')
      const [err, res]: ToResponse = await to(loginApi.weChatLogin(param))
      if (err) {
        // 跳转到登录页面
        Local.remove('token')
        router.push('/login')
        return
      }
      // 存储 token 到浏览器缓存
      Local.set('token', res?.data?.token)
    }

    const id = route.query.id ? +route.query.id : 0
    await getDict()
    await getFundDetail(id)
    getAmountInfo()
  })
</script>

<style lang="scss" scoped>
  .entry-container {
    flex: 1;
    padding: 0 10px 10px;
    background-color: #f9f9f9;
    overflow-y: auto;
    h4 {
      height: 38px;
      line-height: 38px;
      display: flex;
      align-items: center;
      span {
        font-weight: normal;
        margin-left: auto;
      }
      &::before {
        display: inline-block;
        content: '';
        width: 3px;
        height: 18px;
        background-color: #1c9bfd;
        margin-right: 4px;
        vertical-align: middle;
      }
      .van-button {
        margin-left: auto;
      }
    }
    .file-card {
      background: #fff;
      padding: 10px 10px 0;
    }
  }
</style>
