|
@@ -0,0 +1,393 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <Dialog
|
|
|
|
|
+ v-model="dialogVisible"
|
|
|
|
|
+ :title="titleName"
|
|
|
|
|
+ width="80%"
|
|
|
|
|
+ class="form-tag-dialog delete-item-form"
|
|
|
|
|
+ scroll
|
|
|
|
|
+ @close="handleClosed"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ class="-mb-15px"
|
|
|
|
|
+ :model="dataForm"
|
|
|
|
|
+ ref="formRef"
|
|
|
|
|
+ label-width="110px"
|
|
|
|
|
+ :rules="dataRule"
|
|
|
|
|
+ v-loading="formLoading"
|
|
|
|
|
+ >
|
|
|
|
|
+ <!-- 长者选择 -->
|
|
|
|
|
+ <div class="info-title">长者信息</div>
|
|
|
|
|
+ <div class="info-wrap">
|
|
|
|
|
+ <el-row :gutter="10">
|
|
|
|
|
+ <el-col :lg="12" :md="12" :sm="24" :xs="24">
|
|
|
|
|
+ <el-form-item label="选择长者" prop="elderId">
|
|
|
|
|
+ <SelectElder
|
|
|
|
|
+ v-model="dataForm.elderId"
|
|
|
|
|
+ type="2"
|
|
|
|
|
+ @elder="handleSelectElder"
|
|
|
|
|
+ :tId="dataForm.tenantId"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :lg="12" :md="12" :sm="24" :xs="24">
|
|
|
|
|
+ <el-form-item label="长者姓名">
|
|
|
|
|
+ <el-text>{{ dataForm.elderName }}</el-text>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :lg="12" :md="12" :sm="24" :xs="24">
|
|
|
|
|
+ <el-form-item label="身份证号">
|
|
|
|
|
+ <el-text>{{ dataForm.idCard }}</el-text>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :lg="12" :md="12" :sm="24" :xs="24">
|
|
|
|
|
+ <el-form-item label="床位号">
|
|
|
|
|
+ <el-text>{{ dataForm.bedName }}</el-text>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 月度固定费用列表 -->
|
|
|
|
|
+ <div class="info-title">月度固定费用 (共 {{ expenseList.length }} 条)</div>
|
|
|
|
|
+ <div class="info-wrap">
|
|
|
|
|
+ <div v-if="expenseList.length > 0">
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ :data="expenseList"
|
|
|
|
|
+ v-loading="tableLoading"
|
|
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
|
|
+ border
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-table-column type="selection" width="55" align="center" fixed />
|
|
|
|
|
+ <el-table-column label="项目类别" prop="itemCategoryName" min-width="120" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column label="项目名称" prop="itemName" min-width="150" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column label="金额" prop="amount" min-width="100">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span>¥{{ formatNum(row.amount) }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="实际金额" prop="actualAmount" min-width="100">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span>¥{{ formatNum(row.actualAmount) }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="是否打折" prop="isDiscount" min-width="90">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.isDiscount === 1" type="success">是</el-tag>
|
|
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="折扣" prop="discount" min-width="80" />
|
|
|
|
|
+ <el-table-column label="折扣金额" prop="discountAmount" min-width="100">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span v-if="row.discountAmount">¥{{ formatNum(row.discountAmount) }}</span>
|
|
|
|
|
+ <span v-else>-</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="是否月度费用" prop="isMonthlyExpense" min-width="110">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.isMonthlyExpense === 1" type="success">是</el-tag>
|
|
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="是否一次性费用" prop="isOneTimeFee" min-width="120">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.isOneTimeFee === 1" type="success">是</el-tag>
|
|
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="是否押金" prop="isDeposit" min-width="90">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.isDeposit === 1" type="success">是</el-tag>
|
|
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="是否赠送" prop="isFreeGift" min-width="90">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.isFreeGift === 1" type="success">是</el-tag>
|
|
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="赠送开始时间" prop="freeStartTime" min-width="160" />
|
|
|
|
|
+ <el-table-column label="赠送结束时间" prop="freeEndTime" min-width="160" />
|
|
|
|
|
+ <el-table-column label="是否分期" prop="isHirePurchase" min-width="90">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.isHirePurchase === 1" type="success">是</el-tag>
|
|
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="分期期数" prop="hirePurchaseNumber" min-width="90" />
|
|
|
|
|
+ <el-table-column label="分期每期金额" prop="hirePurchaseAmount" min-width="120">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span v-if="row.hirePurchaseAmount">¥{{ formatNum(row.hirePurchaseAmount) }}</span>
|
|
|
|
|
+ <span v-else>-</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="数量" prop="count" min-width="80" />
|
|
|
|
|
+ <el-table-column label="单项总价" prop="totalAmount" min-width="100">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span>¥{{ formatNum(row.totalAmount) }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="费用类型" prop="type" min-width="100">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.type === 1" type="primary">床位费</el-tag>
|
|
|
|
|
+ <el-tag v-else-if="row.type === 2" type="success">护理费</el-tag>
|
|
|
|
|
+ <el-tag v-else-if="row.type === 3" type="warning">膳食费</el-tag>
|
|
|
|
|
+ <span v-else>-</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="租户ID" prop="tenantId" min-width="100" />
|
|
|
|
|
+ <el-table-column label="变更开始日期" prop="changeStartDate" min-width="120">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span>{{ row.changeStartDate ? formatBackendDateTime(row.changeStartDate, 'YYYY-MM-DD') : '-' }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="变更结束日期" prop="changeEndDate" min-width="120">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span>{{ row.changeEndDate ? formatBackendDateTime(row.changeEndDate, 'YYYY-MM-DD') : '-' }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="变更标识" prop="changeFlag" min-width="100">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.changeFlag === 0" type="warning">有变更</el-tag>
|
|
|
|
|
+ <el-tag v-else-if="row.changeFlag === 1" type="success">无变更</el-tag>
|
|
|
|
|
+ <span v-else>-</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="是否按天计算" prop="isDayCalculate" min-width="110">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.isDayCalculate === 1" type="success">是</el-tag>
|
|
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="创建时间" prop="createTime" min-width="160">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span>{{ formatBackendDateTime(row.createTime) }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-empty v-else-if="!tableLoading" description="暂无数据" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="handleClosed">关闭</el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-loading="submitLoading"
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ @click="submitForm"
|
|
|
|
|
+ :disabled="!selectedIds.length"
|
|
|
|
|
+ >
|
|
|
|
|
+ 删除选中({{ selectedIds.length }})
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </Dialog>
|
|
|
|
|
+</template>
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { getTenantId } from '@/utils/auth'
|
|
|
|
|
+import { formatNum } from '@/utils/formatter'
|
|
|
|
|
+import { formatBackendDateTime } from '@/utils/formatTime'
|
|
|
|
|
+import { getExpenseItemsByElderId, deleteExpenseItems } from './api'
|
|
|
|
|
+
|
|
|
|
|
+interface ExpenseItem {
|
|
|
|
|
+ id: number
|
|
|
|
|
+ expenseId: number
|
|
|
|
|
+ itemId: number
|
|
|
|
|
+ itemCategoryId: number
|
|
|
|
|
+ itemCategoryName: string
|
|
|
|
|
+ itemName: string
|
|
|
|
|
+ amount: number
|
|
|
|
|
+ actualAmount: number
|
|
|
|
|
+ isDiscount: number
|
|
|
|
|
+ discount: string
|
|
|
|
|
+ isMonthlyExpense: number
|
|
|
|
|
+ isOneTimeFee: number
|
|
|
|
|
+ isDeposit: number
|
|
|
|
|
+ isFreeGift: number
|
|
|
|
|
+ freeStartTime: string
|
|
|
|
|
+ freeEndTime: string
|
|
|
|
|
+ isHirePurchase: number
|
|
|
|
|
+ hirePurchaseNumber: number
|
|
|
|
|
+ hirePurchaseAmount: number
|
|
|
|
|
+ count: number
|
|
|
|
|
+ totalAmount: number
|
|
|
|
|
+ type: number
|
|
|
|
|
+ discountAmount: number
|
|
|
|
|
+ tenantId: number
|
|
|
|
|
+ changeStartDate: string
|
|
|
|
|
+ changeEndDate: string
|
|
|
|
|
+ changeFlag: number
|
|
|
|
|
+ createTime: string
|
|
|
|
|
+ isDayCalculate: number
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface DataForm {
|
|
|
|
|
+ elderId: number | undefined
|
|
|
|
|
+ elderName: string
|
|
|
|
|
+ idCard: string
|
|
|
|
|
+ bedName: string
|
|
|
|
|
+ tenantId: number
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+defineOptions({ name: 'DeleteItemForm' })
|
|
|
|
|
+const message = useMessage() // 消息弹窗
|
|
|
|
|
+const { t } = useI18n() // 国际化
|
|
|
|
|
+const dialogVisible = ref(false) // 弹窗
|
|
|
|
|
+const formLoading = ref(false) // 表单加载
|
|
|
|
|
+const submitLoading = ref(false) // 提交加载
|
|
|
|
|
+const tableLoading = ref(false) // 表格加载
|
|
|
|
|
+const titleName = ref('删除长者固定月费用')
|
|
|
|
|
+
|
|
|
|
|
+// 表单数据
|
|
|
|
|
+const dataForm = reactive<DataForm>({
|
|
|
|
|
+ elderId: undefined,
|
|
|
|
|
+ elderName: '',
|
|
|
|
|
+ idCard: '',
|
|
|
|
|
+ bedName: '',
|
|
|
|
|
+ tenantId: getTenantId()
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 表单校验规则
|
|
|
|
|
+const dataRule = {
|
|
|
|
|
+ elderId: [
|
|
|
|
|
+ { required: true, message: '请选择长者', trigger: 'change' }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 费用列表
|
|
|
|
|
+const expenseList = ref<ExpenseItem[]>([])
|
|
|
|
|
+// 选中的费用ID
|
|
|
|
|
+const selectedIds = ref<number[]>([])
|
|
|
|
|
+
|
|
|
|
|
+const formRef = ref()
|
|
|
|
|
+
|
|
|
|
|
+/** 打开弹窗 */
|
|
|
|
|
+const open = async () => {
|
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
|
+ resetForm()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|
|
|
|
+
|
|
|
|
|
+/** 选择长者回调 */
|
|
|
|
|
+const handleSelectElder = async (item: any) => {
|
|
|
|
|
+ dataForm.elderId = item.id
|
|
|
|
|
+ dataForm.elderName = item.elderName || ''
|
|
|
|
|
+ dataForm.idCard = item.idCard || ''
|
|
|
|
|
+ dataForm.bedName = item.bedName || ''
|
|
|
|
|
+
|
|
|
|
|
+ // 获取长者月度固定费用
|
|
|
|
|
+ if (item.id) {
|
|
|
|
|
+ await getExpenseList(item.id)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/** 获取长者月度固定费用列表 */
|
|
|
|
|
+const getExpenseList = async (elderId: number) => {
|
|
|
|
|
+ tableLoading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res: any = await getExpenseItemsByElderId(elderId)
|
|
|
|
|
+ console.log('接口返回:', res)
|
|
|
|
|
+ expenseList.value = res
|
|
|
|
|
+ console.log('expenseList 赋值后:', expenseList.value)
|
|
|
|
|
+
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.error('获取费用列表失败', err)
|
|
|
|
|
+ expenseList.value = []
|
|
|
|
|
+ message.error('获取费用列表失败')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ tableLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/** 表格选择变化 */
|
|
|
|
|
+const handleSelectionChange = (selection: ExpenseItem[]) => {
|
|
|
|
|
+ selectedIds.value = selection.map(item => item.id)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/** 提交表单 - 删除选中的费用 */
|
|
|
|
|
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
|
|
|
|
+const submitForm = async () => {
|
|
|
|
|
+ if (!selectedIds.value.length) {
|
|
|
|
|
+ message.warning('请选择要删除的费用')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 确认删除
|
|
|
|
|
+ try {
|
|
|
|
|
+ await ElMessageBox.confirm(
|
|
|
|
|
+ `确定要删除选中的 ${selectedIds.value.length} 项费用吗?`,
|
|
|
|
|
+ '提示',
|
|
|
|
|
+ {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
|
+ type: 'warning'
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ submitLoading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res: any = await deleteExpenseItems(selectedIds.value)
|
|
|
|
|
+ console.log('删除接口返回:', res)
|
|
|
|
|
+ // 支持两种返回格式: {code: 0, data: true, msg: ""} 或 {code: 0, msg: ""}
|
|
|
|
|
+ if (res) {
|
|
|
|
|
+ message.success('删除成功')
|
|
|
|
|
+ // 刷新列表
|
|
|
|
|
+ if (dataForm.elderId) {
|
|
|
|
|
+ await getExpenseList(dataForm.elderId)
|
|
|
|
|
+ }
|
|
|
|
|
+ selectedIds.value = []
|
|
|
|
|
+ // 发送操作成功的事件
|
|
|
|
|
+ emit('success')
|
|
|
|
|
+ } else {
|
|
|
|
|
+ message.error(res?.msg || '删除失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.error('删除失败', err)
|
|
|
|
|
+ message.error('删除失败')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ submitLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 重置表单
|
|
|
|
|
+const resetForm = () => {
|
|
|
|
|
+ dataForm.elderId = undefined
|
|
|
|
|
+ dataForm.elderName = ''
|
|
|
|
|
+ dataForm.idCard = ''
|
|
|
|
|
+ dataForm.bedName = ''
|
|
|
|
|
+ expenseList.value = []
|
|
|
|
|
+ selectedIds.value = []
|
|
|
|
|
+ formRef.value?.resetFields()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 关闭表单
|
|
|
|
|
+const handleClosed = () => {
|
|
|
|
|
+ resetForm()
|
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
|
+}
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+.delete-item-form {
|
|
|
|
|
+ .info-title {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ margin: 15px 0 10px;
|
|
|
|
|
+ padding-left: 10px;
|
|
|
|
|
+ border-left: 4px solid #409eff;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .info-wrap {
|
|
|
|
|
+ padding: 15px;
|
|
|
|
|
+ background-color: #f5f7fa;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ margin-bottom: 15px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|