|
@@ -33,6 +33,17 @@
|
|
|
:rules="[{ required: true, message: '结束时间不能为空' }]"
|
|
:rules="[{ required: true, message: '结束时间不能为空' }]"
|
|
|
/>
|
|
/>
|
|
|
</van-cell-group>
|
|
</van-cell-group>
|
|
|
|
|
+ <h4>费用预估</h4>
|
|
|
|
|
+ <van-cell-group class="mt10">
|
|
|
|
|
+ <van-field
|
|
|
|
|
+ label="预估费用"
|
|
|
|
|
+ v-model="state.estimateFee"
|
|
|
|
|
+ placeholder="请选择预约时间和相关信息后自动计算"
|
|
|
|
|
+ readonly
|
|
|
|
|
+ is-link
|
|
|
|
|
+ @click="showCostDetails"
|
|
|
|
|
+ />
|
|
|
|
|
+ </van-cell-group>
|
|
|
<h4>申请明细</h4>
|
|
<h4>申请明细</h4>
|
|
|
<template v-if="state.appointId == 0">
|
|
<template v-if="state.appointId == 0">
|
|
|
<van-cell-group class="mt10" v-if="state.isActiveService">
|
|
<van-cell-group class="mt10" v-if="state.isActiveService">
|
|
@@ -86,6 +97,14 @@
|
|
|
v-model="state.form.userContact"
|
|
v-model="state.form.userContact"
|
|
|
:rules="[{ required: true, message: '联系电话不能为空' }]"
|
|
:rules="[{ required: true, message: '联系电话不能为空' }]"
|
|
|
></van-field>
|
|
></van-field>
|
|
|
|
|
+ <van-field name="assistEnable" label="辅助上机" :rules="[{ required: true, message: '请选择是否辅助上机' }]">
|
|
|
|
|
+ <template #input>
|
|
|
|
|
+ <van-radio-group v-model="state.form.assistEnable" direction="horizontal">
|
|
|
|
|
+ <van-radio style="margin-right: 20px" :name="false">否</van-radio>
|
|
|
|
|
+ <van-radio :name="true">是</van-radio>
|
|
|
|
|
+ </van-radio-group>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </van-field>
|
|
|
<van-field label="备注" placeholder="备注" v-model="state.form.remark" rows="2" autosize type="textarea" maxlength="300" show-word-limit></van-field>
|
|
<van-field label="备注" placeholder="备注" v-model="state.form.remark" rows="2" autosize type="textarea" maxlength="300" show-word-limit></van-field>
|
|
|
</van-cell-group>
|
|
</van-cell-group>
|
|
|
</template>
|
|
</template>
|
|
@@ -134,9 +153,9 @@
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
import { useInstrApi } from '/@/api/instr'
|
|
import { useInstrApi } from '/@/api/instr'
|
|
|
import { useInstDocApi } from '/@/api/instr/document'
|
|
import { useInstDocApi } from '/@/api/instr/document'
|
|
|
- import { defineAsyncComponent, onMounted, reactive, ref } from 'vue'
|
|
|
|
|
|
|
+ import { defineAsyncComponent, onMounted, reactive, ref, watch } from 'vue'
|
|
|
import { formatDate } from '/@/utils/formatTime'
|
|
import { formatDate } from '/@/utils/formatTime'
|
|
|
- import { showNotify } from 'vant'
|
|
|
|
|
|
|
+ import { showNotify, showDialog } from 'vant'
|
|
|
import download from 'downloadjs'
|
|
import download from 'downloadjs'
|
|
|
import { useNoticeApi } from '/@/api/instr/notice'
|
|
import { useNoticeApi } from '/@/api/instr/notice'
|
|
|
import { useProApi } from '/@/api/project'
|
|
import { useProApi } from '/@/api/project'
|
|
@@ -173,6 +192,8 @@
|
|
|
showAppointUser: false,
|
|
showAppointUser: false,
|
|
|
isInstrHead: false,
|
|
isInstrHead: false,
|
|
|
instDetail: {} as any,
|
|
instDetail: {} as any,
|
|
|
|
|
+ estimateFee: '', // 预估费用
|
|
|
|
|
+ costDetails: [] as any[], // 费用明细
|
|
|
form: {
|
|
form: {
|
|
|
instId: 0,
|
|
instId: 0,
|
|
|
instName: '',
|
|
instName: '',
|
|
@@ -188,12 +209,52 @@
|
|
|
userId: 0,
|
|
userId: 0,
|
|
|
nickName: '',
|
|
nickName: '',
|
|
|
projectType: '',
|
|
projectType: '',
|
|
|
- assistEnable: false,
|
|
|
|
|
|
|
+ assistEnable: false, // 是否辅助上机,默认为false(否)
|
|
|
createForm: [],
|
|
createForm: [],
|
|
|
remark: ''
|
|
remark: ''
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+ // 获取预估费用
|
|
|
|
|
+ const getEstimateFee = async () => {
|
|
|
|
|
+ // 必须有开始时间、结束时间和仪器ID才能计算预估费用
|
|
|
|
|
+ if (!state.form.instId || !state.form.startTime || !state.form.endTime) {
|
|
|
|
|
+ state.estimateFee = ''
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 使用原始格式,不进行时间格式转换
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ instId: state.form.instId,
|
|
|
|
|
+ startTime: state.form.startTime,
|
|
|
|
|
+ endTime: state.form.endTime,
|
|
|
|
|
+ projectId: state.form.projectId || 0,
|
|
|
|
|
+ expenseCardId: state.form.expenseCardId || 0,
|
|
|
|
|
+ assistEnable: state.form.assistEnable
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const [err, res]: ToResponse = await to(instApi.getEstimateFee(params))
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ state.estimateFee = '计算失败'
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (res?.code === 200 && res.data) {
|
|
|
|
|
+ // 根据返回格式获取预估费用
|
|
|
|
|
+ const cost = res.data.estimatedCost || res.data
|
|
|
|
|
+ state.estimateFee = `¥${cost}`
|
|
|
|
|
+
|
|
|
|
|
+ // 保存费用明细数据
|
|
|
|
|
+ if (res.data.costDetails && res.data.costDetails.length > 0) {
|
|
|
|
|
+ state.costDetails = res.data.costDetails
|
|
|
|
|
+ } else {
|
|
|
|
|
+ state.costDetails = []
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ state.estimateFee = '无法计算'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 选择课题还是服务
|
|
// 选择课题还是服务
|
|
|
const changeProjectType = () => {
|
|
const changeProjectType = () => {
|
|
|
state.form.serviceId = 0
|
|
state.form.serviceId = 0
|
|
@@ -203,24 +264,28 @@
|
|
|
state.form.expenseCardId = 0
|
|
state.form.expenseCardId = 0
|
|
|
state.form.expenseCardName = ''
|
|
state.form.expenseCardName = ''
|
|
|
fundsList.value = []
|
|
fundsList.value = []
|
|
|
|
|
+ getEstimateFee() // 重新计算预估费用
|
|
|
}
|
|
}
|
|
|
const pickProject = ({ selectedOptions }) => {
|
|
const pickProject = ({ selectedOptions }) => {
|
|
|
state.form.projectId = selectedOptions[0].projectId
|
|
state.form.projectId = selectedOptions[0].projectId
|
|
|
state.form.projectName = selectedOptions[0].projectName
|
|
state.form.projectName = selectedOptions[0].projectName
|
|
|
state.showProject = false
|
|
state.showProject = false
|
|
|
getFundsData()
|
|
getFundsData()
|
|
|
|
|
+ getEstimateFee() // 重新计算预估费用
|
|
|
}
|
|
}
|
|
|
// 选择服务
|
|
// 选择服务
|
|
|
const pickService = ({ selectedOptions }) => {
|
|
const pickService = ({ selectedOptions }) => {
|
|
|
state.form.serviceId = selectedOptions[0].id
|
|
state.form.serviceId = selectedOptions[0].id
|
|
|
state.form.serviceName = selectedOptions[0].name
|
|
state.form.serviceName = selectedOptions[0].name
|
|
|
state.shwoService = false
|
|
state.shwoService = false
|
|
|
|
|
+ getEstimateFee() // 重新计算预估费用
|
|
|
}
|
|
}
|
|
|
// 经费卡选择
|
|
// 经费卡选择
|
|
|
const pickExpenseCard = ({ selectedOptions }) => {
|
|
const pickExpenseCard = ({ selectedOptions }) => {
|
|
|
state.form.expenseCardId = selectedOptions[0].id
|
|
state.form.expenseCardId = selectedOptions[0].id
|
|
|
state.form.expenseCardName = selectedOptions[0].finAccount
|
|
state.form.expenseCardName = selectedOptions[0].finAccount
|
|
|
state.showExpenseCard = false
|
|
state.showExpenseCard = false
|
|
|
|
|
+ getEstimateFee() // 重新计算预估费用
|
|
|
}
|
|
}
|
|
|
const getFundsData = async () => {
|
|
const getFundsData = async () => {
|
|
|
const [err, res]: ToResponse = await to(projApi.getFinanceAccountList({ projId: state.form.projectId }))
|
|
const [err, res]: ToResponse = await to(projApi.getFinanceAccountList({ projId: state.form.projectId }))
|
|
@@ -230,6 +295,7 @@
|
|
|
state.form.expenseCardId = fundsList.value[0][0].id
|
|
state.form.expenseCardId = fundsList.value[0][0].id
|
|
|
state.form.expenseCardName = fundsList.value[0][0].finAccount
|
|
state.form.expenseCardName = fundsList.value[0][0].finAccount
|
|
|
}
|
|
}
|
|
|
|
|
+ getEstimateFee() // 重新计算预估费用
|
|
|
}
|
|
}
|
|
|
// 预约人选择
|
|
// 预约人选择
|
|
|
const pickAppointUser = ({ selectedOptions }) => {
|
|
const pickAppointUser = ({ selectedOptions }) => {
|
|
@@ -245,6 +311,7 @@
|
|
|
state.form.expenseCardName = ''
|
|
state.form.expenseCardName = ''
|
|
|
fundsList.value = []
|
|
fundsList.value = []
|
|
|
getMyProjectInfo(state.form.userId)
|
|
getMyProjectInfo(state.form.userId)
|
|
|
|
|
+ getEstimateFee() // 重新计算预估费用
|
|
|
}
|
|
}
|
|
|
// 选择预约人
|
|
// 选择预约人
|
|
|
const openSelectUser = () => {
|
|
const openSelectUser = () => {
|
|
@@ -303,6 +370,8 @@
|
|
|
state.form.projectId = res?.data.id || null
|
|
state.form.projectId = res?.data.id || null
|
|
|
state.form.projectName = res?.data.pgName || ''
|
|
state.form.projectName = res?.data.pgName || ''
|
|
|
getFundsData()
|
|
getFundsData()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ getEstimateFee() // 重新计算预估费用
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
const getUserList = async () => {
|
|
const getUserList = async () => {
|
|
@@ -325,7 +394,45 @@
|
|
|
path: val,
|
|
path: val,
|
|
|
query: { ...params }
|
|
query: { ...params }
|
|
|
})
|
|
})
|
|
|
|
|
+ // 如果是跳转到日历页面,返回后重新计算预估费用
|
|
|
|
|
+ if (val === '/instr-calendar') {
|
|
|
|
|
+ // 使用setTimeout确保从日历页面返回后再计算
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ if (state.form.startTime && state.form.endTime) {
|
|
|
|
|
+ getEstimateFee()
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 1000)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ // 展示费用明细
|
|
|
|
|
+ const showCostDetails = () => {
|
|
|
|
|
+ if (state.costDetails.length === 0) {
|
|
|
|
|
+ showNotify({
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ message: '暂无费用明细'
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let detailsHtml = '<div class="cost-details-content">'
|
|
|
|
|
+ state.costDetails.forEach((item, index) => {
|
|
|
|
|
+ detailsHtml += `<div class="cost-item">`
|
|
|
|
|
+ detailsHtml += `<div class="cost-item-name">${item.itemName || ''}</div>`
|
|
|
|
|
+ detailsHtml += `<div class="cost-item-amount">¥${item.amount || 0}</div>`
|
|
|
|
|
+ detailsHtml += `</div>`
|
|
|
|
|
+ })
|
|
|
|
|
+ detailsHtml += '</div>'
|
|
|
|
|
+
|
|
|
|
|
+ showDialog({
|
|
|
|
|
+ title: '费用明细',
|
|
|
|
|
+ message: detailsHtml,
|
|
|
|
|
+ className: 'cost-details-dialog',
|
|
|
|
|
+ allowHtml: true,
|
|
|
|
|
+ showConfirmButton: true,
|
|
|
|
|
+ confirmButtonText: '确定'
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const onClickButton = async () => {
|
|
const onClickButton = async () => {
|
|
|
state.loading = true
|
|
state.loading = true
|
|
|
const [errValid] = await to(formRef.value.validate())
|
|
const [errValid] = await to(formRef.value.validate())
|
|
@@ -362,7 +469,33 @@
|
|
|
state.form.startTime = startTime
|
|
state.form.startTime = startTime
|
|
|
state.form.endTime = endTime
|
|
state.form.endTime = endTime
|
|
|
init()
|
|
init()
|
|
|
|
|
+ // 如果有开始时间和结束时间,初始化后计算预估费用
|
|
|
|
|
+ if (startTime && endTime) {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ getEstimateFee()
|
|
|
|
|
+ }, 500) // 延迟执行,确保其他初始化完成
|
|
|
|
|
+ }
|
|
|
})
|
|
})
|
|
|
|
|
+
|
|
|
|
|
+ // 监听开始时间和结束时间变化,重新计算预估费用
|
|
|
|
|
+ watch(
|
|
|
|
|
+ () => [state.form.startTime, state.form.endTime],
|
|
|
|
|
+ () => {
|
|
|
|
|
+ if (state.form.startTime && state.form.endTime) {
|
|
|
|
|
+ getEstimateFee()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ // 监听辅助上机选项变化,重新计算预估费用
|
|
|
|
|
+ watch(
|
|
|
|
|
+ () => state.form.assistEnable,
|
|
|
|
|
+ () => {
|
|
|
|
|
+ if (state.form.startTime && state.form.endTime) {
|
|
|
|
|
+ getEstimateFee()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
@@ -392,3 +525,40 @@
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss">
|
|
|
|
|
+// 费用明细对话框样式
|
|
|
|
|
+.cost-details-dialog {
|
|
|
|
|
+ .van-dialog__content {
|
|
|
|
|
+ max-height: 60vh;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .cost-details-content {
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+
|
|
|
|
|
+ .cost-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ padding: 12px 0;
|
|
|
|
|
+ border-bottom: 1px solid #eee;
|
|
|
|
|
+
|
|
|
|
|
+ &:last-child {
|
|
|
|
|
+ border-bottom: none;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .cost-item-name {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .cost-item-amount {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ color: #f56c6c;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|