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

424 lines
11 KiB
Vue

<template>
<div class="process-management">
<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.type"
placeholder="请选择类型"
allow-clear
style="width: 150px"
>
<a-option value="">全部</a-option>
<a-option value="管理规范">管理规范</a-option>
<a-option value="操作流程">操作流程</a-option>
<a-option value="安全制度">安全制度</a-option>
<a-option value="其他">其他</a-option>
</a-select>
</a-form-item>
<a-form-item label="状态">
<a-select
v-model="searchForm.status"
placeholder="请选择状态"
allow-clear
style="width: 150px"
>
<a-option value="">全部</a-option>
<a-option value="PUBLISHED">已公示</a-option>
<a-option value="APPROVED">已通过</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="handlePageChange"
@page-size-change="handlePageSizeChange"
>
<template #toolbar-left>
<span class="search-result-info">
共找到 <strong>{{ pagination.total }}</strong> 条记录
</span>
</template>
<template #status="{ record }">
<a-tag :color="getStatusColor(record.status)">
{{ getStatusText(record.status) }}
</a-tag>
</template>
<template #level="{ record }">
<a-tag :color="getLevelColor(record.level)">
{{ getLevelText(record.level) }}
</a-tag>
</template>
<template #operations="{ record }">
<a-space>
<a-button type="text" size="small" @click="handleView(record)">
查看详情
</a-button>
<a-button
v-if="record.status === RegulationStatus.PUBLISHED"
type="text"
size="small"
disabled
>
已公告
</a-button>
</a-space>
</template>
</a-table>
</a-card>
<!-- 提案详情弹窗 -->
<a-modal
v-model:visible="detailModalVisible"
title="提案详情"
width="800px"
:footer="false"
>
<div class="proposal-detail" v-if="currentProposal">
<div class="detail-header">
<h3>{{ currentProposal.title }}</h3>
<div class="detail-meta">
<span>提案人: {{ currentProposal.createByName }}</span>
<span>提案类型: {{ currentProposal.regulationType }}</span>
<span>适用范围: {{ currentProposal.scope }}</span>
<span>级别: <a-tag :color="getLevelColor(currentProposal.level)">{{ getLevelText(currentProposal.level) }}</a-tag></span>
<span>创建时间: {{ formatDate(currentProposal.createTime) }}</span>
<span>状态: <a-tag :color="getStatusColor(currentProposal.status)">{{ getStatusText(currentProposal.status) }}</a-tag></span>
</div>
</div>
<a-divider />
<div class="detail-content">
<h4>提案内容</h4>
<div class="content-text">{{ currentProposal.content }}</div>
<h4>备注</h4>
<div class="content-text">{{ currentProposal.remark || '暂无备注' }}</div>
</div>
<a-divider />
<div class="detail-footer">
<a-button
v-if="currentProposal.status === RegulationStatus.PUBLISHED"
disabled
>
已自动公示
</a-button>
</div>
</div>
</a-modal>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
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 {
RegulationStatus,
RegulationLevel,
type Regulation,
type RegulationType
} from '@/apis/regulation/type'
defineOptions({ name: 'ProcessManagement' })
// 表格列定义
const columns = [
{ title: '提案标题', dataIndex: 'title', key: 'title', width: 200 },
{ title: '提案人', dataIndex: 'createByName', key: 'createByName', width: 120 },
{ title: '提案类型', dataIndex: 'regulationType', key: 'regulationType', width: 120 },
{ title: '状态', dataIndex: 'status', key: 'status', slotName: 'status', width: 100 },
{ title: '级别', dataIndex: 'level', key: 'level', slotName: 'level', width: 80 },
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
{ title: '操作', key: 'operations', slotName: 'operations', width: 150 }
]
// 搜索表单
const searchForm = reactive({
title: '',
proposer: '',
type: '',
status: ''
})
// 表格数据
const tableData = ref<Regulation[]>([])
const loading = ref(false)
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0,
showTotal: true,
showJumper: true,
showPageSize: true
})
const currentProposal = ref<Regulation | null>(null)
// 详情相关
const detailModalVisible = ref(false)
// 当前用户
const currentUser = ref('管理者') // 从用户认证系统获取当前用户ID
// 制度管理store
const regulationStore = useRegulationStore()
// 获取状态颜色
const getStatusColor = (status: RegulationStatus) => {
const colors = {
[RegulationStatus.DRAFT]: 'blue',
[RegulationStatus.PUBLISHED]: 'purple',
[RegulationStatus.APPROVED]: 'green',
}
return colors[status] || 'blue'
}
// 获取状态文本
const getStatusText = (status: RegulationStatus) => {
const texts = {
[RegulationStatus.DRAFT]: '草稿',
[RegulationStatus.PUBLISHED]: '已公告',
[RegulationStatus.APPROVED]: '已公示',
}
return texts[status] || '草稿'
}
// 格式化日期
const formatDate = (dateString: string) => {
if (!dateString) return '-'
const date = new Date(dateString)
return date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
})
}
// 获取级别颜色
const getLevelColor = (level: RegulationLevel) => {
const colors = {
[RegulationLevel.LOW]: 'blue',
[RegulationLevel.MEDIUM]: 'orange',
[RegulationLevel.HIGH]: 'red'
}
return colors[level] || 'blue'
}
// 获取级别文本
const getLevelText = (level: RegulationLevel) => {
const texts = {
[RegulationLevel.LOW]: '低',
[RegulationLevel.MEDIUM]: '中',
[RegulationLevel.HIGH]: '高'
}
return texts[level] || '中'
}
// 获取表格数据 - 使用后端搜索接口
const getTableData = async () => {
loading.value = true
try {
const response = await regulationApi.getRegulationList({
page: pagination.current,
size: pagination.pageSize,
title: searchForm.title || undefined,
proposer: searchForm.proposer || undefined,
type: searchForm.type || undefined,
status: searchForm.status || undefined
})
if (response.status === 200) {
tableData.value = response.data.records
pagination.total = response.data.total
pagination.current = response.data.current
} 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: '',
type: '',
status: ''
})
pagination.current = 1
getTableData()
}
// 查看
const handleView = (record: Regulation) => {
currentProposal.value = record
detailModalVisible.value = true
}
// 分页事件
const handlePageChange = (page: number) => {
pagination.current = page
getTableData()
}
const handlePageSizeChange = (pageSize: number) => {
pagination.pageSize = pageSize
pagination.current = 1
getTableData()
}
onMounted(() => {
getTableData()
})
</script>
<style scoped lang="scss">
.process-management {
.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;
}
}
.proposal-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;
flex-wrap: wrap;
}
}
.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;
margin-top: 20px;
}
}
</style>