2025-07-14 11:11:33 +08:00
|
|
|
<template>
|
|
|
|
<GiPageLayout>
|
|
|
|
<div class="certification-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="certificationName">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-input v-model="searchForm.certificationName" placeholder="请输入证书名称" allow-clear style="width: 200px" />
|
2025-07-14 11:11:33 +08:00
|
|
|
</a-form-item>
|
|
|
|
|
|
|
|
<a-form-item label="证书类型" field="certificationType">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-input v-model="searchForm.certificationType" placeholder="请输入证书类型" allow-clear style="width: 200px" />
|
2025-07-14 11:11:33 +08:00
|
|
|
</a-form-item>
|
|
|
|
|
|
|
|
<a-form-item label="用户姓名" field="userName">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-input v-model="searchForm.userName" placeholder="请输入用户姓名" allow-clear style="width: 200px" />
|
2025-07-14 11:11:33 +08:00
|
|
|
</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">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-table :columns="columns" :data="certificationList" :pagination="paginationConfig" :loading="loading"
|
|
|
|
row-key="certificationId" @page-change="handlePageChange">
|
2025-07-14 11:11:33 +08:00
|
|
|
<template #userName="{ record }">
|
|
|
|
<span>{{ getUserName(record.userId) }}</span>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<template #certificationImage="{ record }">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-image v-if="record.certificationImage" :src="record.certificationImage" width="60" height="40"
|
|
|
|
fit="cover" show-loader preview />
|
2025-07-14 11:11:33 +08:00
|
|
|
<span v-else>-</span>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<template #validityPeriod="{ record }">
|
|
|
|
<span>{{ record.validityDateBegin }} 至 {{ record.validityDateEnd }}</span>
|
|
|
|
</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>
|
|
|
|
|
|
|
|
<!-- 新增/编辑资质信息模态框 -->
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-modal v-model:visible="modalVisible" :title="isEdit ? '编辑资质信息' : '新增资质信息'" width="700px" @ok="handleSubmit"
|
|
|
|
@cancel="handleCancel">
|
|
|
|
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
|
2025-07-14 11:11:33 +08:00
|
|
|
<a-row :gutter="16">
|
|
|
|
<a-col :span="12">
|
|
|
|
<a-form-item label="证书编号" field="certificationCode">
|
|
|
|
<a-input v-model="formData.certificationCode" placeholder="请输入证书编号" />
|
|
|
|
</a-form-item>
|
|
|
|
</a-col>
|
|
|
|
|
|
|
|
<a-col :span="12">
|
|
|
|
<a-form-item label="证书名称" field="certificationName">
|
|
|
|
<a-input v-model="formData.certificationName" placeholder="请输入证书名称" />
|
|
|
|
</a-form-item>
|
|
|
|
</a-col>
|
|
|
|
</a-row>
|
|
|
|
|
2025-07-24 22:02:13 +08:00
|
|
|
<a-form-item label="证书类型" field="certificationType">
|
|
|
|
<a-select v-model="formData.certificationType" placeholder="请选择证书类型">
|
|
|
|
<a-option v-for="item in CERTIFICATION_TYPE_OPTIONS" :key="item.value" :value="item.value"
|
|
|
|
:label="item.label">
|
|
|
|
{{ item.label }}
|
|
|
|
</a-option>
|
|
|
|
</a-select>
|
|
|
|
</a-form-item>
|
2025-07-14 11:11:33 +08:00
|
|
|
|
2025-07-24 22:02:13 +08:00
|
|
|
<a-col :span="12">
|
|
|
|
<a-form-item label="持证人" field="userId">
|
|
|
|
<a-select v-model="formData.userId" placeholder="请选择持证人" :loading="loadingUsers" allow-search
|
|
|
|
:filter-option="filterUserOption" @="console.log('d', formData)">
|
|
|
|
<a-option v-for="user in userList" :key="user.userId" :value="user.userId" :label="user.name">
|
|
|
|
{{ user.name }}({{ user.account }})
|
|
|
|
</a-option>
|
|
|
|
</a-select>
|
|
|
|
</a-form-item>
|
|
|
|
</a-col>
|
2025-07-14 11:11:33 +08:00
|
|
|
|
|
|
|
<a-row :gutter="16">
|
|
|
|
<a-col :span="12">
|
|
|
|
<a-form-item label="有效期开始" field="validityDateBegin">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-date-picker v-model="formData.validityDateBegin" placeholder="请选择有效期开始日期" style="width: 100%" />
|
2025-07-14 11:11:33 +08:00
|
|
|
</a-form-item>
|
|
|
|
</a-col>
|
|
|
|
|
|
|
|
<a-col :span="12">
|
|
|
|
<a-form-item label="有效期结束" field="validityDateEnd">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-date-picker v-model="formData.validityDateEnd" placeholder="请选择有效期结束日期" style="width: 100%" />
|
2025-07-14 11:11:33 +08:00
|
|
|
</a-form-item>
|
|
|
|
</a-col>
|
|
|
|
</a-row>
|
|
|
|
|
|
|
|
<a-form-item label="证书图片" field="certificationImage">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-upload :custom-request="handleUpload" :show-file-list="false" accept="image/*"
|
|
|
|
:before-upload="beforeUpload">
|
2025-07-14 11:11:33 +08:00
|
|
|
<template #upload-button>
|
|
|
|
<div class="upload-wrapper">
|
2025-07-24 20:53:50 +08:00
|
|
|
<a-image v-if="formData.certificationImage" :src="formData.certificationImage" width="200"
|
|
|
|
height="120" fit="cover" show-loader preview />
|
2025-07-14 11:11:33 +08:00
|
|
|
<div v-else class="upload-placeholder">
|
|
|
|
<icon-plus />
|
|
|
|
<div>点击上传证书图片</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</a-upload>
|
|
|
|
</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 CertificationAPI from '@/apis/employee'
|
|
|
|
import type { CertificationInfo, CertificationListParams, SimpleUserInfo } from '@/apis/employee'
|
|
|
|
import { uploadFile } from '@/apis/common/common'
|
|
|
|
|
|
|
|
defineOptions({ name: 'HRCertification' })
|
|
|
|
|
|
|
|
// 数据状态
|
|
|
|
const loading = ref(false)
|
|
|
|
const loadingUsers = ref(false)
|
|
|
|
const modalVisible = ref(false)
|
|
|
|
const isEdit = ref(false)
|
|
|
|
const formRef = ref()
|
|
|
|
|
|
|
|
// 列表数据
|
2025-07-24 20:53:50 +08:00
|
|
|
const certificationList = ref<CertificationAPI.CertificationListResponse>()
|
2025-07-14 11:11:33 +08:00
|
|
|
const userList = ref<SimpleUserInfo[]>([])
|
|
|
|
|
|
|
|
// 搜索表单
|
|
|
|
const searchForm = reactive<CertificationListParams>({
|
|
|
|
certificationName: '',
|
|
|
|
certificationType: '',
|
|
|
|
userName: ''
|
|
|
|
})
|
|
|
|
|
|
|
|
// 分页配置
|
|
|
|
const paginationConfig = reactive({
|
|
|
|
current: 1,
|
|
|
|
pageSize: 10,
|
|
|
|
total: 0,
|
|
|
|
showTotal: true,
|
|
|
|
showJumper: true
|
|
|
|
})
|
|
|
|
|
|
|
|
// 表单数据
|
|
|
|
const formData = reactive<CertificationInfo>({
|
|
|
|
certificationCode: '',
|
2025-07-24 20:53:50 +08:00
|
|
|
certificationImage: 'n',
|
2025-07-14 11:11:33 +08:00
|
|
|
certificationName: '',
|
|
|
|
certificationType: '',
|
|
|
|
userId: '',
|
|
|
|
validityDateBegin: '',
|
2025-07-24 20:53:50 +08:00
|
|
|
validityDateEnd: '',
|
|
|
|
// certificationTypeLabel: ''
|
2025-07-14 11:11:33 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
// 表单验证规则
|
|
|
|
const formRules = {
|
|
|
|
certificationCode: [
|
|
|
|
{ required: true, message: '请输入证书编号' }
|
|
|
|
],
|
|
|
|
certificationName: [
|
|
|
|
{ required: true, message: '请输入证书名称' }
|
|
|
|
],
|
|
|
|
certificationType: [
|
|
|
|
{ required: true, message: '请输入证书类型' }
|
|
|
|
],
|
|
|
|
userId: [
|
|
|
|
{ required: true, message: '请选择持证人' }
|
|
|
|
],
|
|
|
|
validityDateBegin: [
|
|
|
|
{ required: true, message: '请选择有效期开始日期' }
|
|
|
|
],
|
|
|
|
validityDateEnd: [
|
|
|
|
{ required: true, message: '请选择有效期结束日期' }
|
|
|
|
]
|
|
|
|
}
|
2025-07-24 22:02:13 +08:00
|
|
|
const CERTIFICATION_TYPE_OPTIONS = [
|
|
|
|
{ label: '高处作业', value: 'height-operation' },
|
|
|
|
{ label: '低压电工', value: 'low-voltage-operation' },
|
|
|
|
{ label: '高压电工', value: 'high-voltage-operation' },
|
|
|
|
{ label: '海上交通安全', value: 'maritime-traffic-safety' },
|
|
|
|
{ label: '驾驶证', value: 'driving-license' },
|
|
|
|
{ label: '防雷检测', value: 'lightning-protection-detection' },
|
|
|
|
{ label: '无人机驾驶', value: 'drone-driving' }
|
|
|
|
]
|
2025-07-14 11:11:33 +08:00
|
|
|
// 表格列定义
|
|
|
|
const columns = [
|
|
|
|
{
|
|
|
|
title: '证书编号',
|
|
|
|
dataIndex: 'certificationCode',
|
|
|
|
width: 150
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '证书名称',
|
|
|
|
dataIndex: 'certificationName',
|
|
|
|
width: 200
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '证书类型',
|
|
|
|
dataIndex: 'certificationType',
|
2025-07-24 22:02:13 +08:00
|
|
|
width: 150,
|
|
|
|
render: ({ record }) => {
|
|
|
|
const type = CERTIFICATION_TYPE_OPTIONS.find(item => item.value === record.certificationType)
|
|
|
|
return type ? type.label : '-'
|
|
|
|
}
|
2025-07-14 11:11:33 +08:00
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '持证人',
|
2025-07-24 20:53:50 +08:00
|
|
|
dataIndex: 'userName',
|
2025-07-14 11:11:33 +08:00
|
|
|
slotName: 'userName',
|
|
|
|
width: 120
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '证书图片',
|
|
|
|
dataIndex: 'certificationImage',
|
|
|
|
slotName: 'certificationImage',
|
|
|
|
width: 100
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '有效期',
|
|
|
|
dataIndex: 'validityPeriod',
|
|
|
|
slotName: 'validityPeriod',
|
|
|
|
width: 200
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '操作',
|
|
|
|
slotName: 'actions',
|
|
|
|
width: 150,
|
|
|
|
fixed: 'right'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
// 获取用户名称
|
|
|
|
const getUserName = (userId: string) => {
|
|
|
|
const user = userList.value.find(u => u.userId === userId)
|
|
|
|
return user ? user.name : '-'
|
|
|
|
}
|
|
|
|
|
|
|
|
// 用户搜索过滤
|
|
|
|
const filterUserOption = (inputValue: string, option: any) => {
|
|
|
|
const user = userList.value.find(u => u.userId === option.value)
|
|
|
|
if (!user) return false
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
const searchText = inputValue.toLowerCase()
|
2025-07-24 20:53:50 +08:00
|
|
|
return user.name.toLowerCase().includes(searchText) ||
|
|
|
|
user.account.toLowerCase().includes(searchText)
|
2025-07-14 11:11:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 获取用户列表
|
|
|
|
const getUserList = async () => {
|
|
|
|
try {
|
|
|
|
loadingUsers.value = true
|
|
|
|
const response = await CertificationAPI.getUserList()
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
console.log('用户列表响应:', response)
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
if (response.data) {
|
2025-07-24 20:53:50 +08:00
|
|
|
userList.value = response.data.map(item => ({
|
|
|
|
userId: item.userId,
|
|
|
|
name: item.name,
|
|
|
|
account: item.account,
|
|
|
|
})) || []
|
|
|
|
console.log('用户列表响应2:', userList.value)
|
2025-07-14 11:11:33 +08:00
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error('获取用户列表失败:', error)
|
|
|
|
Message.error('获取用户列表失败')
|
|
|
|
} finally {
|
|
|
|
loadingUsers.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取资质信息列表
|
|
|
|
const getCertificationList = async () => {
|
|
|
|
try {
|
|
|
|
loading.value = true
|
|
|
|
const params: CertificationListParams = {
|
|
|
|
...searchForm,
|
|
|
|
}
|
|
|
|
const response = await CertificationAPI.getCertificationList(params)
|
|
|
|
if (response.data) {
|
2025-07-24 20:53:50 +08:00
|
|
|
certificationList.value = response.data || []
|
2025-07-14 11:11:33 +08:00
|
|
|
paginationConfig.total = response.data.total || 0
|
2025-07-24 20:53:50 +08:00
|
|
|
console.log('cc', certificationList.value)
|
|
|
|
console.log('cd', response.data[0])
|
2025-07-14 11:11:33 +08:00
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
Message.error('获取资质信息列表失败')
|
|
|
|
} finally {
|
|
|
|
loading.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 文件上传前检查
|
|
|
|
const beforeUpload = (file: File) => {
|
|
|
|
const isImage = file.type.startsWith('image/')
|
|
|
|
if (!isImage) {
|
|
|
|
Message.error('只能上传图片文件')
|
|
|
|
return false
|
|
|
|
}
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
const isLt2M = file.size / 1024 / 1024 < 2
|
|
|
|
if (!isLt2M) {
|
|
|
|
Message.error('图片大小不能超过 2MB')
|
|
|
|
return false
|
|
|
|
}
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// 文件上传处理
|
|
|
|
const handleUpload = async (option: any) => {
|
|
|
|
try {
|
|
|
|
const uploadFormData = new FormData()
|
|
|
|
uploadFormData.append('file', option.fileItem.file)
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
const response = await uploadFile(uploadFormData)
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
if (response.data && response.data.url) {
|
|
|
|
formData.certificationImage = response.data.url
|
|
|
|
Message.success('图片上传成功')
|
|
|
|
option.onSuccess()
|
|
|
|
} else {
|
|
|
|
Message.error('图片上传失败')
|
|
|
|
option.onError()
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error('图片上传失败:', error)
|
|
|
|
Message.error('图片上传失败')
|
|
|
|
option.onError()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 搜索
|
|
|
|
const handleSearch = () => {
|
|
|
|
paginationConfig.current = 1
|
|
|
|
getCertificationList()
|
|
|
|
}
|
|
|
|
|
|
|
|
// 重置搜索
|
|
|
|
const handleReset = () => {
|
|
|
|
Object.assign(searchForm, {
|
|
|
|
certificationName: '',
|
|
|
|
certificationType: '',
|
|
|
|
userName: ''
|
|
|
|
})
|
|
|
|
paginationConfig.current = 1
|
|
|
|
getCertificationList()
|
|
|
|
}
|
|
|
|
|
|
|
|
// 分页变化
|
|
|
|
const handlePageChange = (page: number) => {
|
|
|
|
paginationConfig.current = page
|
|
|
|
getCertificationList()
|
|
|
|
}
|
|
|
|
|
|
|
|
// 显示新增模态框
|
|
|
|
const showAddModal = () => {
|
|
|
|
isEdit.value = false
|
|
|
|
resetForm()
|
|
|
|
modalVisible.value = true
|
|
|
|
}
|
|
|
|
|
|
|
|
// 编辑记录
|
|
|
|
const editRecord = (record: CertificationInfo) => {
|
|
|
|
isEdit.value = true
|
|
|
|
Object.assign(formData, record)
|
|
|
|
modalVisible.value = true
|
|
|
|
}
|
|
|
|
|
|
|
|
// 删除记录
|
|
|
|
const deleteRecord = (record: CertificationInfo) => {
|
|
|
|
Modal.confirm({
|
|
|
|
title: '确认删除',
|
|
|
|
content: '确定要删除这条资质信息吗?',
|
|
|
|
okText: '确认',
|
|
|
|
cancelText: '取消',
|
|
|
|
onOk: async () => {
|
|
|
|
try {
|
|
|
|
await CertificationAPI.deleteCertification(record.certificationId!)
|
|
|
|
Message.success('删除成功')
|
|
|
|
await getCertificationList()
|
|
|
|
} catch (error) {
|
|
|
|
console.error('删除失败:', error)
|
|
|
|
Message.error('删除失败')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// 表单提交
|
|
|
|
const handleSubmit = async () => {
|
|
|
|
try {
|
|
|
|
await formRef.value?.validate()
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
if (isEdit.value) {
|
|
|
|
await CertificationAPI.updateCertification(formData.certificationId!, formData)
|
|
|
|
Message.success('更新成功')
|
|
|
|
} else {
|
|
|
|
await CertificationAPI.createCertification(formData)
|
|
|
|
Message.success('创建成功')
|
|
|
|
}
|
2025-07-24 20:53:50 +08:00
|
|
|
|
2025-07-14 11:11:33 +08:00
|
|
|
modalVisible.value = false
|
|
|
|
resetForm()
|
|
|
|
await getCertificationList()
|
|
|
|
} catch (error) {
|
|
|
|
console.error('操作失败:', error)
|
|
|
|
Message.error('操作失败,请重试')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 取消操作
|
|
|
|
const handleCancel = () => {
|
|
|
|
modalVisible.value = false
|
|
|
|
resetForm()
|
|
|
|
}
|
|
|
|
|
|
|
|
// 重置表单
|
|
|
|
const resetForm = () => {
|
|
|
|
Object.assign(formData, {
|
|
|
|
certificationId: '',
|
|
|
|
certificationCode: '',
|
|
|
|
certificationImage: '',
|
|
|
|
certificationName: '',
|
|
|
|
certificationType: '',
|
|
|
|
userId: '',
|
|
|
|
validityDateBegin: '',
|
|
|
|
validityDateEnd: ''
|
|
|
|
})
|
|
|
|
formRef.value?.resetFields()
|
|
|
|
}
|
|
|
|
|
|
|
|
// 初始化
|
|
|
|
const init = async () => {
|
|
|
|
await Promise.all([
|
|
|
|
getUserList(),
|
|
|
|
getCertificationList()
|
|
|
|
])
|
|
|
|
}
|
|
|
|
|
|
|
|
// 组件挂载
|
|
|
|
onMounted(() => {
|
|
|
|
init()
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
.certification-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;
|
|
|
|
}
|
|
|
|
|
|
|
|
.upload-wrapper {
|
|
|
|
border: 1px dashed #d9d9d9;
|
|
|
|
border-radius: 6px;
|
|
|
|
cursor: pointer;
|
|
|
|
position: relative;
|
|
|
|
overflow: hidden;
|
|
|
|
transition: border-color 0.3s;
|
|
|
|
}
|
|
|
|
|
|
|
|
.upload-wrapper:hover {
|
|
|
|
border-color: #40a9ff;
|
|
|
|
}
|
|
|
|
|
|
|
|
.upload-placeholder {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
width: 200px;
|
|
|
|
height: 120px;
|
|
|
|
background-color: #fafafa;
|
|
|
|
color: #999;
|
|
|
|
}
|
|
|
|
|
|
|
|
.upload-placeholder .arco-icon {
|
|
|
|
font-size: 24px;
|
|
|
|
margin-bottom: 8px;
|
|
|
|
}
|
2025-07-24 20:53:50 +08:00
|
|
|
</style>
|