659 lines
17 KiB
Vue
659 lines
17 KiB
Vue
<template>
|
|
<GiPageLayout>
|
|
<div class="insurance-manage-container">
|
|
<div class="page-header">
|
|
<h2 class="page-title">保险信息管理</h2>
|
|
<a-button type="primary" @click="showAddModal">
|
|
<template #icon>
|
|
<icon-plus />
|
|
</template>
|
|
新增保险
|
|
</a-button>
|
|
</div>
|
|
|
|
<!-- 搜索表单 -->
|
|
<a-card class="search-card" :bordered="false">
|
|
<a-form :model="searchForm" layout="inline">
|
|
<a-form-item label="保险公司" field="insuranceCompanyId">
|
|
<a-select
|
|
v-model="searchForm.insuranceCompanyId"
|
|
placeholder="请选择保险公司"
|
|
allow-clear
|
|
:loading="loadingCompanies"
|
|
style="width: 200px"
|
|
>
|
|
<a-option
|
|
v-for="company in companyList"
|
|
:key="company.id"
|
|
:value="company.id"
|
|
>
|
|
{{ company.insuranceCompanyName }}
|
|
</a-option>
|
|
</a-select>
|
|
</a-form-item>
|
|
|
|
<a-form-item label="保险类型" field="insuranceTypeId">
|
|
<a-select
|
|
v-model="searchForm.insuranceTypeId"
|
|
placeholder="请选择保险类型"
|
|
allow-clear
|
|
:loading="loadingTypes"
|
|
style="width: 200px"
|
|
>
|
|
<a-option
|
|
v-for="type in typeList"
|
|
:key="type.id"
|
|
:value="type.id"
|
|
>
|
|
{{ type.insuranceTypeName }}
|
|
</a-option>
|
|
</a-select>
|
|
</a-form-item>
|
|
|
|
<a-form-item label="用户" field="userId">
|
|
<a-input
|
|
v-model="searchForm.userId"
|
|
placeholder="请输入用户ID"
|
|
style="width: 200px"
|
|
/>
|
|
</a-form-item>
|
|
|
|
<a-form-item>
|
|
<a-space>
|
|
<a-button type="primary" @click="handleSearch">
|
|
<template #icon>
|
|
<icon-search />
|
|
</template>
|
|
搜索
|
|
</a-button>
|
|
<a-button @click="handleReset">
|
|
<template #icon>
|
|
<icon-refresh />
|
|
</template>
|
|
重置
|
|
</a-button>
|
|
</a-space>
|
|
</a-form-item>
|
|
</a-form>
|
|
</a-card>
|
|
|
|
<!-- 保险信息表格 -->
|
|
<a-card class="table-card" :bordered="false">
|
|
<a-table
|
|
:columns="columns"
|
|
:data="insuranceList"
|
|
:pagination="paginationConfig"
|
|
:loading="loading"
|
|
row-key="id"
|
|
@page-change="handlePageChange"
|
|
>
|
|
<template #insuranceCompany="{ record }">
|
|
<span>{{ getCompanyName(record.insuranceCompanyId) }}</span>
|
|
</template>
|
|
|
|
<template #insuranceType="{ record }">
|
|
<span>{{ getTypeName(record.insuranceTypeId) }}</span>
|
|
</template>
|
|
|
|
<template #status="{ record }">
|
|
<a-tag
|
|
:color="record.status === 'active' ? 'green' : 'red'"
|
|
>
|
|
{{ record.status === 'active' ? '有效' : '失效' }}
|
|
</a-tag>
|
|
</template>
|
|
|
|
<template #actions="{ record }">
|
|
<a-space>
|
|
<a-button type="primary" size="small" @click="editRecord(record)">
|
|
编辑
|
|
</a-button>
|
|
<a-button type="primary" status="danger" size="small" @click="deleteRecord(record)">
|
|
删除
|
|
</a-button>
|
|
</a-space>
|
|
</template>
|
|
</a-table>
|
|
</a-card>
|
|
|
|
<!-- 新增/编辑保险信息模态框 -->
|
|
<a-modal
|
|
v-model:visible="modalVisible"
|
|
:title="isEdit ? '编辑保险信息' : '新增保险信息'"
|
|
width="600px"
|
|
@ok="handleSubmit"
|
|
@cancel="handleCancel"
|
|
>
|
|
<a-form
|
|
ref="formRef"
|
|
:model="formData"
|
|
:rules="formRules"
|
|
layout="vertical"
|
|
>
|
|
<a-row :gutter="16">
|
|
<a-col :span="12">
|
|
<a-form-item label="保险公司" field="insuranceCompanyId">
|
|
<a-select
|
|
v-model="formData.insuranceCompanyId"
|
|
placeholder="请选择保险公司"
|
|
:loading="loadingCompanies"
|
|
>
|
|
<a-option
|
|
v-for="company in companyList"
|
|
:key="company.insuranceCompanyId"
|
|
:value="company.insuranceCompanyId"
|
|
>
|
|
{{ company.insuranceCompanyName }}
|
|
</a-option>
|
|
</a-select>
|
|
</a-form-item>
|
|
</a-col>
|
|
|
|
<a-col :span="12">
|
|
<a-form-item label="保险类型" field="insuranceTypeId">
|
|
<a-select
|
|
v-model="formData.insuranceTypeId"
|
|
placeholder="请选择保险类型"
|
|
:loading="loadingTypes"
|
|
>
|
|
<a-option
|
|
v-for="type in typeList"
|
|
:key="type.insuranceTypeId"
|
|
:value="type.insuranceTypeId"
|
|
>
|
|
{{ type.insuranceTypeName }}
|
|
</a-option>
|
|
</a-select>
|
|
</a-form-item>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-row :gutter="16">
|
|
<a-col :span="12">
|
|
<a-form-item label="选择人员" field="userId">
|
|
|
|
<a-select
|
|
v-model="formData.userId"
|
|
placeholder="请选择员工"
|
|
allow-search
|
|
:filter-option="false"
|
|
@search="searchEmployees"
|
|
>
|
|
<a-option
|
|
v-for="employee in employeeOptions"
|
|
:key="employee.userId"
|
|
:value="employee.userId"
|
|
>
|
|
{{ employee.nickname || employee.name }} ({{ employee.deptName }})
|
|
</a-option>
|
|
</a-select>
|
|
</a-form-item>
|
|
</a-col>
|
|
|
|
|
|
<a-col :span="12">
|
|
<a-form-item label="保险单号" field="insuranceBillCode">
|
|
<a-input v-model="formData.insuranceBillCode" placeholder="请输入保险单号" />
|
|
</a-form-item>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-row :gutter="16">
|
|
<a-col :span="12">
|
|
<a-form-item label="生效日期" field="effectiveDate">
|
|
<a-date-picker
|
|
v-model="formData.effectiveDate"
|
|
placeholder="请选择生效日期"
|
|
style="width: 100%"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
|
|
<a-col :span="12">
|
|
<a-form-item label="到期日期" field="expireDate">
|
|
<a-date-picker
|
|
v-model="formData.expireDate"
|
|
placeholder="请选择到期日期"
|
|
style="width: 100%"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-row :gutter="16">
|
|
<a-col :span="12">
|
|
<a-form-item label="保险金额" field="insuranceAmount">
|
|
<a-input-number
|
|
v-model="formData.insuranceAmount"
|
|
placeholder="请输入保险金额"
|
|
:precision="2"
|
|
style="width: 100%"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
|
|
<a-col :span="12">
|
|
<a-form-item label="保险费" field="insurancePremium">
|
|
<a-input-number
|
|
v-model="formData.insurancePremium"
|
|
placeholder="请输入保险费"
|
|
:precision="2"
|
|
style="width: 100%"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-form-item label="受益人" field="beneficiary">
|
|
<a-input v-model="formData.beneficiary" placeholder="请输入受益人" />
|
|
</a-form-item>
|
|
<a-col :span="12">
|
|
<a-form-item label="上传保单" field="attachInfoId">
|
|
<a-upload
|
|
:custom-request="uploadInsuranceFile"
|
|
>
|
|
<a-button type="primary">
|
|
<template #icon><icon-upload /></template>
|
|
上传保单
|
|
</a-button>
|
|
</a-upload>
|
|
</a-form-item>
|
|
</a-col>
|
|
<a-form-item label="备注" field="remark">
|
|
<a-textarea
|
|
v-model="formData.remark"
|
|
placeholder="请输入备注"
|
|
:auto-size="{ minRows: 3, maxRows: 6 }"
|
|
/>
|
|
</a-form-item>
|
|
</a-form>
|
|
</a-modal>
|
|
</div>
|
|
</GiPageLayout>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, reactive, onMounted, computed } from 'vue'
|
|
import { Message, Modal } from '@arco-design/web-vue'
|
|
import { IconPlus, IconSearch, IconRefresh } from '@arco-design/web-vue/es/icon'
|
|
import * as InsuranceAPI from '@/apis/insurance'
|
|
import { listAllUser } from '@/apis/system/user'
|
|
import type { InsuranceInfo, InsuranceListParams } from '@/apis/insurance'
|
|
import * as InsuranceCompanyAPI from '@/apis/insurance-company'
|
|
import * as InsuranceTypeAPI from '@/apis/insurance-type'
|
|
import { addAttachInsurance } from '@/apis/attach-info'
|
|
|
|
// 数据状态
|
|
const loading = ref(false)
|
|
const loadingCompanies = ref(false)
|
|
const loadingTypes = ref(false)
|
|
const modalVisible = ref(false)
|
|
const isEdit = ref(false)
|
|
const formRef = ref()
|
|
|
|
// 列表数据
|
|
const insuranceList = ref<InsuranceInfo[]>([])
|
|
const companyList = ref<any[]>([])
|
|
const typeList = ref<any[]>([])
|
|
|
|
// 搜索表单
|
|
const searchForm = reactive<InsuranceListParams>({
|
|
insuranceCompanyId: '',
|
|
insuranceTypeId: '',
|
|
userId: ''
|
|
})
|
|
|
|
// 分页配置
|
|
const paginationConfig = reactive({
|
|
current: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
showTotal: true,
|
|
showJumper: true
|
|
})
|
|
|
|
// 表单数据
|
|
const formData = reactive<InsuranceInfo>({
|
|
id: '',
|
|
attachInfoId: '',
|
|
insuranceCompanyId: '',
|
|
insuranceTypeId: '',
|
|
userId: '',
|
|
insuranceBillCode: '',
|
|
effectiveDate: '',
|
|
expireDate: '',
|
|
insuranceAmount: 0,
|
|
insurancePremium: 0,
|
|
beneficiary: '',
|
|
remark: ''
|
|
})
|
|
|
|
// 表单验证规则
|
|
const formRules = {
|
|
insuranceCompanyId: [
|
|
{ required: true, message: '请选择保险公司' }
|
|
],
|
|
insuranceTypeId: [
|
|
{ required: true, message: '请选择保险类型' }
|
|
],
|
|
userId: [
|
|
{ required: true, message: '请输入用户ID' }
|
|
],
|
|
insuranceBillCode: [
|
|
{ required: true, message: '请输入保险单号' }
|
|
],
|
|
effectiveDate: [
|
|
{ required: true, message: '请选择生效日期' }
|
|
],
|
|
expireDate: [
|
|
{ required: true, message: '请选择到期日期' }
|
|
],
|
|
insuranceAmount: [
|
|
{ required: true, message: '请输入保险金额' }
|
|
],
|
|
insurancePremium: [
|
|
{ required: true, message: '请输入保险费' }
|
|
]
|
|
}
|
|
|
|
// 表格列定义
|
|
const columns = [
|
|
{
|
|
title: '用户名称',
|
|
dataIndex: 'name',
|
|
width: 100
|
|
},
|
|
{
|
|
title: '保险公司',
|
|
dataIndex: 'insuranceCompanyName',
|
|
slotName: 'insuranceCompanyName',
|
|
width: 150
|
|
},
|
|
{
|
|
title: '保险类型',
|
|
dataIndex: 'insuranceTypeName',
|
|
slotName: 'insuranceTypeName',
|
|
width: 120
|
|
},
|
|
{
|
|
title: '保险单号',
|
|
dataIndex: 'insuranceBillCode',
|
|
width: 150
|
|
},
|
|
{
|
|
title: '生效日期',
|
|
dataIndex: 'effectiveDate',
|
|
width: 120
|
|
},
|
|
{
|
|
title: '到期日期',
|
|
dataIndex: 'expireDate',
|
|
width: 120
|
|
},
|
|
{
|
|
title: '保险金额',
|
|
dataIndex: 'insuranceAmount',
|
|
width: 120
|
|
},
|
|
{
|
|
title: '状态',
|
|
dataIndex: 'status',
|
|
slotName: 'status',
|
|
width: 80
|
|
},
|
|
{
|
|
title: '操作',
|
|
slotName: 'actions',
|
|
width: 150,
|
|
fixed: 'right'
|
|
}
|
|
]
|
|
|
|
// 获取保险公司名称
|
|
const getCompanyName = (id: string) => {
|
|
const company = companyList.value.find(c => c.id === id)
|
|
return company ? company.insuranceCompanyName : '-'
|
|
}
|
|
// 获取保险类型名称
|
|
const getTypeName = (id: string) => {
|
|
const type = typeList.value.find(t => t.id === id)
|
|
return type ? type.insuranceTypeName : '-'
|
|
}
|
|
|
|
// 获取保险公司列表
|
|
const getCompanyList = async () => {
|
|
try {
|
|
loadingCompanies.value = true
|
|
const response = await InsuranceCompanyAPI.getInsuranceCompanyList({})
|
|
|
|
console.log('保险公司列表响应:', response)
|
|
|
|
if (response.data) {
|
|
companyList.value = response.data || []
|
|
}
|
|
} catch (error) {
|
|
console.error('获取保险公司列表失败:', error)
|
|
Message.error('获取保险公司列表失败')
|
|
} finally {
|
|
loadingCompanies.value = false
|
|
}
|
|
}
|
|
|
|
// 获取保险类型列表
|
|
const getTypeList = async () => {
|
|
try {
|
|
loadingTypes.value = true
|
|
const response = await InsuranceTypeAPI.getInsuranceTypeList()
|
|
|
|
console.log('保险类型列表响应:', response)
|
|
|
|
if (response.data) {
|
|
typeList.value = response.data || []
|
|
}
|
|
} catch (error) {
|
|
console.error('获取保险类型列表失败:', error)
|
|
Message.error('获取保险类型列表失败')
|
|
} finally {
|
|
loadingTypes.value = false
|
|
}
|
|
}
|
|
|
|
// 获取保险信息列表
|
|
const getInsuranceList = async () => {
|
|
try {
|
|
loading.value = true
|
|
const params: InsuranceListParams = {
|
|
...searchForm,
|
|
current: paginationConfig.current,
|
|
size: paginationConfig.pageSize
|
|
}
|
|
|
|
const response = await InsuranceAPI.getInsuranceList(params)
|
|
|
|
console.log('保险信息列表响应:', response)
|
|
|
|
if (response.data) {
|
|
insuranceList.value = response.data || []
|
|
paginationConfig.total = response.data.total || 0
|
|
}
|
|
} catch (error) {
|
|
console.error('获取保险信息列表失败:', error)
|
|
Message.error('获取保险信息列表失败')
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
// 搜索员工
|
|
const searchEmployees = (keyword: string) => {
|
|
fetchEmployeeOptions(keyword)
|
|
}
|
|
const employeeOptions = ref<any[]>([])
|
|
// 获取员工列表
|
|
const fetchEmployeeOptions = async (keyword?: string) => {
|
|
try {
|
|
const response = await listAllUser({ description: keyword })
|
|
employeeOptions.value = response.data || []
|
|
} catch (error) {
|
|
console.error('获取员工列表失败:', error)
|
|
Message.error('获取员工列表失败')
|
|
} finally {
|
|
}
|
|
}
|
|
const uploadInsuranceFile = async (options: any) => {
|
|
if(!formData.userId || !formData.insuranceBillCode){
|
|
Message.error('请先选择员工和输入保险单号')
|
|
return
|
|
}
|
|
const uploadForm = new FormData()
|
|
uploadForm.append('file', options.fileItem.file)
|
|
uploadForm.append('userDefinedPath', `${formData.userId}/${formData.insuranceBillCode}`)
|
|
const response = await addAttachInsurance(uploadForm)
|
|
console.log('上传保险文件响应:', response)
|
|
formData.attachInfoId = response.data
|
|
}
|
|
// 搜索
|
|
const handleSearch = () => {
|
|
paginationConfig.current = 1
|
|
getInsuranceList()
|
|
}
|
|
|
|
// 重置搜索
|
|
const handleReset = () => {
|
|
Object.assign(searchForm, {
|
|
insuranceCompanyId: '',
|
|
insuranceTypeId: '',
|
|
userId: ''
|
|
})
|
|
paginationConfig.current = 1
|
|
getInsuranceList()
|
|
}
|
|
|
|
// 分页变化
|
|
const handlePageChange = (page: number) => {
|
|
paginationConfig.current = page
|
|
getInsuranceList()
|
|
}
|
|
|
|
// 显示新增模态框
|
|
const showAddModal = () => {
|
|
isEdit.value = false
|
|
resetForm()
|
|
modalVisible.value = true
|
|
}
|
|
|
|
// 编辑记录
|
|
const editRecord = (record: InsuranceInfo) => {
|
|
isEdit.value = true
|
|
Object.assign(formData, record)
|
|
modalVisible.value = true
|
|
}
|
|
|
|
// 删除记录
|
|
const deleteRecord = (record: InsuranceInfo) => {
|
|
Modal.confirm({
|
|
title: '确认删除',
|
|
content: '确定要删除这条保险信息吗?',
|
|
okText: '确认',
|
|
cancelText: '取消',
|
|
onOk: async () => {
|
|
try {
|
|
await InsuranceAPI.deleteInsurance(record.id!)
|
|
Message.success('删除成功')
|
|
await getInsuranceList()
|
|
} catch (error) {
|
|
console.error('删除失败:', error)
|
|
Message.error('删除失败')
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// 表单提交
|
|
const handleSubmit = async () => {
|
|
try {
|
|
await formRef.value?.validate()
|
|
|
|
if (isEdit.value) {
|
|
await InsuranceAPI.updateInsurance(formData.id!, formData)
|
|
Message.success('更新成功')
|
|
} else {
|
|
await InsuranceAPI.createInsurance(formData)
|
|
Message.success('创建成功')
|
|
}
|
|
|
|
modalVisible.value = false
|
|
resetForm()
|
|
await getInsuranceList()
|
|
} catch (error) {
|
|
console.error('操作失败:', error)
|
|
Message.error('操作失败,请重试')
|
|
}
|
|
}
|
|
|
|
// 取消操作
|
|
const handleCancel = () => {
|
|
modalVisible.value = false
|
|
resetForm()
|
|
}
|
|
|
|
// 重置表单
|
|
const resetForm = () => {
|
|
Object.assign(formData, {
|
|
id: '',
|
|
attachInfoId: '',
|
|
insuranceCompanyId: '',
|
|
insuranceTypeId: '',
|
|
userId: '',
|
|
insuranceBillCode: '',
|
|
effectiveDate: '',
|
|
expireDate: '',
|
|
insuranceAmount: 0,
|
|
insurancePremium: 0,
|
|
beneficiary: '',
|
|
remark: ''
|
|
})
|
|
formRef.value?.resetFields()
|
|
}
|
|
|
|
// 初始化
|
|
const init = async () => {
|
|
await Promise.all([
|
|
getCompanyList(),
|
|
getTypeList(),
|
|
fetchEmployeeOptions(),
|
|
getInsuranceList()
|
|
])
|
|
}
|
|
|
|
// 组件挂载
|
|
onMounted(() => {
|
|
init()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.insurance-manage-container {
|
|
padding: 20px;
|
|
}
|
|
|
|
.page-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.page-title {
|
|
margin: 0;
|
|
font-size: 18px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.search-card {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.table-card {
|
|
margin-bottom: 20px;
|
|
}
|
|
</style> |