154 lines
4.7 KiB
Vue
154 lines
4.7 KiB
Vue
<script setup>
|
||
import { reactive, ref, onMounted } from 'vue'
|
||
import {
|
||
getExpenseItemTree,
|
||
flattenExpenseLeaves,
|
||
createAdvance,
|
||
submitAdvance,
|
||
bindAttachments
|
||
} from '@/api/bx'
|
||
import { chooseAndUploadBxAttachments } from '@/utils/bxUpload'
|
||
import { PAGE_PATHS } from '@/config/api'
|
||
|
||
const submitting = ref(false)
|
||
const leaves = ref([])
|
||
const photos = ref([])
|
||
const form = reactive({
|
||
reason: '',
|
||
purpose: '',
|
||
amount: '',
|
||
remark: '',
|
||
expenseItemId: '',
|
||
expenseLabel: ''
|
||
})
|
||
|
||
const goBack = () => {
|
||
uni.navigateBack({
|
||
fail: () => uni.navigateTo({ url: PAGE_PATHS.bxAdvanceList })
|
||
})
|
||
}
|
||
|
||
onMounted(async () => {
|
||
try {
|
||
leaves.value = flattenExpenseLeaves(await getExpenseItemTree())
|
||
} catch (e) {
|
||
uni.showToast({ title: e.message || '费用项目加载失败', icon: 'none' })
|
||
}
|
||
})
|
||
|
||
const pickExpense = () => {
|
||
if (!leaves.value.length) {
|
||
uni.showToast({ title: '暂无费用项目', icon: 'none' })
|
||
return
|
||
}
|
||
uni.showActionSheet({
|
||
itemList: leaves.value.map((i) => i.pathLabel).slice(0, 20),
|
||
success: (res) => {
|
||
const item = leaves.value[res.tapIndex]
|
||
if (!item) return
|
||
form.expenseItemId = item.id
|
||
form.expenseLabel = item.pathLabel
|
||
}
|
||
})
|
||
}
|
||
|
||
const addPhotos = async () => {
|
||
const uploaded = await chooseAndUploadBxAttachments({
|
||
bizType: 'advance_apply',
|
||
bizId: '0',
|
||
maxCount: 6,
|
||
currentCount: photos.value.length
|
||
})
|
||
photos.value = photos.value.concat(uploaded)
|
||
}
|
||
|
||
const removePhoto = (idx) => photos.value.splice(idx, 1)
|
||
|
||
const submit = async (andSubmit) => {
|
||
if (!String(form.reason).trim()) {
|
||
uni.showToast({ title: '请填写借款事由', icon: 'none' })
|
||
return
|
||
}
|
||
if (!form.amount || Number(form.amount) <= 0) {
|
||
uni.showToast({ title: '请填写金额', icon: 'none' })
|
||
return
|
||
}
|
||
submitting.value = true
|
||
try {
|
||
const created = await createAdvance({
|
||
reason: String(form.reason).trim(),
|
||
purpose: form.purpose || undefined,
|
||
amount: Number(form.amount),
|
||
remark: form.remark || undefined,
|
||
expenseItemId: form.expenseItemId || undefined
|
||
})
|
||
const id = created?.id
|
||
if (id && photos.value.length) {
|
||
await bindAttachments(
|
||
photos.value.map((p) => p.id),
|
||
'advance_apply',
|
||
id
|
||
)
|
||
}
|
||
if (andSubmit && id) {
|
||
await submitAdvance(id)
|
||
uni.showToast({ title: '已提交审批', icon: 'success' })
|
||
} else {
|
||
uni.showToast({ title: '已保存草稿', icon: 'success' })
|
||
}
|
||
setTimeout(() => goBack(), 500)
|
||
} catch (e) {
|
||
uni.showToast({ title: e.message || '保存失败', icon: 'none' })
|
||
} finally {
|
||
submitting.value = false
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<view class="mp-page mp-page--sub mp-page--with-bottom">
|
||
<view class="mp-header mp-header--bx">
|
||
<text class="mp-subpage-back" @click="goBack">← 返回</text>
|
||
<text class="mp-header__title" style="margin-top: 16rpx">新建借款</text>
|
||
</view>
|
||
|
||
<view class="mp-form-panel">
|
||
<view class="mp-form-row">
|
||
<text class="mp-form-label mp-form-label--req">借款事由</text>
|
||
<textarea v-model="form.reason" class="mp-form-textarea" placeholder="用途说明" />
|
||
</view>
|
||
<view class="mp-form-row">
|
||
<text class="mp-form-label">用途</text>
|
||
<input v-model="form.purpose" class="mp-form-input" placeholder="可选" />
|
||
</view>
|
||
<view class="mp-form-row">
|
||
<text class="mp-form-label mp-form-label--req">金额(元)</text>
|
||
<input v-model="form.amount" class="mp-form-input" type="digit" placeholder="0.00" />
|
||
</view>
|
||
<view class="mp-form-row" @click="pickExpense">
|
||
<text class="mp-form-label">费用项目</text>
|
||
<view class="mp-form-input">{{ form.expenseLabel || '可选,点击选择' }}</view>
|
||
</view>
|
||
<view class="mp-form-row">
|
||
<text class="mp-form-label">备注</text>
|
||
<textarea v-model="form.remark" class="mp-form-textarea" placeholder="可选" />
|
||
</view>
|
||
<view class="mp-form-row">
|
||
<text class="mp-form-label">凭证照片</text>
|
||
<view class="mp-photo-row">
|
||
<view v-for="(p, idx) in photos" :key="p.id" class="mp-photo-item">
|
||
<image :src="p.localPath" mode="aspectFill" />
|
||
<view class="mp-photo-del" @click.stop="removePhoto(idx)">×</view>
|
||
</view>
|
||
<view v-if="photos.length < 6" class="mp-photo-add" @click="addPhotos">+ 拍照</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="mp-bottom-bar">
|
||
<view class="mp-btn mp-btn--ghost" @click="submit(false)">{{ submitting ? '…' : '存草稿' }}</view>
|
||
<view class="mp-btn mp-btn--primary" @click="submit(true)">{{ submitting ? '…' : '提交审批' }}</view>
|
||
</view>
|
||
</view>
|
||
</template>
|