2025-03-24 17:14:27 +08:00

527 lines
16 KiB
Vue

<template>
<lay-container fluid="true" style="padding: 20px">
<!-- 搜索区域改为卡片式布局 -->
<lay-row :space="10">
<lay-col :md="24">
<lay-card>
<div class="search-form-wrapper">
<lay-form style="margin-top: 20px">
<lay-row style="min-width: 1400px">
<lay-col :md="5">
<lay-form-item label="记录状态:">
<lay-select v-model="searchForm.status" placeholder="请选择状态" style="width: 180px;">
<lay-select-option :value="1" label="待审核"></lay-select-option>
<lay-select-option :value="2" label="审核通过"></lay-select-option>
<lay-select-option :value="3" label="已驳回"></lay-select-option>
</lay-select>
</lay-form-item>
</lay-col>
<lay-col :md="6">
<lay-form-item label-width="0">
<lay-button type="primary" @click="search">查询</lay-button>
<lay-button @click="resetSearch" style="margin-left: 10px">重置</lay-button>
</lay-form-item>
</lay-col>
</lay-row>
</lay-form>
</div>
</lay-card>
</lay-col>
<!-- 列表区域 -->
<lay-col :md="24">
<lay-card>
<div style="padding: 10px">
<span style="font-size: 18px;vertical-align: center;margin-right: 20px">个人记录列表</span>
<lay-button type="primary" @click="openNew()" size="sm">新增记录</lay-button>
</div>
<lay-table size="lg" height="500px" :columns="columns" :data-source="dataSource" :page="page" @change="change">
<template v-slot:status="{ data }">
<span v-if="data.status == 1" style="color: #1E9FFF">待审核</span>
<span v-if="data.status == 2" style="color: #009688">审核通过</span>
<span v-if="data.status == 3" style="color: #009688">已驳回</span>
</template>
<template v-slot:assessment_type="{ data }">
<lay-tag :type="data.assessment_type == 1 ? 'primary' : 'danger'">
{{ data.assessment_type == 1 ? '加分' : '减分' }}
</lay-tag>
</template>
<template v-slot:operator="{ data }">
<lay-space size="lg">
<span style="color: #00A394;cursor: pointer" @click="showDetail(data)">详情</span>
<span v-if="data.status == 1" style="color: #00A394;cursor: pointer" @click="editRecord(data)">编辑</span>
<!-- <lay-popconfirm trigger="click" content="确定要删除吗?" @confirm="deleteRecord(data)">
<span style="color: #00A394;cursor: pointer">删除</span>
</lay-popconfirm> -->
</lay-space>
</template>
</lay-table>
</lay-card>
</lay-col>
<lay-layer v-model="showForm" :title="isEdit ? '编辑记录' : '新增记录'" :type="4" :shade="true" :area="['950px', '100%']"
:btn="formButtons">
<lay-container fluid="true" style="padding: 20px">
<lay-form :model="formData">
<lay-form-item required label="考评对象" prop="user_id">
<lay-select v-model="formData.user_id" placeholder="请选择考评对象" :show-search="true">
<lay-select-option v-for="user in userList" :key="user.id" :value="user.id" :label="user.nickname">
</lay-select-option>
</lay-select>
</lay-form-item>
<lay-form-item required label="考评类型" prop="assessment_type">
<lay-select v-model="formData.assessment_type" placeholder="请选择">
<lay-select-option :value="1" label="加分"></lay-select-option>
<lay-select-option :value="2" label="减分"></lay-select-option>
</lay-select>
</lay-form-item>
<lay-form-item required label="考评项目" prop="assessment_project" :tips="selectedItemTips">
<lay-select v-model="formData.assessment_project" placeholder="请选择" :show-search="true"
@change="handleItemChange">
<lay-select-option v-for="item in evaluationItems" :key="item.id" :value="item.id"
:label="item.project_name"></lay-select-option>
</lay-select>
</lay-form-item>
<lay-form-item required label="分值" :tips="selectedItemTipsScore" prop="score_value">
<lay-input-number :max="maxInput.single_score_max" :min="maxInput.single_score_min" v-model="formData.score_value" placeholder="请输入分值"></lay-input-number>
</lay-form-item>
<lay-form-item required label="发生时间" prop="fsdate">
<lay-date-picker v-model="formData.fsdate" placeholder="发生时间" type="datetime"></lay-date-picker>
</lay-form-item>
<lay-form-item required label="证明人" prop="zm_user_id">
<lay-select v-model="formData.zm_user_id" placeholder="请选择证明人" :show-search="true">
<lay-select-option v-for="user in userList" :key="user.id" :value="user.id" :label="user.nickname">
</lay-select-option>
</lay-select>
</lay-form-item>
<lay-form-item label="附件" mode="block">
<lay-upload ref="uploadRef" :number="1" field="file" :size="1000"
:headers="{ token: userStore.token }" url="/api/common/upload" @cutdone="getCutDone"
v-model="file1" :auto="true" :cut="false" :cutOptions="cutOptions" @done="getFileDone">
<template #preview>
<a v-if="formData.fj_url!=''" style="color: #009688" :href="formData.fj_url" target="_blank">
{{ formData.fj_url }}
</a>
</template>
</lay-upload>
</lay-form-item>
<lay-form-item label="备注" prop="notes">
<lay-textarea v-model="formData.notes" placeholder="请输入备注"></lay-textarea>
</lay-form-item>
</lay-form>
</lay-container>
</lay-layer>
<lay-layer v-model="showDetailDialog" title="记录详情" :area="['950px', '100%']" :shade="true" :type="4">
<div style="padding: 20px">
<lay-descriptions title="基本信息" :column="2" border>
<lay-descriptions-item label="考评对象">
{{ detailData.nickname }}
</lay-descriptions-item>
<lay-descriptions-item label="考评类型">
{{ detailData.assessment_type == 1 ? '加分' : '减分' }}
</lay-descriptions-item>
<lay-descriptions-item label="考评项目">
{{ detailData.project_name }}
</lay-descriptions-item>
<lay-descriptions-item label="分值">
{{ detailData.score_value }}
</lay-descriptions-item>
<lay-descriptions-item label="发生时间">
{{ detailData.fsdate }}
</lay-descriptions-item>
<lay-descriptions-item label="证明人">
{{ detailData.zm_nickname }}
</lay-descriptions-item>
</lay-descriptions>
<lay-descriptions title="其他信息" :column="2" border style="margin-top: 20px">
<lay-descriptions-item label="状态">
<lay-tag size="sm" type="primary">
{{ detailData.status == 1 ? '待审核' : '审核通过' }}
</lay-tag>
</lay-descriptions-item>
<lay-descriptions-item label="备注" :span="2">
{{ detailData.notes || '暂无备注' }}
</lay-descriptions-item>
</lay-descriptions>
<lay-descriptions v-if="detailData.fj_url" title="附件信息" :column="1" border style="margin-top: 20px">
<lay-descriptions-item label="附件">
<a style="color: #009688" :href="detailData.fj_url" target="_blank">查看附件</a>
</lay-descriptions-item>
</lay-descriptions>
<div style="text-align: center; margin-top: 20px;">
<lay-button type="primary" @click="showDetailDialog = false">关闭</lay-button>
</div>
</div>
</lay-layer>
</lay-row>
</lay-container>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { layer } from '@layui/layer-vue'
import { scoringGetHierarchicalData, getDoctorName, getAddition, getAdditionCreate, getAdditionUpdate, getAdditionDelete } from '@/api/module/home'
import { useUserStore } from '@/store/user'
interface EvaluationItem {
id: number
project_name: string
scoring_criteria: string
single_score_max: number
single_score_min: number
}
// 定义用户接口
interface User {
id: number
nickname: string
}
// 修改 userList 的类型定义
const userList = ref<User[]>([])
const detailData = ref<DetailData>({
nickname: '',
assessment_type: 1,
project_name: '',
score_value: 0,
fsdate: '',
zm_nickname: '',
fj_url: '',
notes: '',
status: 1,
create_time: ''
})
const formData = reactive<FormData>({
id: 0,
user_id: '',
assessment_type: 1,
assessment_project: '',
score_value: 0,
fsdate: '',
zm_user_id: '',
fj_url: '',
notes: ''
})
// 修改文件上传相关的类型
interface UploadResponse {
data: string
msg: string
}
const getCutDone = (res: UploadResponse) => {
console.log("getCutDone", res)
cutUrl.value = res.msg
}
const getFileDone = (res: UploadResponse) => {
const date = JSON.parse(res.data)
console.log("getFileDone", date)
formData.fj_url = date.data.fullurl
}
const selectedItemTipsScore = ref('');
// 修改 handleItemChange 的实现
const handleItemChange = (value: string | number | object) => {
const selectedItem = evaluationItems.value.find(item => item.id == value)
console.log(selectedItem);
if (selectedItem) {
maxInput.value.single_score_max = selectedItem.single_score_max
maxInput.value.single_score_min = selectedItem.single_score_min
selectedItemTips.value = selectedItem.scoring_criteria || '';
selectedItemTipsScore.value = selectedItem.single_score_max + '分,最低' + selectedItem.single_score_min + '分';
}
}
onMounted(() => {
getAdditionList()
getHierarchicalData()
getUserList()
})
// 添加搜索表单数据
const searchForm = reactive({
status: ''
})
const cutOptions = {
copperOption: {
center: false,
aspectRatio: 1,
}
}
const cutUrl = ref("");
const uploadRef = ref(null)
const file1 = ref([]);
// 分页配置
const page = reactive({
total: 1, // 总条数
current: 1, // 当前页
limit: 10, // 每页条数
showRefresh: true, // 显示刷新按钮
showLimit: true // 显示条数选择器
})
const getAdditionList = () => {
const params = {
page: page.current,
size: page.limit,
...searchForm
}
getAddition(params).then((res) => {
console.log(res);
if (res.code == 1) {
dataSource.value = res.data.data;
page.total = res.data.count;
} else {
layer.msg(res.msg, { icon: 2 })
}
})
}
const evaluationItems = ref<EvaluationItem[]>([])
const selectedItemTips = ref('')
const getHierarchicalData = () => {
scoringGetHierarchicalData({page:1,size:1000}).then((res) => {
console.log(res)
if (res.code == 1) {
evaluationItems.value = res.data;
} else {
layer.msg(res.msg, { icon: 2 })
}
})
}
// 列表数据
const dataSource = ref()
// 表单显示控制
const showForm = ref(false)
const isEdit = ref(false)
const showDetailDialog = ref(false)
// 表单按钮定义
const formButtons = ref([
{
text: "确认",
callback: async () => {
// 分开检查必填字段是否为空
if (!formData.user_id) {
layer.msg('考评对象不能为空!', { icon: 2 });
return;
}
if (!formData.assessment_project) {
layer.msg('考评项目不能为空!', { icon: 2 });
return;
}
if (!formData.score_value) {
layer.msg('分值不能为空!', { icon: 2 });
return;
}
if (!formData.fsdate) {
layer.msg('发生时间不能为空!', { icon: 2 });
return;
}
if (!formData.zm_user_id) {
layer.msg('证明人不能为空!', { icon: 2 });
return;
}
formData.tb_user_id = userStore.userInfo.id;
formData.group_id = userStore.userInfo.group_id;
try {
if (isEdit.value) {
// 调用编辑接口
await getAdditionUpdate(formData);
layer.msg('编辑成功!', { icon: 1 });
} else {
// 调用新增接口
await getAdditionCreate(formData);
layer.msg('新增成功!', { icon: 1 });
}
showForm.value = false;
getAdditionList();
} catch (error) {
layer.msg('操作失败!', { icon: 2 });
}
}
},
{
text: "取消",
callback: () => {
showForm.value = false
}
}
])
// 添加搜索方法
const search = () => {
page.current = 1;
dataSource.value = [];
getAdditionList()
}
// 重置搜索
const resetSearch = () => {
searchForm.status = '';
// 重新获取所有数据
getAdditionList()
}
// 分页变化处理
const change = ({ current, limit }: { current: number, limit: number }) => {
page.current = current
page.limit = limit
// getListData() // 重新获取数据
}
const maxInput = ref({
single_score_max:10,
single_score_min:0,
});
const getUserList = () => {
getDoctorName({}).then((res) => {
if (res.code === 1) {
userList.value = res.data;
}
})
}
// 表格列定义
const columns = [
{
title: "序号",
width: "80px",
key: "id",
align: 'center'
},
{
title: "发生时间",
width: "160px",
key: "fsdate",
align: 'center'
},
{
title: "考评对象",
width: "120px",
key: "nickname",
align: 'center'
},
{
title: "考评类型",
width: "100px",
key: "assessment_type",
align: 'center',
customSlot: 'assessment_type'
},
{
title: "考评项",
width: "150px",
key: "project_name",
align: 'center'
},
{
title: "分值",
width: "80px",
key: "score_value",
align: 'center'
},
{
title: "记录状态",
width: "100px",
customSlot: 'status',
key: "status",
align: 'center'
},
{
title: '操作',
width: '180px',
customSlot: 'operator',
key: 'operator',
align: 'center',
fixed: 'right'
}
]
// 按钮事件处理
const openNew = () => {
isEdit.value = false
resetForm()
showForm.value = true
}
const editRecord = (data: any) => {
isEdit.value = true; // 设置为编辑状态
formData.id = data.id; // 复制记录的 ID
formData.user_id = data.user_id; // 复制考评对象
formData.assessment_type = data.assessment_type; // 复制考评类型
formData.assessment_project = data.assessment_project; // 复制考评项目
formData.score_value = data.score_value; // 复制分值
formData.fsdate = data.fsdate; // 复制发生时间
formData.zm_user_id = data.zm_user_id; // 复制证明人
formData.fj_url = data.fj_url; // 复制附件 URL
formData.notes = data.notes; // 复制备注
showForm.value = true; // 显示表单
}
const showDetail = (data: any) => {
detailData.value = data
showDetailDialog.value = true
}
const deleteRecord = async (data: any) => {
try {
await getAdditionDelete({id: data.id}); // 调用删除接口
layer.msg('删除成功!', { icon: 1 });
} catch (error) {
layer.msg('删除失败!', { icon: 2 });
}
getAdditionList()
}
const resetForm = () => {
formData.id = 0
formData.user_id = ''
formData.assessment_type = 1
formData.assessment_project = ''
formData.score_value = 0
formData.fsdate = ''
formData.zm_user_id = ''
formData.fj_url = ''
formData.notes = ''
}
const userStore = useUserStore();
</script>
<style>
.layui-table-header .layui-table-cell {
background-color: #ECF8FA !important;
}
/* 移除之前的搜索区域样式 */
.layui-inline {
margin-right: 15px;
}
.search-form-wrapper {
width: 100%;
overflow-x: auto;
}
.search-form-wrapper::-webkit-scrollbar {
height: 8px;
}
.search-form-wrapper::-webkit-scrollbar-thumb {
background-color: #e0e0e0;
border-radius: 4px;
}
.search-form-wrapper::-webkit-scrollbar-track {
background-color: #f5f5f5;
}
</style>