471 lines
12 KiB
Vue

<script setup>
import { h, onMounted, ref, resolveDirective, withDirectives } from 'vue'
import {
NButton,
NForm,
NFormItem,
NInput,
NTag,
NPopconfirm,
NSelect,
NDatePicker,
NInputNumber,
NSpace,
} from 'naive-ui'
import CommonPage from '@/components/page/CommonPage.vue'
import QueryBarItem from '@/components/query-bar/QueryBarItem.vue'
import CrudModal from '@/components/table/CrudModal.vue'
import CrudTable from '@/components/table/CrudTable.vue'
import { formatDate, renderIcon } from '@/utils'
import { useCRUD } from '@/composables'
import api from '@/api'
import TheIcon from '@/components/icon/TheIcon.vue'
defineOptions({ name: '审核列表' })
const $table = ref(null)
const queryItems = ref({})
const vPermission = resolveDirective('permission')
// 审核状态选项
const statusOptions = [
{ label: '全部', value: '' },
{ label: '待审核', value: 'pending' },
{ label: '已完成', value: 'approved' },
]
const {
modalVisible,
modalTitle,
modalAction,
modalLoading,
handleSave,
modalForm,
modalFormRef,
handleEdit,
handleDelete,
handleAdd,
} = useCRUD({
name: '估值评估',
initForm: {},
doCreate: api.createValuation,
doUpdate: api.updateValuation,
doDelete: api.deleteValuation,
refresh: () => $table.value?.handleSearch(),
})
// 审核备注弹窗
const approvalModalVisible = ref(false)
const approvalModalTitle = ref('')
const approvalForm = ref({
valuation_id: null,
admin_notes: '',
action: '', // 'approve' or 'reject'
})
const approvalFormRef = ref(null)
// 文案设置弹窗
const contentModalVisible = ref(false)
const contentForm = ref({
content: '',
})
const contentFormRef = ref(null)
onMounted(() => {
$table.value?.handleSearch()
})
// 状态标签渲染
const renderStatus = (status) => {
const statusMap = {
pending: { type: 'warning', text: '待审核' },
approved: { type: 'success', text: '已完成' },
}
const config = statusMap[status] || { type: 'default', text: '未知' }
return h(NTag, { type: config.type }, { default: () => config.text })
}
// 格式化金额
const formatAmount = (amount) => {
if (!amount) return '-'
return `¥${Number(amount).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
}
const columns = [
{
title: '编号',
key: 'id',
width: 80,
align: 'center',
},
{
title: '手机号',
key: 'phone',
width: 120,
align: 'center',
ellipsis: { tooltip: true },
},
{
title: '微信号',
key: 'wechat',
width: 120,
align: 'center',
ellipsis: { tooltip: true },
},
{
title: '评估结果',
key: 'valuation_result',
width: 120,
align: 'center',
render(row) {
return formatAmount(row.valuation_result)
},
},
{
title: '提交时间',
key: 'created_at',
width: 160,
align: 'center',
render(row) {
return formatDate(row.created_at)
},
},
{
title: '审核时间',
key: 'reviewed_at',
width: 160,
align: 'center',
render(row) {
return row.reviewed_at ? formatDate(row.reviewed_at) : '-'
},
},
{
title: '状态',
key: 'status',
width: 100,
align: 'center',
render(row) {
return renderStatus(row.status)
},
},
{
title: '操作',
key: 'actions',
width: 120,
align: 'center',
fixed: 'right',
render(row) {
if (row.status === 'pending') {
return h(
NButton,
{
size: 'small',
type: 'primary',
onClick: () => handleApprove(row),
},
{
default: () => '审核',
icon: renderIcon('mdi:check-circle-outline', { size: 16 }),
}
)
} else if (row.status === 'approved') {
return h(
NButton,
{
size: 'small',
type: 'info',
onClick: () => handleView(row),
},
{
default: () => '查看',
icon: renderIcon('mdi:eye-outline', { size: 16 }),
}
)
}
return null
},
},
]
// 打开审核弹窗
function handleApprove(row) {
approvalForm.value = {
valuation_id: row.id,
admin_notes: '',
action: 'approve',
}
approvalModalTitle.value = '审核估值评估'
approvalModalVisible.value = true
}
// 查看详情
function handleView(row) {
console.log('查看详情', row)
}
// 打开文案设置弹窗
function handleAddContent() {
contentForm.value = {
content: '',
}
contentModalVisible.value = true
}
// 保存文案设置
function handleContentSave() {
contentFormRef.value?.validate((errors) => {
if (!errors) {
console.log('保存文案设置', contentForm.value)
// 这里可以调用API保存文案
contentModalVisible.value = false
$message.success('文案上传并通知成功')
}
})
}
// 审核处理
async function handleApprovalSubmit(action) {
try {
approvalForm.value.action = action
await approvalFormRef.value?.validate()
const apiCall = action === 'approve' ? api.approveValuation : api.rejectValuation
await apiCall({
valuation_id: approvalForm.value.valuation_id,
admin_notes: approvalForm.value.admin_notes,
})
$message.success(action === 'approve' ? '审核通过成功' : '审核拒绝成功')
approvalModalVisible.value = false
$table.value?.handleSearch()
} catch (error) {
if (error?.message) {
$message.error(error.message)
}
}
}
const approvalRules = {
admin_notes: [
{
required: true,
message: '请输入审核备注',
trigger: ['input', 'blur'],
},
],
}
const contentRules = {
content: [
{
required: true,
message: '请输入文案内容',
trigger: ['input', 'blur'],
},
],
}
</script>
<template>
<CommonPage show-footer title="审核列表">
<!-- 表格 -->
<CrudTable
ref="$table"
v-model:query-items="queryItems"
:columns="columns"
:get-data="api.getValuationList"
>
<template #queryBar>
<QueryBarItem label="手机号" :label-width="80">
<NInput
v-model:value="queryItems.phone"
clearable
type="text"
placeholder="请输入手机号"
style="width: 200px"
@keypress.enter="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="微信号" :label-width="80">
<NInput
v-model:value="queryItems.wechat"
clearable
type="text"
placeholder="请输入微信号"
style="width: 200px"
@keypress.enter="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="提交时间" :label-width="80">
<NDatePicker
v-model:value="queryItems.created_at"
type="daterange"
clearable
placeholder="请选择提交时间"
style="width: 280px"
@update:value="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="审核时间" :label-width="80">
<NDatePicker
v-model:value="queryItems.reviewed_at"
type="daterange"
clearable
placeholder="请选择审核时间"
style="width: 280px"
@update:value="$table?.handleSearch()"
/>
</QueryBarItem>
<QueryBarItem label="状态" :label-width="80">
<NSelect
v-model:value="queryItems.status"
:options="statusOptions"
placeholder="请选择状态"
clearable
style="width: 200px"
@update:value="$table?.handleSearch()"
/>
</QueryBarItem>
</template>
<template #action>
<NButton type="primary" @click="handleAddContent">
<TheIcon icon="mdi:plus" :size="18" class="mr-5" />
新增文案设置
</NButton>
</template>
</CrudTable>
<!-- 查看详情弹窗 -->
<CrudModal
v-model:visible="modalVisible"
:title="modalTitle"
:loading="modalLoading"
:show-footer="false"
>
<NForm
ref="modalFormRef"
label-placement="left"
label-align="left"
:label-width="120"
:model="modalForm"
>
<NFormItem label="编号">
<span>{{ modalForm.id }}</span>
</NFormItem>
<NFormItem label="手机号">
<span>{{ modalForm.phone }}</span>
</NFormItem>
<NFormItem label="微信号">
<span>{{ modalForm.wechat }}</span>
</NFormItem>
<NFormItem label="评估结果">
<span>{{ formatAmount(modalForm.valuation_result) }}</span>
</NFormItem>
<NFormItem label="资产名称">
<span>{{ modalForm.asset_name || '-' }}</span>
</NFormItem>
<NFormItem label="所属机构">
<span>{{ modalForm.institution || '-' }}</span>
</NFormItem>
<NFormItem label="所属行业">
<span>{{ modalForm.industry || '-' }}</span>
</NFormItem>
<NFormItem label="非遗等级">
<span>{{ modalForm.heritage_level || '-' }}</span>
</NFormItem>
<NFormItem label="提交时间">
<span>{{ formatDate(modalForm.created_at) }}</span>
</NFormItem>
<NFormItem label="审核时间">
<span>{{ modalForm.reviewed_at ? formatDate(modalForm.reviewed_at) : '-' }}</span>
</NFormItem>
<NFormItem label="状态">
{{ renderStatus(modalForm.status) }}
</NFormItem>
<NFormItem label="管理员备注">
<span>{{ modalForm.admin_notes || '-' }}</span>
</NFormItem>
</NForm>
</CrudModal>
<!-- 审核弹窗 -->
<CrudModal
v-model:visible="approvalModalVisible"
:title="approvalModalTitle"
:show-footer="false"
>
<NForm
ref="approvalFormRef"
label-placement="left"
label-align="left"
:label-width="100"
:model="approvalForm"
:rules="approvalRules"
>
<NFormItem label="审核备注" path="admin_notes">
<NInput
v-model:value="approvalForm.admin_notes"
type="textarea"
:rows="4"
placeholder="请输入审核备注"
/>
</NFormItem>
<NFormItem>
<NSpace>
<NButton type="success" @click="handleApprovalSubmit('approve')">
<template #icon>
<TheIcon icon="mdi:check-circle-outline" :size="16" />
</template>
通过
</NButton>
<NButton type="error" @click="handleApprovalSubmit('reject')">
<template #icon>
<TheIcon icon="mdi:close-circle-outline" :size="16" />
</template>
拒绝
</NButton>
<NButton @click="approvalModalVisible = false">取消</NButton>
</NSpace>
</NFormItem>
</NForm>
</CrudModal>
<!-- 文案设置弹窗 -->
<CrudModal
v-model:visible="contentModalVisible"
title="新增文案设置"
:show-footer="false"
>
<NForm
ref="contentFormRef"
label-placement="left"
label-align="left"
:label-width="80"
:model="contentForm"
:rules="contentRules"
>
<NFormItem label="文案" path="content">
<NInput
v-model:value="contentForm.content"
type="textarea"
:rows="6"
placeholder="请输入文案内容"
/>
</NFormItem>
<NFormItem>
<div style="display: flex; justify-content: flex-end; gap: 12px; width: 100%">
<NButton @click="contentModalVisible = false">取消</NButton>
<NButton type="primary" @click="handleContentSave">
上传并通知
</NButton>
</div>
</NFormItem>
</NForm>
</CrudModal>
</CommonPage>
</template>