Industrial-image-management.../src/views/regulation/repository.vue

467 lines
12 KiB
Vue

<template>
<div class="system-regulation">
<a-card title="已公告制度确认" :bordered="false">
<!-- 搜索区域 -->
<div class="search-container">
<a-form layout="inline" :model="searchForm" class="search-form">
<a-form-item label="制度标题">
<a-input
v-model="searchForm.title"
placeholder="请输入制度标题"
allow-clear
style="width: 200px"
/>
</a-form-item>
<a-form-item label="公示人">
<a-input
v-model="searchForm.proposer"
placeholder="请输入公示人"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="确认状态">
<a-select
v-model="searchForm.confirmStatus"
placeholder="请选择状态"
allow-clear
style="width: 150px"
>
<a-option value="">全部</a-option>
<a-option value="CONFIRMED">已确认</a-option>
<a-option value="PENDING">待确认</a-option>
</a-select>
</a-form-item>
<a-form-item>
<a-space>
<a-button type="primary" @click="search">
<template #icon><icon-search /></template>
搜索
</a-button>
<a-button @click="reset">
<template #icon><icon-refresh /></template>
重置
</a-button>
</a-space>
</a-form-item>
</a-form>
</div>
<a-table
:columns="columns"
:data="tableData"
:loading="loading"
:pagination="pagination"
@page-change="onPageChange"
@page-size-change="onPageSizeChange"
>
<template #toolbar-left>
<span class="search-result-info">
共找到 <strong>{{ pagination.total }}</strong> 条记录
</span>
</template>
<template #confirmStatus="{ record }">
<a-tag :color="record.confirmStatus === 'CONFIRMED' ? 'green' : 'orange'">
{{ record.confirmStatus === 'CONFIRMED' ? '已确认' : '待确认' }}
</a-tag>
</template>
<template #operations="{ record }">
<a-space>
<a-button type="text" size="small" @click="handleView(record)">
查看详情
</a-button>
<a-button type="text" size="small" @click="handleDownload(record)">
下载
</a-button>
</a-space>
</template>
</a-table>
</a-card>
<!-- 制度详情弹窗 -->
<a-modal
v-model:visible="detailModalVisible"
title="制度详情"
width="800px"
:footer="false"
>
<div class="regulation-detail" v-if="currentRegulation">
<div class="detail-header">
<h3>{{ currentRegulation.title }}</h3>
<div class="detail-meta">
<span>公示人: {{ currentRegulation.createByName }}</span>
<span>公示时间: {{ currentRegulation.publishTime }}</span>
<span>生效日期: {{ currentRegulation.effectiveTime }}</span>
<span>确认状态:
<a-tag :color="currentRegulation.confirmStatus === 'CONFIRMED' ? 'green' : 'orange'">
{{ currentRegulation.confirmStatus === 'CONFIRMED' ? '已确认' : '待确认' }}
</a-tag>
</span>
</div>
</div>
<a-divider />
<div class="detail-content">
<h4>制度内容</h4>
<div class="content-text">{{ currentRegulation.content }}</div>
<h4>适用范围</h4>
<div class="content-text">{{ currentRegulation.scope }}</div>
<h4>实施要求</h4>
<div class="content-text">{{ currentRegulation.requirements }}</div>
<h4>注意事项</h4>
<div class="content-text">{{ currentRegulation.notes }}</div>
</div>
<a-divider />
<div class="detail-footer">
<a-button
v-if="currentRegulation.confirmStatus !== 'CONFIRMED'"
type="primary"
@click="handleConfirm(currentRegulation)"
>
确认知晓并遵守
</a-button>
<a-button
v-else
type="primary"
disabled
>
已确认知晓
</a-button>
<a-button @click="handleDownload(currentRegulation)">
下载制度文件
</a-button>
</div>
</div>
</a-modal>
<!-- 确认承诺弹窗 -->
<a-modal
v-model:visible="confirmModalVisible"
title="制度确认承诺"
width="600px"
@ok="submitConfirm"
@cancel="confirmModalVisible = false"
>
<div class="confirm-content">
<p>我确认已仔细阅读并理解《{{ currentRegulation?.title }}》的全部内容,承诺:</p>
<ul>
<li>严格遵守该制度的各项规定</li>
<li>认真履行相关职责和义务</li>
<li>如有违反,愿意承担相应责任</li>
</ul>
<a-checkbox v-model="agreeTerms">
我已阅读并同意上述承诺
</a-checkbox>
</div>
</a-modal>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import type { Regulation } from '@/apis/regulation/type'
import { Message } from '@arco-design/web-vue'
import { IconSearch, IconRefresh } from '@arco-design/web-vue/es/icon'
import { useRegulationStore } from '@/stores/modules/regulation'
import { regulationApi } from '@/apis/regulation'
import { PDFGenerator } from '@/utils/pdfGenerator'
defineOptions({ name: 'SystemRegulation' })
// 表格列定义
const columns = [
{ title: '制度名称', dataIndex: 'title', key: 'title' },
{ title: '制度类型', dataIndex: 'regulationType', key: 'regulationType' },
{ title: '公示人', dataIndex: 'createByName', key: 'createByName' },
{ title: '公示时间', dataIndex: 'publishTime', key: 'publishTime' },
{ title: '生效日期', dataIndex: 'effectiveTime', key: 'effectiveTime' },
{ title: '确认状态', dataIndex: 'confirmStatus', key: 'confirmStatus', slotName: 'confirmStatus' },
{ title: '操作', key: 'operations', slotName: 'operations', width: 250 }
]
// 表格数据
const tableData = ref<Regulation[]>([])
const loading = ref(false)
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0,
showTotal: true,
showJumper: true,
showPageSize: true
})
// 搜索表单
const searchForm = reactive({
title: '',
proposer: '',
confirmStatus: ''
})
// 弹窗相关
const detailModalVisible = ref(false)
const confirmModalVisible = ref(false)
const currentRegulation = ref<Regulation | null>(null)
const agreeTerms = ref(false)
// 制度管理store
const regulationStore = useRegulationStore()
// 获取表格数据 - 使用后端搜索接口
const getTableData = async () => {
loading.value = true
try {
const response = await regulationApi.getRegulationList({
page: pagination.current,
size: pagination.pageSize,
status: "PUBLISHED",
title: searchForm.title || undefined,
proposer: searchForm.proposer || undefined,
confirmStatus: searchForm.confirmStatus || undefined
})
if (response.status === 200) {
// 确保每个记录都有 confirmStatus 字段
const records = response.data.records.map((record: any) => ({
...record,
confirmStatus: record.confirmStatus || 'PENDING'
}))
tableData.value = records
pagination.pageSize = response.data.size
pagination.current = response.data.current
pagination.total = response.data.total
} else {
Message.error('搜索失败')
}
} catch (error) {
console.error('搜索已公告制度失败:', error)
Message.error('搜索失败')
} finally {
loading.value = false
}
}
// 搜索
const search = () => {
pagination.current = 1
getTableData()
}
// 重置
const reset = () => {
Object.assign(searchForm, {
title: '',
proposer: '',
confirmStatus: ''
})
pagination.current = 1
getTableData()
}
// 分页事件
const onPageChange = (page: number) => {
pagination.current = page
getTableData()
}
const onPageSizeChange = (pageSize: number) => {
pagination.pageSize = pageSize
pagination.current = 1
getTableData()
}
// 查看详情
const handleView = (record: any) => {
currentRegulation.value = record
detailModalVisible.value = true
}
// 确认知晓
const handleConfirm = (record: any) => {
currentRegulation.value = record
confirmModalVisible.value = true
agreeTerms.value = false
}
// 下载
const handleDownload = async (record: any) => {
try {
const loadingMessage = Message.loading('正在生成PDF文件...', 0)
// 生成PDF
const pdfBlob = await PDFGenerator.generateRegulationPDF(record)
// 关闭加载提示
loadingMessage.close()
// 生成文件名
const filename = `${record.title}_${new Date().toISOString().split('T')[0]}.pdf`
// 下载PDF
PDFGenerator.downloadPDF(pdfBlob, filename)
Message.success('PDF文件下载成功')
} catch (error) {
Message.error('PDF生成失败')
console.error('PDF生成错误:', error)
}
}
// 提交确认
const submitConfirm = async () => {
if (!agreeTerms.value) {
Message.warning('请先同意承诺条款')
return
}
try {
if (currentRegulation.value) {
await regulationApi.confirmRegulation(currentRegulation.value.regulationId)
Message.success('确认成功,您已承诺遵守该制度')
confirmModalVisible.value = false
// 立即刷新数据,确保状态同步
await getTableData()
// 如果详情弹窗是打开的,也更新详情弹窗中的数据
if (detailModalVisible.value && currentRegulation.value) {
const updatedRecord = tableData.value.find(item => item.regulationId === currentRegulation.value.regulationId)
if (updatedRecord) {
currentRegulation.value = updatedRecord
}
}
}
} catch (error) {
console.error('确认失败:', error)
Message.error('确认失败')
}
}
onMounted(() => {
getTableData()
})
</script>
<style scoped lang="scss">
.system-regulation {
.arco-card {
margin-bottom: 16px;
}
}
.search-container {
padding: 16px;
background: var(--color-bg-2);
border-radius: 6px;
margin-bottom: 16px;
.search-form {
.arco-form-item {
margin-bottom: 0;
margin-right: 16px;
.arco-form-item-label {
font-weight: 500;
color: var(--color-text-1);
margin-right: 8px;
}
}
.arco-input,
.arco-select {
border-radius: 4px;
}
.arco-btn {
border-radius: 4px;
}
}
}
.search-result-info {
color: var(--color-text-2);
font-size: 14px;
strong {
color: var(--color-text-1);
font-weight: 600;
}
}
.regulation-detail {
.detail-header {
margin-bottom: 16px;
h3 {
margin-bottom: 12px;
color: var(--color-text-1);
}
.detail-meta {
display: flex;
gap: 16px;
color: var(--color-text-3);
font-size: 14px;
}
}
.detail-content {
h4 {
margin: 16px 0 8px 0;
color: var(--color-text-1);
font-weight: 500;
}
.content-text {
color: var(--color-text-2);
line-height: 1.6;
margin-bottom: 16px;
padding: 12px;
background: var(--color-fill-1);
border-radius: 6px;
}
}
.detail-footer {
display: flex;
gap: 12px;
justify-content: center;
}
}
.confirm-content {
p {
margin-bottom: 16px;
color: var(--color-text-1);
line-height: 1.6;
}
ul {
margin-bottom: 20px;
padding-left: 20px;
li {
margin-bottom: 8px;
color: var(--color-text-2);
line-height: 1.5;
}
}
}
</style>