|
|
@@ -231,140 +231,15 @@
|
|
|
<b>¥{{ schedulePaid(sch).arrears }}</b>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <article
|
|
|
- v-for="(tr, tIdx) in sch.transfers || []"
|
|
|
- :key="tr.id || `${pIdx}-${sIdx}-${tIdx}`"
|
|
|
- class="protocol-sample-pay__transfer"
|
|
|
- >
|
|
|
- <header class="protocol-sample-pay__transfer-title">
|
|
|
- <strong>转账 {{ tIdx + 1 }}</strong>
|
|
|
- <van-tag class="market-tag" :type="payStatusTone(tr.payStatus)" round>
|
|
|
- {{ payStatusLabel(tr.payStatus) }}
|
|
|
- </van-tag>
|
|
|
- </header>
|
|
|
- <div class="market-form-fields">
|
|
|
- <div class="market-form-field">
|
|
|
- <label>转账方式</label>
|
|
|
- <div
|
|
|
- class="market-form-field__control"
|
|
|
- @click="!disabled && canEditTransfer(sch, tr) && openTransferTypeSheet(pIdx, sIdx, tIdx)"
|
|
|
- >
|
|
|
- <van-field
|
|
|
- :model-value="transferTypeLabel(tr.transferType)"
|
|
|
- is-link
|
|
|
- readonly
|
|
|
- placeholder="请选择"
|
|
|
- :disabled="disabled || !canEditTransfer(sch, tr)"
|
|
|
- :border="false"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="market-form-field">
|
|
|
- <label>转账金额</label>
|
|
|
- <van-field
|
|
|
- :model-value="tr.transferAmount == null ? '' : String(tr.transferAmount)"
|
|
|
- type="number"
|
|
|
- placeholder="请输入"
|
|
|
- :disabled="disabled || !canEditTransfer(sch, tr)"
|
|
|
- :border="false"
|
|
|
- @update:model-value="(v) => patchTransfer(pIdx, sIdx, tIdx, { transferAmount: parseAmount(v) })"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="market-form-field">
|
|
|
- <label>转账时间</label>
|
|
|
- <div class="market-form-field__control">
|
|
|
- <OaDatePicker
|
|
|
- :model-value="tr.transferTime || ''"
|
|
|
- type="datetime"
|
|
|
- value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
- :disabled="disabled || !canEditTransfer(sch, tr)"
|
|
|
- @update:model-value="(v) => patchTransfer(pIdx, sIdx, tIdx, { transferTime: v || '' })"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="market-form-field">
|
|
|
- <label>转账凭证</label>
|
|
|
- <PresignAttachmentUploader
|
|
|
- :model-value="ensureTransferAttachments(tr)"
|
|
|
- :disabled="disabled || !canEditTransfer(sch, tr)"
|
|
|
- :uploading="isTransferUploading(pIdx, sIdx, tIdx)"
|
|
|
- @upload="(file) => uploadTransferFile(pIdx, sIdx, tIdx, file)"
|
|
|
- @remove="(index) => removeTransferFile(pIdx, sIdx, tIdx, index)"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="market-form-field">
|
|
|
- <label>备注</label>
|
|
|
- <van-field
|
|
|
- :model-value="tr.remark || ''"
|
|
|
- type="textarea"
|
|
|
- rows="2"
|
|
|
- maxlength="512"
|
|
|
- show-word-limit
|
|
|
- placeholder="选填"
|
|
|
- :disabled="disabled || !canEditTransfer(sch, tr)"
|
|
|
- :border="false"
|
|
|
- @update:model-value="(v) => patchTransfer(pIdx, sIdx, tIdx, { remark: v })"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div v-if="tr.financeRemark" class="market-form-field">
|
|
|
- <label>财务备注</label>
|
|
|
- <van-field
|
|
|
- :model-value="tr.financeRemark"
|
|
|
- readonly
|
|
|
- :border="false"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div v-if="!disabled && hasTransferAction(sch, tr)" class="protocol-sample-pay__transfer-actions">
|
|
|
- <van-button
|
|
|
- v-if="canEditTransfer(sch, tr)"
|
|
|
- size="mini"
|
|
|
- type="primary"
|
|
|
- plain
|
|
|
- :loading="busyKey === transferBusyKey(pIdx, sIdx, tIdx, tr)"
|
|
|
- @click="saveTransfer(pIdx, sIdx, tIdx)"
|
|
|
- >
|
|
|
- 保存
|
|
|
- </van-button>
|
|
|
- <van-button
|
|
|
- v-if="canSubmitTransfer(tr)"
|
|
|
- size="mini"
|
|
|
- type="primary"
|
|
|
- :loading="busyKey === `submit:${tr.id}`"
|
|
|
- @click="submitFinance(tr, pIdx, sIdx, tIdx)"
|
|
|
- >
|
|
|
- 提交财务
|
|
|
- </van-button>
|
|
|
- <van-button
|
|
|
- v-if="canWithdrawTransfer(tr)"
|
|
|
- size="mini"
|
|
|
- type="warning"
|
|
|
- :loading="busyKey === `withdraw:${tr.id}`"
|
|
|
- @click="withdrawFinance(tr, pIdx, sIdx, tIdx)"
|
|
|
- >
|
|
|
- 撤回
|
|
|
- </van-button>
|
|
|
- <van-button
|
|
|
- v-if="canDeleteTransfer(sch, tr)"
|
|
|
- size="mini"
|
|
|
- type="danger"
|
|
|
- plain
|
|
|
- @click="removeTransfer(pIdx, sIdx, tIdx)"
|
|
|
- >
|
|
|
- 删除
|
|
|
- </van-button>
|
|
|
- </div>
|
|
|
- </article>
|
|
|
- <van-button
|
|
|
- v-if="!disabled && canAddTransfer(sch)"
|
|
|
- class="protocol-sample-pay__add-transfer"
|
|
|
- size="mini"
|
|
|
- type="primary"
|
|
|
- block
|
|
|
- @click="addTransfer(pIdx, sIdx)"
|
|
|
- >
|
|
|
- 添加转账
|
|
|
- </van-button>
|
|
|
+ <ScheduleTransferEditor
|
|
|
+ :schedule="sch"
|
|
|
+ :transfer-types="transferTypes"
|
|
|
+ :market-role="marketRole"
|
|
|
+ :context-id="protocolId"
|
|
|
+ :disabled="disabled"
|
|
|
+ @update:schedule="(next) => replaceSchedule(pIdx, sIdx, next)"
|
|
|
+ @changed="onTransferChanged"
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
</article>
|
|
|
@@ -379,13 +254,6 @@
|
|
|
close-on-click-action
|
|
|
@select="onPayModeSelect"
|
|
|
/>
|
|
|
- <van-action-sheet
|
|
|
- v-model:show="transferTypeSheetVisible"
|
|
|
- :actions="transferTypeSheetActions"
|
|
|
- cancel-text="取消"
|
|
|
- close-on-click-action
|
|
|
- @select="onTransferTypeSelect"
|
|
|
- />
|
|
|
<van-popup v-model:show="datePickerVisible" position="bottom" round>
|
|
|
<van-date-picker
|
|
|
v-model="datePickerValue"
|
|
|
@@ -401,10 +269,8 @@
|
|
|
|
|
|
<script setup>
|
|
|
import { computed, ref, watch } from 'vue'
|
|
|
-import { showConfirmDialog, showSuccessToast, showToast } from 'vant'
|
|
|
-import OaDatePicker from '../../oa/components/OaDatePicker.vue'
|
|
|
-import { performMarketAction, uploadMarketAttachment } from '../../api/market.js'
|
|
|
-import PresignAttachmentUploader from './PresignAttachmentUploader.vue'
|
|
|
+import { showConfirmDialog, showToast } from 'vant'
|
|
|
+import ScheduleTransferEditor from './ScheduleTransferEditor.vue'
|
|
|
import {
|
|
|
applyConsolidateRemainingToPayment,
|
|
|
applyExpandRemainingToInstallment,
|
|
|
@@ -421,32 +287,11 @@ import {
|
|
|
shouldAutoFillLastPeriodDue
|
|
|
} from '../protocol-sample-payment.js'
|
|
|
import {
|
|
|
- applySavedTransfer,
|
|
|
- assertCanSaveTransfer,
|
|
|
- buildTransferSavePayload,
|
|
|
- canSubmitFinance,
|
|
|
canUseProtocolScheduleAction,
|
|
|
- canUseProtocolTransferAction,
|
|
|
- canWithdrawFinance,
|
|
|
- emptyTransferRow,
|
|
|
- ensureTransferAttachments,
|
|
|
- PAY_STATUS_LABELS,
|
|
|
- patchTransfersAt,
|
|
|
- validateTransferRow
|
|
|
+ emptyTransferRow
|
|
|
} from '../protocol-sample-transfer.js'
|
|
|
-import { marketErrorMessage } from '../market-error.js'
|
|
|
-import {
|
|
|
- createPendingMarketAttachment,
|
|
|
- dropPendingMarketAttachment,
|
|
|
- removeMarketAttachmentAt,
|
|
|
- resolvePendingMarketAttachment,
|
|
|
- withPendingMarketAttachment
|
|
|
-} from '../attachment-upload-state.js'
|
|
|
import {
|
|
|
- applyTransferDeleteResult,
|
|
|
- clearTransferDirty,
|
|
|
hasDirtyTransfers,
|
|
|
- isTransferDirty,
|
|
|
markTransferDirty
|
|
|
} from '../protocol-transfer-dirty.js'
|
|
|
import { compareMoney, normalizeMoney } from '../money.js'
|
|
|
@@ -472,16 +317,11 @@ const lastPeriodDueOverrideByKey = ref({})
|
|
|
const modeSheetVisible = ref(false)
|
|
|
const modeSheetPayIdx = ref(-1)
|
|
|
const modeSheetActions = ref([])
|
|
|
-const transferTypeSheetVisible = ref(false)
|
|
|
-const transferTypeSheetActions = ref([])
|
|
|
-const transferTypeTarget = ref(null)
|
|
|
const datePickerVisible = ref(false)
|
|
|
const datePickerValue = ref(['2026', '10', '13'])
|
|
|
const dateTarget = ref(null)
|
|
|
const minDate = new Date(2020, 0, 1)
|
|
|
const maxDate = new Date(2040, 11, 31)
|
|
|
-const busyKey = ref('')
|
|
|
-const uploadKeys = ref(new Set())
|
|
|
|
|
|
const syncedPayments = computed(() => props.modelValue || [])
|
|
|
const expandedSchedules = ref(new Set())
|
|
|
@@ -592,66 +432,38 @@ function isScheduleLocked(sch) {
|
|
|
return (sch.transfers || []).some((t) => t.payStatus === 'yjf')
|
|
|
}
|
|
|
|
|
|
-function paymentContext() {
|
|
|
- return { module: 'payment', marketRole: props.marketRole || 'specialist' }
|
|
|
-}
|
|
|
-
|
|
|
function schedulePaid(sch) {
|
|
|
return schedulePaidArrears(sch?.dueAmount, sch?.transfers || [])
|
|
|
}
|
|
|
|
|
|
-function payStatusLabel(status) {
|
|
|
- return PAY_STATUS_LABELS[String(status || 'dfj')] || '已付款'
|
|
|
-}
|
|
|
-
|
|
|
-function payStatusTone(status) {
|
|
|
- const code = String(status || 'dfj')
|
|
|
- if (code === 'yjf') return 'success'
|
|
|
- if (code === 'jfqrz') return 'warning'
|
|
|
- return 'primary'
|
|
|
-}
|
|
|
-
|
|
|
-function transferTypeLabel(value) {
|
|
|
- const key = String(value || '').trim()
|
|
|
- const hit = (props.transferTypes || []).find((opt) => String(opt.value) === key)
|
|
|
- return hit?.label || key || '请选择'
|
|
|
-}
|
|
|
-
|
|
|
-function parseAmount(raw) {
|
|
|
- if (raw === '' || raw == null) return null
|
|
|
- return String(raw)
|
|
|
-}
|
|
|
-
|
|
|
-function transferBusyKey(pIdx, sIdx, tIdx, tr) {
|
|
|
- return `save:${tr?.id || `${pIdx}-${sIdx}-${tIdx}`}`
|
|
|
-}
|
|
|
-
|
|
|
-function isTransferUploading(pIdx, sIdx, tIdx) {
|
|
|
- return uploadKeys.value.has(`${pIdx}-${sIdx}-${tIdx}`)
|
|
|
-}
|
|
|
-
|
|
|
-function getTransferList(pIdx, sIdx) {
|
|
|
- return [...(props.modelValue?.[pIdx]?.schedules?.[sIdx]?.transfers || [])]
|
|
|
+function replaceSchedule(pIdx, sIdx, nextSchedule) {
|
|
|
+ const list = [...(props.modelValue || [])]
|
|
|
+ const pay = { ...list[pIdx] }
|
|
|
+ const schedules = [...(pay.schedules || [])]
|
|
|
+ schedules[sIdx] = nextSchedule
|
|
|
+ pay.schedules = schedules
|
|
|
+ list[pIdx] = pay
|
|
|
+ emitList(list)
|
|
|
+ emit('transfer-dirty-change', hasDirtyTransfers(list))
|
|
|
}
|
|
|
|
|
|
-function setTransferList(pIdx, sIdx, transfers) {
|
|
|
- const next = patchTransfersAt(props.modelValue, pIdx, sIdx, transfers)
|
|
|
- emitList(next)
|
|
|
- emit('transfer-dirty-change', hasDirtyTransfers(next))
|
|
|
+function onTransferChanged() {
|
|
|
+ emit('transfer-dirty-change', hasDirtyTransfers(props.modelValue))
|
|
|
}
|
|
|
|
|
|
-function patchTransfer(pIdx, sIdx, tIdx, patch) {
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- transfers[tIdx] = markTransferDirty({ ...transfers[tIdx], ...patch })
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
+function canAddTransfer(schedule) {
|
|
|
+ if (!schedule) return false
|
|
|
+ // 对齐 Web SamplePaymentPanel:每期均可录入转账草稿
|
|
|
+ const actions = schedule.allowedActions
|
|
|
+ if (!Array.isArray(actions) || actions.length === 0) return true
|
|
|
+ return canUseProtocolScheduleAction(schedule, 'register-transfer')
|
|
|
}
|
|
|
|
|
|
function addTransfer(pIdx, sIdx) {
|
|
|
const schedule = props.modelValue?.[pIdx]?.schedules?.[sIdx]
|
|
|
if (!canAddTransfer(schedule)) return
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- transfers.push(markTransferDirty(emptyTransferRow()))
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
+ const transfers = [...(schedule.transfers || []), markTransferDirty(emptyTransferRow())]
|
|
|
+ replaceSchedule(pIdx, sIdx, { ...schedule, transfers })
|
|
|
const key = scheduleKey(pIdx, sIdx)
|
|
|
if (!expandedSchedules.value.has(key)) {
|
|
|
const next = new Set(expandedSchedules.value)
|
|
|
@@ -660,240 +472,6 @@ function addTransfer(pIdx, sIdx) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-async function removeTransfer(pIdx, sIdx, tIdx) {
|
|
|
- const schedule = props.modelValue?.[pIdx]?.schedules?.[sIdx]
|
|
|
- const transfer = schedule?.transfers?.[tIdx]
|
|
|
- if (!transfer || !canDeleteTransfer(schedule, transfer)) return
|
|
|
- try {
|
|
|
- await showConfirmDialog({ title: '删除转账', message: '确认删除该笔转账记录吗?' })
|
|
|
- } catch {
|
|
|
- return
|
|
|
- }
|
|
|
- if (!transfer.id) {
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- transfers.splice(tIdx, 1)
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
- return
|
|
|
- }
|
|
|
- busyKey.value = `delete:${transfer.id}`
|
|
|
- try {
|
|
|
- await performMarketAction(paymentContext(), 'delete-payment-transfer', {
|
|
|
- id: transfer.id
|
|
|
- })
|
|
|
- const next = applyTransferDeleteResult(
|
|
|
- { samplePayments: props.modelValue }, pIdx, sIdx, tIdx, true
|
|
|
- ).samplePayments
|
|
|
- emitList(next)
|
|
|
- emit('transfer-dirty-change', hasDirtyTransfers(next))
|
|
|
- showSuccessToast('转账记录已删除')
|
|
|
- } catch (error) {
|
|
|
- showToast(marketErrorMessage(error, '删除转账失败'))
|
|
|
- } finally {
|
|
|
- busyKey.value = ''
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-function canAddTransfer(schedule) {
|
|
|
- if (!schedule) return false
|
|
|
- // 对齐 Web SamplePaymentPanel:每期均可录入转账草稿
|
|
|
- const actions = schedule.allowedActions
|
|
|
- if (!Array.isArray(actions) || actions.length === 0) return true
|
|
|
- return canUseProtocolScheduleAction(schedule, 'register-transfer')
|
|
|
-}
|
|
|
-
|
|
|
-function canEditTransfer(schedule, transfer) {
|
|
|
- if (!transfer?.id) return canAddTransfer(schedule)
|
|
|
- return canUseProtocolTransferAction(transfer, 'edit-transfer')
|
|
|
-}
|
|
|
-
|
|
|
-function canDeleteTransfer(schedule, transfer) {
|
|
|
- if (!transfer?.id) return canAddTransfer(schedule)
|
|
|
- return canUseProtocolTransferAction(transfer, 'delete-payment-transfer')
|
|
|
-}
|
|
|
-
|
|
|
-function canSubmitTransfer(transfer) {
|
|
|
- return !isTransferDirty(transfer) &&
|
|
|
- canUseProtocolTransferAction(transfer, 'submit') &&
|
|
|
- canSubmitFinance(transfer, props.protocolId)
|
|
|
-}
|
|
|
-
|
|
|
-function canWithdrawTransfer(transfer) {
|
|
|
- return canUseProtocolTransferAction(transfer, 'withdraw') &&
|
|
|
- canWithdrawFinance(transfer, props.protocolId)
|
|
|
-}
|
|
|
-
|
|
|
-function hasTransferAction(schedule, transfer) {
|
|
|
- return canEditTransfer(schedule, transfer) ||
|
|
|
- canDeleteTransfer(schedule, transfer) ||
|
|
|
- canSubmitTransfer(transfer) ||
|
|
|
- canWithdrawTransfer(transfer)
|
|
|
-}
|
|
|
-
|
|
|
-function openTransferTypeSheet(pIdx, sIdx, tIdx) {
|
|
|
- transferTypeTarget.value = { pIdx, sIdx, tIdx }
|
|
|
- transferTypeSheetActions.value = (props.transferTypes || []).map((opt) => ({
|
|
|
- name: opt.label || opt.value,
|
|
|
- value: opt.value
|
|
|
- }))
|
|
|
- if (!transferTypeSheetActions.value.length) {
|
|
|
- showToast('暂无转账方式选项')
|
|
|
- return
|
|
|
- }
|
|
|
- transferTypeSheetVisible.value = true
|
|
|
-}
|
|
|
-
|
|
|
-function onTransferTypeSelect(action) {
|
|
|
- const target = transferTypeTarget.value
|
|
|
- if (!target) return
|
|
|
- patchTransfer(target.pIdx, target.sIdx, target.tIdx, { transferType: action.value })
|
|
|
-}
|
|
|
-
|
|
|
-async function saveTransfer(pIdx, sIdx, tIdx) {
|
|
|
- const sch = props.modelValue?.[pIdx]?.schedules?.[sIdx]
|
|
|
- const tr = sch?.transfers?.[tIdx]
|
|
|
- if (!tr || !canEditTransfer(sch, tr)) return
|
|
|
- try {
|
|
|
- assertCanSaveTransfer({ protocolId: props.protocolId, scheduleId: sch?.id })
|
|
|
- } catch (error) {
|
|
|
- showToast(error.message)
|
|
|
- return
|
|
|
- }
|
|
|
- const invalid = validateTransferRow(tr)
|
|
|
- if (invalid) {
|
|
|
- showToast(invalid)
|
|
|
- return
|
|
|
- }
|
|
|
- const key = transferBusyKey(pIdx, sIdx, tIdx, tr)
|
|
|
- busyKey.value = key
|
|
|
- try {
|
|
|
- const payload = buildTransferSavePayload(tr)
|
|
|
- let remote
|
|
|
- if (tr.id) {
|
|
|
- remote = await performMarketAction(paymentContext(), 'edit-transfer', {
|
|
|
- id: tr.id,
|
|
|
- data: payload
|
|
|
- })
|
|
|
- } else {
|
|
|
- remote = await performMarketAction(paymentContext(), 'register-transfer', {
|
|
|
- data: { scheduleId: String(sch.id), ...payload }
|
|
|
- })
|
|
|
- }
|
|
|
- const data = remote?.data || remote || {}
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- transfers[tIdx] = clearTransferDirty(applySavedTransfer(transfers[tIdx], data))
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
- showSuccessToast(tr.id ? '转账记录已保存' : '转账记录已创建')
|
|
|
- } catch (error) {
|
|
|
- showToast(marketErrorMessage(error, '保存转账失败'))
|
|
|
- } finally {
|
|
|
- busyKey.value = ''
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-async function submitFinance(tr, pIdx, sIdx, tIdx) {
|
|
|
- if (!canSubmitTransfer(tr)) {
|
|
|
- showToast('请先保存该转账记录后再提交财务确认')
|
|
|
- return
|
|
|
- }
|
|
|
- try {
|
|
|
- await showConfirmDialog({
|
|
|
- title: '提交财务确认',
|
|
|
- message: '确认提交该笔转账给财务确认吗?'
|
|
|
- })
|
|
|
- } catch {
|
|
|
- return
|
|
|
- }
|
|
|
- busyKey.value = `submit:${tr.id}`
|
|
|
- try {
|
|
|
- const remote = await performMarketAction(paymentContext(), 'submit', { id: tr.id })
|
|
|
- const data = remote?.data || remote || {}
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- transfers[tIdx] = applySavedTransfer(transfers[tIdx], { ...data, payStatus: data.payStatus || 'jfqrz' })
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
- showSuccessToast('已提交财务确认')
|
|
|
- } catch (error) {
|
|
|
- showToast(marketErrorMessage(error, '提交失败'))
|
|
|
- } finally {
|
|
|
- busyKey.value = ''
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-async function withdrawFinance(tr, pIdx, sIdx, tIdx) {
|
|
|
- if (!canWithdrawTransfer(tr)) return
|
|
|
- try {
|
|
|
- await showConfirmDialog({
|
|
|
- title: '撤回',
|
|
|
- message: '确认撤回该笔转账的财务确认申请?撤回后可修改并重新提交。'
|
|
|
- })
|
|
|
- } catch {
|
|
|
- return
|
|
|
- }
|
|
|
- busyKey.value = `withdraw:${tr.id}`
|
|
|
- try {
|
|
|
- const remote = await performMarketAction(paymentContext(), 'withdraw', { id: tr.id })
|
|
|
- const data = remote?.data || remote || {}
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- transfers[tIdx] = applySavedTransfer(transfers[tIdx], { ...data, payStatus: data.payStatus || 'dfj' })
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
- showSuccessToast('已撤回')
|
|
|
- } catch (error) {
|
|
|
- showToast(marketErrorMessage(error, '撤回失败'))
|
|
|
- } finally {
|
|
|
- busyKey.value = ''
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-async function uploadTransferFile(pIdx, sIdx, tIdx, file) {
|
|
|
- if (!file) return
|
|
|
- const key = `${pIdx}-${sIdx}-${tIdx}`
|
|
|
- const pending = createPendingMarketAttachment(file)
|
|
|
- const transfersBegin = getTransferList(pIdx, sIdx)
|
|
|
- const begin = { ...transfersBegin[tIdx] }
|
|
|
- ensureTransferAttachments(begin)
|
|
|
- begin.attachments = withPendingMarketAttachment(begin.attachments, pending)
|
|
|
- transfersBegin[tIdx] = markTransferDirty(begin)
|
|
|
- setTransferList(pIdx, sIdx, transfersBegin)
|
|
|
- uploadKeys.value = new Set([...uploadKeys.value, key])
|
|
|
- try {
|
|
|
- const uploaded = await uploadMarketAttachment(
|
|
|
- { module: 'payment', marketRole: props.marketRole || 'specialist' },
|
|
|
- file
|
|
|
- )
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- const current = { ...transfers[tIdx] }
|
|
|
- ensureTransferAttachments(current)
|
|
|
- current.attachments = resolvePendingMarketAttachment(
|
|
|
- current.attachments,
|
|
|
- pending._pendingId,
|
|
|
- uploaded
|
|
|
- )
|
|
|
- transfers[tIdx] = markTransferDirty(current)
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
- showSuccessToast('附件上传成功')
|
|
|
- } catch (error) {
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- const current = { ...transfers[tIdx] }
|
|
|
- ensureTransferAttachments(current)
|
|
|
- current.attachments = dropPendingMarketAttachment(current.attachments, pending._pendingId)
|
|
|
- transfers[tIdx] = markTransferDirty(current)
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
- showToast(marketErrorMessage(error, '附件上传失败'))
|
|
|
- } finally {
|
|
|
- const next = new Set(uploadKeys.value)
|
|
|
- next.delete(key)
|
|
|
- uploadKeys.value = next
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-function removeTransferFile(pIdx, sIdx, tIdx, index) {
|
|
|
- const transfers = getTransferList(pIdx, sIdx)
|
|
|
- const current = { ...transfers[tIdx] }
|
|
|
- ensureTransferAttachments(current)
|
|
|
- current.attachments = removeMarketAttachmentAt(current.attachments, index)
|
|
|
- transfers[tIdx] = markTransferDirty(current)
|
|
|
- setTransferList(pIdx, sIdx, transfers)
|
|
|
-}
|
|
|
-
|
|
|
function activeScheduleIndices(schedules) {
|
|
|
const idx = []
|
|
|
;(schedules || []).forEach((s, i) => {
|
|
|
@@ -1421,50 +999,4 @@ function onDateConfirm({ selectedValues }) {
|
|
|
.protocol-sample-pay__stat.is-arrears b {
|
|
|
color: #b45309;
|
|
|
}
|
|
|
-.protocol-sample-pay__transfer {
|
|
|
- margin: 8px 8px 10px;
|
|
|
- padding: 10px;
|
|
|
- border-radius: 12px;
|
|
|
- border: 1px solid #e8f0ec;
|
|
|
- background: linear-gradient(180deg, #f8fffc, #fff);
|
|
|
-}
|
|
|
-.protocol-sample-pay__transfer-title {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- gap: 8px;
|
|
|
- margin-bottom: 6px;
|
|
|
-}
|
|
|
-.protocol-sample-pay__attach,
|
|
|
-.protocol-sample-pay__datetime {
|
|
|
- padding: 8px 12px;
|
|
|
-}
|
|
|
-.protocol-sample-pay__attach label,
|
|
|
-.protocol-sample-pay__datetime label {
|
|
|
- display: block;
|
|
|
- margin-bottom: 6px;
|
|
|
- color: #3d524a;
|
|
|
- font-size: 12px;
|
|
|
- font-weight: 650;
|
|
|
-}
|
|
|
-.protocol-sample-pay__transfer-actions {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- gap: 6px;
|
|
|
- justify-content: flex-end;
|
|
|
- padding: 8px 4px 0;
|
|
|
-}
|
|
|
-.protocol-sample-pay__transfer-actions :deep(.van-button),
|
|
|
-.protocol-sample-pay__add-transfer {
|
|
|
- min-width: auto;
|
|
|
- min-height: 28px;
|
|
|
- height: 28px;
|
|
|
- padding: 0 10px;
|
|
|
- border-radius: 8px !important;
|
|
|
- font-weight: 600;
|
|
|
-}
|
|
|
-.protocol-sample-pay__add-transfer {
|
|
|
- margin: 0 8px;
|
|
|
- width: calc(100% - 16px);
|
|
|
-}
|
|
|
</style>
|