优化制度管理模块,新建制度提案页面
This commit is contained in:
parent
327064b7e5
commit
cc65882b8d
|
@ -23,6 +23,7 @@ export const regulationApi = {
|
||||||
scope: string
|
scope: string
|
||||||
level: string
|
level: string
|
||||||
remark?: string
|
remark?: string
|
||||||
|
createBy?: string
|
||||||
}) => {
|
}) => {
|
||||||
return http.post('/regulation/proposal', data)
|
return http.post('/regulation/proposal', data)
|
||||||
},
|
},
|
||||||
|
@ -32,17 +33,22 @@ export const regulationApi = {
|
||||||
return http.put(`/regulation/proposal/${regulationId}`, data)
|
return http.put(`/regulation/proposal/${regulationId}`, data)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 公示提案
|
||||||
|
publishProposal: (regulationId: string) => {
|
||||||
|
return http.post(`/regulation/proposal/${regulationId}/publish`)
|
||||||
|
},
|
||||||
|
|
||||||
// 删除制度提案
|
// 删除制度提案
|
||||||
deleteProposal: (regulationId: string) => {
|
deleteProposal: (regulationId: string) => {
|
||||||
return http.del(`/regulation/proposal/${regulationId}`)
|
return http.del(`/regulation/proposal/${regulationId}`)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 发布制度
|
// 公示制度
|
||||||
publishRegulation: (regulationId: string) => {
|
publishRegulation: (regulationId: string) => {
|
||||||
return http.post(`/regulation/${regulationId}/publish`)
|
return http.post(`/regulation/${regulationId}/approve`)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取已发布制度列表
|
// 获取已公示制度列表
|
||||||
getPublishedRegulationList: (params: {
|
getPublishedRegulationList: (params: {
|
||||||
page: number
|
page: number
|
||||||
size: number
|
size: number
|
||||||
|
@ -61,6 +67,7 @@ export const regulationApi = {
|
||||||
page?: number
|
page?: number
|
||||||
size?: number
|
size?: number
|
||||||
typeName?: string
|
typeName?: string
|
||||||
|
isEnabled?: string
|
||||||
remark?: string
|
remark?: string
|
||||||
}) => {
|
}) => {
|
||||||
return http.get('/regulation/types', params)
|
return http.get('/regulation/types', params)
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
// 制度状态枚举
|
// 制度状态枚举
|
||||||
export enum RegulationStatus {
|
export enum RegulationStatus {
|
||||||
DRAFT = 'DRAFT', // 草稿
|
DRAFT = 'DRAFT', // 草稿
|
||||||
VOTING = 'VOTING', // 投票中
|
|
||||||
APPROVED = 'APPROVED', // 已通过
|
APPROVED = 'APPROVED', // 已通过
|
||||||
REJECTED = 'REJECTED', // 已否决
|
PUBLISHED = 'PUBLISHED', // 已公示
|
||||||
PUBLISHED = 'PUBLISHED', // 已发布
|
|
||||||
ARCHIVED = 'ARCHIVED' // 已归档
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 制度级别枚举
|
// 制度级别枚举
|
||||||
|
@ -22,7 +19,7 @@ export interface Regulation {
|
||||||
content: string
|
content: string
|
||||||
regulationType: string
|
regulationType: string
|
||||||
status: RegulationStatus
|
status: RegulationStatus
|
||||||
publishTime: string
|
publishTime: string // 公示时间
|
||||||
effectiveTime: string
|
effectiveTime: string
|
||||||
expireTime: string
|
expireTime: string
|
||||||
scope: string
|
scope: string
|
||||||
|
@ -47,6 +44,7 @@ export interface CreateProposalRequest {
|
||||||
scope: string
|
scope: string
|
||||||
level: RegulationLevel
|
level: RegulationLevel
|
||||||
remark?: string
|
remark?: string
|
||||||
|
createBy?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页参数接口
|
// 分页参数接口
|
||||||
|
|
|
@ -45,6 +45,12 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
component: () => import('@/views/regulation/confirm.vue'),
|
component: () => import('@/views/regulation/confirm.vue'),
|
||||||
meta: { title: '制度公示', icon: 'workflow', hidden: false },
|
meta: { title: '制度公示', icon: 'workflow', hidden: false },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/regulation/proposal',
|
||||||
|
name: 'RegulationProposal',
|
||||||
|
component: () => import('@/views/regulation/proposal/index.vue'),
|
||||||
|
meta: { title: '制度提案', icon: 'edit', hidden: false },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/regulation/type',
|
path: '/regulation/type',
|
||||||
name: 'RegulationType',
|
name: 'RegulationType',
|
||||||
|
|
|
@ -1,14 +1,73 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="process-management">
|
<div class="process-management">
|
||||||
<a-card title="制度公示管理" :bordered="false">
|
<a-card title="制度公示管理" :bordered="false">
|
||||||
<template #extra>
|
<!-- 搜索区域 -->
|
||||||
<a-button type="primary" @click="handleAdd">
|
<div class="search-container">
|
||||||
<template #icon>
|
<a-form layout="inline" :model="searchForm" class="search-form">
|
||||||
<GiSvgIcon name="plus" />
|
<a-form-item label="提案标题">
|
||||||
</template>
|
<a-input
|
||||||
提交制度提案
|
v-model="searchForm.title"
|
||||||
</a-button>
|
placeholder="请输入提案标题"
|
||||||
</template>
|
allow-clear
|
||||||
|
style="width: 200px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="提案人">
|
||||||
|
<a-input
|
||||||
|
v-model="searchForm.createByName"
|
||||||
|
placeholder="请输入提案人"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="提案类型">
|
||||||
|
<a-select
|
||||||
|
v-model="searchForm.regulationType"
|
||||||
|
placeholder="请选择类型"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@change="debouncedSearch"
|
||||||
|
>
|
||||||
|
<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"
|
||||||
|
@change="debouncedSearch"
|
||||||
|
>
|
||||||
|
<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
|
<a-table
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
@ -18,6 +77,11 @@
|
||||||
@page-change="handlePageChange"
|
@page-change="handlePageChange"
|
||||||
@page-size-change="handlePageSizeChange"
|
@page-size-change="handlePageSizeChange"
|
||||||
>
|
>
|
||||||
|
<template #toolbar-left>
|
||||||
|
<span class="search-result-info">
|
||||||
|
共找到 <strong>{{ pagination.total }}</strong> 条记录
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
<template #status="{ record }">
|
<template #status="{ record }">
|
||||||
<a-tag :color="getStatusColor(record.status)">
|
<a-tag :color="getStatusColor(record.status)">
|
||||||
{{ getStatusText(record.status) }}
|
{{ getStatusText(record.status) }}
|
||||||
|
@ -41,100 +105,14 @@
|
||||||
size="small"
|
size="small"
|
||||||
disabled
|
disabled
|
||||||
>
|
>
|
||||||
已发布
|
已公示
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
|
||||||
v-if="record.publisherId === currentUser && record.status === RegulationStatus.DRAFT"
|
|
||||||
type="text"
|
|
||||||
size="small"
|
|
||||||
@click="handleEdit(record)"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</a-button>
|
|
||||||
<a-popconfirm
|
|
||||||
v-if="record.publisherId === currentUser && record.status === RegulationStatus.DRAFT"
|
|
||||||
content="确定要删除这个提案吗?"
|
|
||||||
@ok="handleDelete(record)"
|
|
||||||
>
|
|
||||||
<a-button type="text" size="small" status="danger">
|
|
||||||
删除
|
|
||||||
</a-button>
|
|
||||||
</a-popconfirm>
|
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
<!-- 提案表单弹窗 -->
|
|
||||||
<a-modal
|
|
||||||
v-model:visible="modalVisible"
|
|
||||||
:title="modalTitle"
|
|
||||||
width="800px"
|
|
||||||
@ok="handleSubmit"
|
|
||||||
@cancel="handleCancel"
|
|
||||||
>
|
|
||||||
<a-form
|
|
||||||
ref="formRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
layout="vertical"
|
|
||||||
>
|
|
||||||
<a-row :gutter="16">
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="提案标题" field="title">
|
|
||||||
<a-input v-model="formData.title" placeholder="请输入提案标题" />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="提案类型" field="regulationType">
|
|
||||||
<a-select v-model="formData.regulationType" placeholder="请选择提案类型">
|
|
||||||
<a-option
|
|
||||||
v-for="type in regulationTypes"
|
|
||||||
:key="type.typeId"
|
|
||||||
:value="type.typeName"
|
|
||||||
:disabled="type.isEnabled === '0'"
|
|
||||||
>
|
|
||||||
{{ type.typeName }}
|
|
||||||
</a-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
|
|
||||||
<a-row :gutter="16">
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="适用范围" field="scope">
|
|
||||||
<a-input v-model="formData.scope" placeholder="请输入适用范围" />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="制度级别" field="level">
|
|
||||||
<a-select v-model="formData.level" placeholder="请选择制度级别">
|
|
||||||
<a-option :value="RegulationLevel.LOW">低</a-option>
|
|
||||||
<a-option :value="RegulationLevel.MEDIUM">中</a-option>
|
|
||||||
<a-option :value="RegulationLevel.HIGH">高</a-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
|
|
||||||
<a-form-item label="提案内容" field="content">
|
|
||||||
<a-textarea
|
|
||||||
v-model="formData.content"
|
|
||||||
placeholder="请详细描述提案的具体内容"
|
|
||||||
:rows="6"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
|
|
||||||
<a-form-item label="备注" field="remark">
|
|
||||||
<a-textarea
|
|
||||||
v-model="formData.remark"
|
|
||||||
placeholder="请输入其他补充说明"
|
|
||||||
:rows="2"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-modal>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,7 +129,7 @@
|
||||||
<div class="detail-header">
|
<div class="detail-header">
|
||||||
<h3>{{ currentProposal.title }}</h3>
|
<h3>{{ currentProposal.title }}</h3>
|
||||||
<div class="detail-meta">
|
<div class="detail-meta">
|
||||||
<span>提案人: {{ currentProposal.createBy }}</span>
|
<span>提案人: {{ currentProposal.createByName }}</span>
|
||||||
<span>提案类型: {{ currentProposal.regulationType }}</span>
|
<span>提案类型: {{ currentProposal.regulationType }}</span>
|
||||||
<span>适用范围: {{ currentProposal.scope }}</span>
|
<span>适用范围: {{ currentProposal.scope }}</span>
|
||||||
<span>级别: <a-tag :color="getLevelColor(currentProposal.level)">{{ getLevelText(currentProposal.level) }}</a-tag></span>
|
<span>级别: <a-tag :color="getLevelColor(currentProposal.level)">{{ getLevelText(currentProposal.level) }}</a-tag></span>
|
||||||
|
@ -177,7 +155,7 @@
|
||||||
v-if="currentProposal.status === RegulationStatus.PUBLISHED"
|
v-if="currentProposal.status === RegulationStatus.PUBLISHED"
|
||||||
disabled
|
disabled
|
||||||
>
|
>
|
||||||
已自动发布
|
已自动公示
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -188,6 +166,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { Message } from '@arco-design/web-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 { useRegulationStore } from '@/stores/modules/regulation'
|
||||||
import { regulationApi } from '@/apis/regulation'
|
import { regulationApi } from '@/apis/regulation'
|
||||||
import {
|
import {
|
||||||
|
@ -197,19 +176,36 @@ import {
|
||||||
type RegulationType
|
type RegulationType
|
||||||
} from '@/apis/regulation/type'
|
} from '@/apis/regulation/type'
|
||||||
|
|
||||||
|
// 防抖函数
|
||||||
|
const debounce = (func: Function, delay: number) => {
|
||||||
|
let timeoutId: NodeJS.Timeout
|
||||||
|
return (...args: any[]) => {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
timeoutId = setTimeout(() => func.apply(null, args), delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineOptions({ name: 'ProcessManagement' })
|
defineOptions({ name: 'ProcessManagement' })
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: '提案标题', dataIndex: 'title', key: 'title' },
|
{ title: '提案标题', dataIndex: 'title', key: 'title', width: 200 },
|
||||||
{ title: '提案人', dataIndex: 'createBy', key: 'createBy' },
|
{ title: '提案人', dataIndex: 'createByName', key: 'createByName', width: 120 },
|
||||||
{ title: '提案类型', dataIndex: 'regulationType', key: 'regulationType' },
|
{ title: '提案类型', dataIndex: 'regulationType', key: 'regulationType', width: 120 },
|
||||||
{ title: '状态', dataIndex: 'status', key: 'status', slotName: 'status' },
|
{ title: '状态', dataIndex: 'status', key: 'status', slotName: 'status', width: 100 },
|
||||||
{ title: '级别', dataIndex: 'level', key: 'level', slotName: 'level' },
|
{ title: '级别', dataIndex: 'level', key: 'level', slotName: 'level', width: 80 },
|
||||||
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime' },
|
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
|
||||||
{ title: '操作', key: 'operations', slotName: 'operations', width: 280 }
|
{ title: '操作', key: 'operations', slotName: 'operations', width: 150 }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
const searchForm = reactive({
|
||||||
|
title: '',
|
||||||
|
createByName: '',
|
||||||
|
regulationType: '',
|
||||||
|
status: ''
|
||||||
|
})
|
||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const tableData = ref<Regulation[]>([])
|
const tableData = ref<Regulation[]>([])
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
@ -222,51 +218,23 @@ const pagination = reactive({
|
||||||
showPageSize: true
|
showPageSize: true
|
||||||
})
|
})
|
||||||
|
|
||||||
// 弹窗相关
|
|
||||||
const modalVisible = ref(false)
|
|
||||||
const modalTitle = ref('提交制度提案')
|
|
||||||
const formRef = ref()
|
|
||||||
const formData = reactive({
|
|
||||||
regulationId: '',
|
|
||||||
title: '',
|
|
||||||
regulationType: '',
|
|
||||||
content: '',
|
|
||||||
scope: '',
|
|
||||||
level: RegulationLevel.MEDIUM,
|
|
||||||
remark: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const currentProposal = ref<Regulation | null>(null)
|
const currentProposal = ref<Regulation | null>(null)
|
||||||
|
|
||||||
// 详情相关
|
// 详情相关
|
||||||
const detailModalVisible = ref(false)
|
const detailModalVisible = ref(false)
|
||||||
|
|
||||||
// 当前用户
|
// 当前用户
|
||||||
const currentUser = ref('admin') // 从用户认证系统获取当前用户ID
|
const currentUser = ref('管理者') // 从用户认证系统获取当前用户ID
|
||||||
|
|
||||||
// 制度管理store
|
// 制度管理store
|
||||||
const regulationStore = useRegulationStore()
|
const regulationStore = useRegulationStore()
|
||||||
|
|
||||||
// 制度类型列表
|
|
||||||
const regulationTypes = ref<RegulationType[]>([])
|
|
||||||
|
|
||||||
// 表单验证规则
|
|
||||||
const rules = {
|
|
||||||
title: [{ required: true, message: '请输入提案标题' }],
|
|
||||||
regulationType: [{ required: true, message: '请选择提案类型' }],
|
|
||||||
content: [{ required: true, message: '请输入提案内容' }],
|
|
||||||
scope: [{ required: true, message: '请输入适用范围' }]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取状态颜色
|
// 获取状态颜色
|
||||||
const getStatusColor = (status: RegulationStatus) => {
|
const getStatusColor = (status: RegulationStatus) => {
|
||||||
const colors = {
|
const colors = {
|
||||||
[RegulationStatus.DRAFT]: 'blue',
|
[RegulationStatus.DRAFT]: 'blue',
|
||||||
[RegulationStatus.VOTING]: 'orange',
|
|
||||||
[RegulationStatus.REJECTED]: 'red',
|
|
||||||
[RegulationStatus.PUBLISHED]: 'purple',
|
[RegulationStatus.PUBLISHED]: 'purple',
|
||||||
[RegulationStatus.APPROVED]: 'green',
|
[RegulationStatus.APPROVED]: 'green',
|
||||||
[RegulationStatus.ARCHIVED]: 'gray'
|
|
||||||
}
|
}
|
||||||
return colors[status] || 'blue'
|
return colors[status] || 'blue'
|
||||||
}
|
}
|
||||||
|
@ -274,12 +242,10 @@ const getStatusColor = (status: RegulationStatus) => {
|
||||||
// 获取状态文本
|
// 获取状态文本
|
||||||
const getStatusText = (status: RegulationStatus) => {
|
const getStatusText = (status: RegulationStatus) => {
|
||||||
const texts = {
|
const texts = {
|
||||||
[RegulationStatus.DRAFT]: '已公示',
|
[RegulationStatus.DRAFT]: '草稿',
|
||||||
[RegulationStatus.VOTING]: '投票中',
|
|
||||||
[RegulationStatus.REJECTED]: '已否决',
|
|
||||||
[RegulationStatus.PUBLISHED]: '已公告',
|
[RegulationStatus.PUBLISHED]: '已公告',
|
||||||
[RegulationStatus.APPROVED]: '已通过',
|
[RegulationStatus.APPROVED]: '已公示',
|
||||||
[RegulationStatus.ARCHIVED]: '已归档'
|
|
||||||
}
|
}
|
||||||
return texts[status] || '草稿'
|
return texts[status] || '草稿'
|
||||||
}
|
}
|
||||||
|
@ -317,30 +283,24 @@ const getLevelText = (level: RegulationLevel) => {
|
||||||
return texts[level] || '中'
|
return texts[level] || '中'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取制度类型列表
|
// 获取表格数据 - 只获取已公示及以上的提案
|
||||||
const getRegulationTypes = async () => {
|
|
||||||
try {
|
|
||||||
const response = await regulationApi.getRegulationTypes()
|
|
||||||
if (response.status === 200) {
|
|
||||||
regulationTypes.value = response.data.records || response.data
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取制度类型列表失败:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取表格数据
|
|
||||||
const getTableData = async () => {
|
const getTableData = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const response = await regulationApi.getRegulationList({
|
const response = await regulationApi.getRegulationList({
|
||||||
page: pagination.current,
|
page: pagination.current,
|
||||||
size: pagination.pageSize
|
size: pagination.pageSize,
|
||||||
|
title: searchForm.title || undefined,
|
||||||
|
createByName: searchForm.createByName || undefined,
|
||||||
|
regulationType: searchForm.regulationType || undefined,
|
||||||
|
status: searchForm.status || undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
tableData.value = response.data.records
|
// 过滤掉草稿状态的提案,只显示已公示及以上的
|
||||||
pagination.total = response.data.total
|
const allRecords = response.data.records || []
|
||||||
|
tableData.value = allRecords.filter(item => item.status !== RegulationStatus.DRAFT)
|
||||||
|
pagination.total = tableData.value.length
|
||||||
pagination.current = response.data.current
|
pagination.current = response.data.current
|
||||||
} else {
|
} else {
|
||||||
Message.error('获取数据失败')
|
Message.error('获取数据失败')
|
||||||
|
@ -353,26 +313,28 @@ const getTableData = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增
|
// 防抖搜索函数
|
||||||
const handleAdd = () => {
|
const debouncedSearch = debounce(() => {
|
||||||
modalTitle.value = '提交制度提案'
|
pagination.current = 1
|
||||||
modalVisible.value = true
|
getTableData()
|
||||||
resetForm()
|
}, 300)
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const search = () => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 编辑
|
// 重置
|
||||||
const handleEdit = (record: Regulation) => {
|
const reset = () => {
|
||||||
modalTitle.value = '编辑制度提案'
|
Object.assign(searchForm, {
|
||||||
modalVisible.value = true
|
title: '',
|
||||||
Object.assign(formData, {
|
createByName: '',
|
||||||
regulationId: record.regulationId,
|
regulationType: '',
|
||||||
title: record.title,
|
status: ''
|
||||||
regulationType: record.regulationType,
|
|
||||||
content: record.content,
|
|
||||||
scope: record.scope,
|
|
||||||
level: record.level,
|
|
||||||
remark: record.remark
|
|
||||||
})
|
})
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查看
|
// 查看
|
||||||
|
@ -381,79 +343,6 @@ const handleView = (record: Regulation) => {
|
||||||
detailModalVisible.value = true
|
detailModalVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
const handleDelete = async (record: Regulation) => {
|
|
||||||
try {
|
|
||||||
await regulationApi.deleteProposal(record.regulationId)
|
|
||||||
Message.success('删除成功')
|
|
||||||
getTableData()
|
|
||||||
} catch (error) {
|
|
||||||
console.error('删除失败:', error)
|
|
||||||
Message.error('删除失败')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 提交表单
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
try {
|
|
||||||
await formRef.value.validate()
|
|
||||||
|
|
||||||
if (formData.regulationId) {
|
|
||||||
// 更新
|
|
||||||
await regulationApi.updateProposal(formData.regulationId, {
|
|
||||||
title: formData.title,
|
|
||||||
regulationType: formData.regulationType,
|
|
||||||
content: formData.content,
|
|
||||||
scope: formData.scope,
|
|
||||||
level: formData.level,
|
|
||||||
remark: formData.remark
|
|
||||||
})
|
|
||||||
Message.success('更新成功')
|
|
||||||
} else {
|
|
||||||
// 新增
|
|
||||||
await regulationApi.createProposal({
|
|
||||||
title: formData.title,
|
|
||||||
regulationType: formData.regulationType,
|
|
||||||
content: formData.content,
|
|
||||||
scope: formData.scope,
|
|
||||||
level: formData.level,
|
|
||||||
remark: formData.remark
|
|
||||||
})
|
|
||||||
Message.success('提案提交成功')
|
|
||||||
}
|
|
||||||
|
|
||||||
modalVisible.value = false
|
|
||||||
getTableData()
|
|
||||||
} catch (error) {
|
|
||||||
console.error('操作失败:', error)
|
|
||||||
Message.error('操作失败')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 取消
|
|
||||||
const handleCancel = () => {
|
|
||||||
modalVisible.value = false
|
|
||||||
resetForm()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重置表单
|
|
||||||
const resetForm = () => {
|
|
||||||
Object.assign(formData, {
|
|
||||||
regulationId: '',
|
|
||||||
title: '',
|
|
||||||
regulationType: '',
|
|
||||||
content: '',
|
|
||||||
scope: '',
|
|
||||||
level: RegulationLevel.MEDIUM,
|
|
||||||
remark: ''
|
|
||||||
})
|
|
||||||
formRef.value?.resetFields()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页事件
|
// 分页事件
|
||||||
const handlePageChange = (page: number) => {
|
const handlePageChange = (page: number) => {
|
||||||
pagination.current = page
|
pagination.current = page
|
||||||
|
@ -468,7 +357,6 @@ const handlePageSizeChange = (pageSize: number) => {
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getTableData()
|
getTableData()
|
||||||
getRegulationTypes()
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -479,6 +367,45 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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 {
|
.proposal-detail {
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import SystemRegulation from './repository.vue'
|
import SystemRegulation from './repository.vue'
|
||||||
|
import RegulationProposal from './proposal/index.vue'
|
||||||
import RegulationType from './type/index.vue'
|
import RegulationType from './type/index.vue'
|
||||||
import ProcessManagement from './confirm.vue'
|
import ProcessManagement from './confirm.vue'
|
||||||
import { useDevice } from '@/hooks'
|
import { useDevice } from '@/hooks'
|
||||||
|
@ -47,6 +48,7 @@ const { isDesktop } = useDevice()
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
{ name: '制度公告', key: 'system-regulation', icon: 'file-text', value: SystemRegulation, path: '/regulation/system-regulation' },
|
{ name: '制度公告', key: 'system-regulation', icon: 'file-text', value: SystemRegulation, path: '/regulation/system-regulation' },
|
||||||
|
{ name: '制度提案', key: 'proposal', icon: 'edit', value: RegulationProposal, path: '/regulation/proposal' },
|
||||||
{ name: '制度公示', key: 'process-management', icon: 'workflow', value: ProcessManagement, path: '/regulation/process-management' },
|
{ name: '制度公示', key: 'process-management', icon: 'workflow', value: ProcessManagement, path: '/regulation/process-management' },
|
||||||
{ name: '制度类型', key: 'type', icon: 'tag', value: RegulationType, path: '/regulation/type' },
|
{ name: '制度类型', key: 'type', icon: 'tag', value: RegulationType, path: '/regulation/type' },
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,955 @@
|
||||||
|
<template>
|
||||||
|
<div class="regulation-proposal">
|
||||||
|
<a-card title="制度提案管理" :bordered="false">
|
||||||
|
<template #extra>
|
||||||
|
<a-button type="primary" @click="handleAdd">
|
||||||
|
<template #icon>
|
||||||
|
<GiSvgIcon name="plus" />
|
||||||
|
</template>
|
||||||
|
新增制度提案
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 搜索区域 -->
|
||||||
|
<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"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="提案人">
|
||||||
|
<a-input
|
||||||
|
v-model="searchForm.createByName"
|
||||||
|
placeholder="请输入提案人"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="提案类型">
|
||||||
|
<a-select
|
||||||
|
v-model="searchForm.regulationType"
|
||||||
|
placeholder="请选择类型"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@change="debouncedSearch"
|
||||||
|
>
|
||||||
|
<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"
|
||||||
|
@change="debouncedSearch"
|
||||||
|
>
|
||||||
|
<a-option value="">全部</a-option>
|
||||||
|
<a-option value="DRAFT">草稿</a-option>
|
||||||
|
<a-option value="PUBLISHED">已公示</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.DRAFT"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
@click="handleEdit(record)"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-if="record.status === RegulationStatus.DRAFT"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
@click="handleConfirm(record)"
|
||||||
|
>
|
||||||
|
确认公示
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-if="record.status !== RegulationStatus.DRAFT"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
已公示
|
||||||
|
</a-button>
|
||||||
|
<a-popconfirm
|
||||||
|
v-if="record.status === RegulationStatus.DRAFT"
|
||||||
|
content="确定要删除这个提案吗?"
|
||||||
|
@ok="handleDelete(record)"
|
||||||
|
>
|
||||||
|
<a-button type="text" size="small" status="danger">
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 提案表单弹窗 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="modalVisible"
|
||||||
|
:title="modalTitle"
|
||||||
|
width="900px"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
class="proposal-form-modal"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
layout="vertical"
|
||||||
|
class="proposal-form"
|
||||||
|
>
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="提案标题" field="title" class="form-item">
|
||||||
|
<a-input
|
||||||
|
v-model="formData.title"
|
||||||
|
placeholder="请输入提案标题"
|
||||||
|
class="form-input"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="提案类型" field="regulationType" class="form-item">
|
||||||
|
<a-select
|
||||||
|
v-model="formData.regulationType"
|
||||||
|
placeholder="请选择提案类型"
|
||||||
|
class="form-select"
|
||||||
|
allow-clear
|
||||||
|
>
|
||||||
|
<a-option
|
||||||
|
v-for="type in regulationTypes"
|
||||||
|
:key="type.typeId"
|
||||||
|
:value="type.typeName"
|
||||||
|
:disabled="type.isEnabled === '0'"
|
||||||
|
>
|
||||||
|
{{ type.typeName }}
|
||||||
|
</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="适用范围" field="scope" class="form-item">
|
||||||
|
<a-input
|
||||||
|
v-model="formData.scope"
|
||||||
|
placeholder="请输入适用范围"
|
||||||
|
class="form-input"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="制度级别" field="level" class="form-item">
|
||||||
|
<a-select
|
||||||
|
v-model="formData.level"
|
||||||
|
placeholder="请选择制度级别"
|
||||||
|
class="form-select"
|
||||||
|
allow-clear
|
||||||
|
>
|
||||||
|
<a-option :value="RegulationLevel.LOW">低</a-option>
|
||||||
|
<a-option :value="RegulationLevel.MEDIUM">中</a-option>
|
||||||
|
<a-option :value="RegulationLevel.HIGH">高</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item label="提案内容" field="content" class="form-item">
|
||||||
|
<a-textarea
|
||||||
|
v-model="formData.content"
|
||||||
|
placeholder="请详细描述提案的具体内容,包括制度的目的、适用范围、具体规定等"
|
||||||
|
:rows="8"
|
||||||
|
class="form-textarea"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="备注" field="remark" class="form-item">
|
||||||
|
<a-textarea
|
||||||
|
v-model="formData.remark"
|
||||||
|
placeholder="请输入其他补充说明(可选)"
|
||||||
|
:rows="3"
|
||||||
|
class="form-textarea"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
|
<!-- 提案详情弹窗 -->
|
||||||
|
<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.DRAFT && currentProposal.createByName === currentUser"
|
||||||
|
type="primary"
|
||||||
|
@click="handleConfirm(currentProposal)"
|
||||||
|
>
|
||||||
|
确认公示
|
||||||
|
</a-button>
|
||||||
|
<a-button @click="detailModalVisible = false">
|
||||||
|
关闭
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
|
<!-- 确认公示弹窗 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="confirmModalVisible"
|
||||||
|
title="确认公示提案"
|
||||||
|
width="600px"
|
||||||
|
@ok="submitConfirm"
|
||||||
|
@cancel="confirmModalVisible = false"
|
||||||
|
>
|
||||||
|
<div class="confirm-content">
|
||||||
|
<div class="confirm-header">
|
||||||
|
<GiSvgIcon name="exclamation-circle" style="color: #faad14; font-size: 24px; margin-right: 8px;" />
|
||||||
|
<span style="font-weight: 500; font-size: 16px;">公示确认</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="confirm-body">
|
||||||
|
<p>您即将公示提案《<strong>{{ currentProposal?.title }}</strong>》</p>
|
||||||
|
<p>公示后:</p>
|
||||||
|
<ul>
|
||||||
|
<li>该提案将进入制度公示页面</li>
|
||||||
|
<li>其他用户可以在制度公示页面查看此提案</li>
|
||||||
|
<li>提案将进入正式的公示流程</li>
|
||||||
|
<li>您将无法再编辑此提案</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="confirm-footer">
|
||||||
|
<a-checkbox v-model="agreeDisplay">
|
||||||
|
我已仔细阅读并确认公示此提案
|
||||||
|
</a-checkbox>
|
||||||
|
</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'
|
||||||
|
|
||||||
|
// 防抖函数
|
||||||
|
const debounce = (func: Function, delay: number) => {
|
||||||
|
let timeoutId: NodeJS.Timeout
|
||||||
|
return (...args: any[]) => {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
timeoutId = setTimeout(() => func.apply(null, args), delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineOptions({ name: 'RegulationProposal' })
|
||||||
|
|
||||||
|
// 表格列定义
|
||||||
|
const columns = [
|
||||||
|
{ title: '提案标题', dataIndex: 'title', key: 'title', width: 220 },
|
||||||
|
{ title: '提案人', dataIndex: 'createByName', key: 'createByName', width: 130 },
|
||||||
|
{ title: '提案类型', dataIndex: 'regulationType', key: 'regulationType', width: 130 },
|
||||||
|
{ title: '状态', dataIndex: 'status', key: 'status', slotName: 'status', width: 110 },
|
||||||
|
{ title: '级别', dataIndex: 'level', key: 'level', slotName: 'level', width: 90 },
|
||||||
|
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 200 },
|
||||||
|
{ title: '操作', key: 'operations', slotName: 'operations', width: 320 }
|
||||||
|
]
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
const searchForm = reactive({
|
||||||
|
title: '',
|
||||||
|
createByName: '',
|
||||||
|
regulationType: '',
|
||||||
|
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 modalVisible = ref(false)
|
||||||
|
const modalTitle = ref('新增制度提案')
|
||||||
|
const formRef = ref()
|
||||||
|
const formData = reactive({
|
||||||
|
regulationId: '',
|
||||||
|
title: '',
|
||||||
|
regulationType: '',
|
||||||
|
content: '',
|
||||||
|
scope: '',
|
||||||
|
level: RegulationLevel.MEDIUM,
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentProposal = ref<Regulation | null>(null)
|
||||||
|
const detailModalVisible = ref(false)
|
||||||
|
const confirmModalVisible = ref(false)
|
||||||
|
const agreeDisplay = ref(false)
|
||||||
|
|
||||||
|
// 当前用户
|
||||||
|
const currentUser = ref('管理者') // 从用户认证系统获取当前用户ID
|
||||||
|
|
||||||
|
// 制度管理store
|
||||||
|
const regulationStore = useRegulationStore()
|
||||||
|
|
||||||
|
// 制度类型列表
|
||||||
|
const regulationTypes = ref<RegulationType[]>([])
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = {
|
||||||
|
title: [{ required: true, message: '请输入提案标题' }],
|
||||||
|
regulationType: [{ required: true, message: '请选择提案类型' }],
|
||||||
|
content: [{ required: true, message: '请输入提案内容' }],
|
||||||
|
scope: [{ required: true, message: '请输入适用范围' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态颜色
|
||||||
|
const getStatusColor = (status: RegulationStatus) => {
|
||||||
|
const colors = {
|
||||||
|
[RegulationStatus.DRAFT]: 'blue',
|
||||||
|
[RegulationStatus.VOTING]: 'orange',
|
||||||
|
[RegulationStatus.REJECTED]: 'red',
|
||||||
|
[RegulationStatus.PUBLISHED]: 'purple',
|
||||||
|
[RegulationStatus.APPROVED]: 'green',
|
||||||
|
[RegulationStatus.ARCHIVED]: 'gray'
|
||||||
|
}
|
||||||
|
return colors[status] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
const getStatusText = (status: RegulationStatus) => {
|
||||||
|
const texts = {
|
||||||
|
[RegulationStatus.DRAFT]: '草稿',
|
||||||
|
[RegulationStatus.VOTING]: '投票中',
|
||||||
|
[RegulationStatus.REJECTED]: '已否决',
|
||||||
|
[RegulationStatus.PUBLISHED]: '已公示',
|
||||||
|
[RegulationStatus.APPROVED]: '已通过',
|
||||||
|
[RegulationStatus.ARCHIVED]: '已归档'
|
||||||
|
}
|
||||||
|
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 getRegulationTypes = async () => {
|
||||||
|
try {
|
||||||
|
const response = await regulationApi.getRegulationTypes()
|
||||||
|
if (response.status === 200) {
|
||||||
|
regulationTypes.value = response.data.records || response.data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取制度类型列表失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表格数据 - 只获取草稿状态的提案
|
||||||
|
const getTableData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const response = await regulationApi.getRegulationList({
|
||||||
|
page: pagination.current,
|
||||||
|
size: pagination.pageSize,
|
||||||
|
status: RegulationStatus.DRAFT, // 只获取草稿状态的提案
|
||||||
|
title: searchForm.title || undefined,
|
||||||
|
createByName: searchForm.createByName || undefined,
|
||||||
|
regulationType: searchForm.regulationType || undefined,
|
||||||
|
status: searchForm.status || undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
tableData.value = response.data.records
|
||||||
|
pagination.total = response.data.total
|
||||||
|
pagination.current = response.data.current
|
||||||
|
|
||||||
|
// 调试信息:输出当前用户和提案创建者信息
|
||||||
|
console.log('当前用户:', currentUser.value)
|
||||||
|
tableData.value.forEach((item, index) => {
|
||||||
|
console.log(`提案 ${index + 1}:`, {
|
||||||
|
title: item.title,
|
||||||
|
createByName: item.createByName,
|
||||||
|
status: item.status,
|
||||||
|
canEdit: item.status === RegulationStatus.DRAFT && item.createByName === currentUser.value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Message.error('获取数据失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取制度列表失败:', error)
|
||||||
|
Message.error('获取数据失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防抖搜索函数
|
||||||
|
const debouncedSearch = debounce(() => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}, 300)
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const search = () => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const reset = () => {
|
||||||
|
Object.assign(searchForm, {
|
||||||
|
title: '',
|
||||||
|
createByName: '',
|
||||||
|
regulationType: '',
|
||||||
|
status: ''
|
||||||
|
})
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
const handleAdd = () => {
|
||||||
|
modalTitle.value = '新增制度提案'
|
||||||
|
modalVisible.value = true
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑
|
||||||
|
const handleEdit = (record: Regulation) => {
|
||||||
|
|
||||||
|
modalTitle.value = '编辑制度提案'
|
||||||
|
modalVisible.value = true
|
||||||
|
Object.assign(formData, {
|
||||||
|
regulationId: record.regulationId,
|
||||||
|
title: record.title,
|
||||||
|
regulationType: record.regulationType,
|
||||||
|
content: record.content,
|
||||||
|
scope: record.scope,
|
||||||
|
level: record.level,
|
||||||
|
remark: record.remark
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看
|
||||||
|
const handleView = (record: Regulation) => {
|
||||||
|
currentProposal.value = record
|
||||||
|
detailModalVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认公示
|
||||||
|
const handleConfirm = (record: Regulation) => {
|
||||||
|
currentProposal.value = record
|
||||||
|
confirmModalVisible.value = true
|
||||||
|
agreeDisplay.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDelete = async (record: Regulation) => {
|
||||||
|
try {
|
||||||
|
await regulationApi.deleteProposal(record.regulationId)
|
||||||
|
Message.success('删除成功')
|
||||||
|
getTableData()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error)
|
||||||
|
Message.error('删除失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交确认公示
|
||||||
|
const submitConfirm = async () => {
|
||||||
|
if (!agreeDisplay.value) {
|
||||||
|
Message.warning('请先确认公示此提案')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (currentProposal.value) {
|
||||||
|
console.log('准备公示提案:', currentProposal.value.regulationId)
|
||||||
|
// 使用公示制度API
|
||||||
|
const response = await regulationApi.publishRegulation(currentProposal.value.regulationId)
|
||||||
|
console.log('公示响应:', response)
|
||||||
|
|
||||||
|
Message.success('提案公示成功,已进入公示流程')
|
||||||
|
confirmModalVisible.value = false
|
||||||
|
getTableData() // 刷新列表
|
||||||
|
|
||||||
|
// 如果是从详情弹窗发起的确认,也关闭详情弹窗
|
||||||
|
if (detailModalVisible.value) {
|
||||||
|
detailModalVisible.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('公示失败:', error)
|
||||||
|
console.error('错误详情:', error.response || error)
|
||||||
|
Message.error('公示失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await formRef.value.validate()
|
||||||
|
|
||||||
|
if (formData.regulationId) {
|
||||||
|
// 更新
|
||||||
|
await regulationApi.updateProposal(formData.regulationId, {
|
||||||
|
title: formData.title,
|
||||||
|
regulationType: formData.regulationType,
|
||||||
|
content: formData.content,
|
||||||
|
scope: formData.scope,
|
||||||
|
level: formData.level,
|
||||||
|
remark: formData.remark
|
||||||
|
})
|
||||||
|
Message.success('更新成功')
|
||||||
|
} else {
|
||||||
|
// 新增
|
||||||
|
const createData = {
|
||||||
|
title: formData.title,
|
||||||
|
regulationType: formData.regulationType,
|
||||||
|
content: formData.content,
|
||||||
|
scope: formData.scope,
|
||||||
|
level: formData.level,
|
||||||
|
remark: formData.remark,
|
||||||
|
createByName: currentUser.value
|
||||||
|
}
|
||||||
|
console.log('新增提案数据:', createData)
|
||||||
|
const response = await regulationApi.createProposal(createData)
|
||||||
|
console.log('新增提案响应:', response)
|
||||||
|
Message.success('提案提交成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
modalVisible.value = false
|
||||||
|
getTableData()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('操作失败:', error)
|
||||||
|
Message.error('操作失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
const handleCancel = () => {
|
||||||
|
modalVisible.value = false
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
const resetForm = () => {
|
||||||
|
Object.assign(formData, {
|
||||||
|
regulationId: '',
|
||||||
|
title: '',
|
||||||
|
regulationType: '',
|
||||||
|
content: '',
|
||||||
|
scope: '',
|
||||||
|
level: RegulationLevel.MEDIUM,
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页事件
|
||||||
|
const handlePageChange = (page: number) => {
|
||||||
|
pagination.current = page
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePageSizeChange = (pageSize: number) => {
|
||||||
|
pagination.pageSize = pageSize
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTableData()
|
||||||
|
getRegulationTypes()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.regulation-proposal {
|
||||||
|
.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-form-modal {
|
||||||
|
.arco-modal-body {
|
||||||
|
padding: 24px 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-modal-header {
|
||||||
|
padding: 20px 32px 16px;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
|
||||||
|
.arco-modal-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-modal-footer {
|
||||||
|
padding: 16px 32px 24px;
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.proposal-form {
|
||||||
|
.form-item {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
.arco-form-item-label {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
color: #ff4d4f;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-form-item-error {
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input,
|
||||||
|
.form-select {
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--color-primary-light-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&.arco-input-focus,
|
||||||
|
&.arco-select-focus {
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
box-shadow: 0 0 0 2px rgba(var(--primary-6), 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-input-inner {
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-textarea {
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--color-primary-light-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&.arco-textarea-focus {
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
box-shadow: 0 0 0 2px rgba(var(--primary-6), 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-textarea-inner {
|
||||||
|
padding: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择框样式优化
|
||||||
|
.arco-select {
|
||||||
|
.arco-select-view {
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-select-arrow {
|
||||||
|
color: var(--color-text-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 占位符样式
|
||||||
|
.arco-input-inner::placeholder,
|
||||||
|
.arco-textarea-inner::placeholder {
|
||||||
|
color: var(--color-text-3);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空按钮样式
|
||||||
|
.arco-input-clear-btn,
|
||||||
|
.arco-textarea-clear-btn {
|
||||||
|
color: var(--color-text-3);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-text-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-content {
|
||||||
|
.confirm-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-body {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 12px 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: var(--color-text-2);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-footer {
|
||||||
|
padding-top: 16px;
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,7 +1,57 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="system-regulation">
|
<div class="system-regulation">
|
||||||
<a-card title="已公告制度确认" :bordered="false">
|
<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"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="公示人">
|
||||||
|
<a-input
|
||||||
|
v-model="searchForm.createByName"
|
||||||
|
placeholder="请输入公示人"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="确认状态">
|
||||||
|
<a-select
|
||||||
|
v-model="searchForm.confirmStatus"
|
||||||
|
placeholder="请选择状态"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@change="debouncedSearch"
|
||||||
|
>
|
||||||
|
<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
|
<a-table
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
@ -11,6 +61,11 @@
|
||||||
@page-change="onPageChange"
|
@page-change="onPageChange"
|
||||||
@page-size-change="onPageSizeChange"
|
@page-size-change="onPageSizeChange"
|
||||||
>
|
>
|
||||||
|
<template #toolbar-left>
|
||||||
|
<span class="search-result-info">
|
||||||
|
共找到 <strong>{{ pagination.total }}</strong> 条记录
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
<template #confirmStatus="{ record }">
|
<template #confirmStatus="{ record }">
|
||||||
<a-tag :color="record.confirmStatus === 'confirmed' ? 'green' : 'orange'">
|
<a-tag :color="record.confirmStatus === 'confirmed' ? 'green' : 'orange'">
|
||||||
{{ record.confirmStatus === 'confirmed' ? '已确认' : '待确认' }}
|
{{ record.confirmStatus === 'confirmed' ? '已确认' : '待确认' }}
|
||||||
|
@ -41,8 +96,8 @@
|
||||||
<div class="detail-header">
|
<div class="detail-header">
|
||||||
<h3>{{ currentRegulation.title }}</h3>
|
<h3>{{ currentRegulation.title }}</h3>
|
||||||
<div class="detail-meta">
|
<div class="detail-meta">
|
||||||
<span>发布人: {{ currentRegulation.createBy }}</span>
|
<span>公示人: {{ currentRegulation.createByName }}</span>
|
||||||
<span>发布时间: {{ currentRegulation.publishTime }}</span>
|
<span>公示时间: {{ currentRegulation.publishTime }}</span>
|
||||||
<span>生效日期: {{ currentRegulation.effectiveTime }}</span>
|
<span>生效日期: {{ currentRegulation.effectiveTime }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -104,18 +159,28 @@
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import type { Regulation } from '@/apis/regulation/type'
|
import type { Regulation } from '@/apis/regulation/type'
|
||||||
import { Message } from '@arco-design/web-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 { useRegulationStore } from '@/stores/modules/regulation'
|
||||||
import { regulationApi } from '@/apis/regulation'
|
import { regulationApi } from '@/apis/regulation'
|
||||||
import { PDFGenerator } from '@/utils/pdfGenerator'
|
import { PDFGenerator } from '@/utils/pdfGenerator'
|
||||||
|
|
||||||
|
// 防抖函数
|
||||||
|
const debounce = (func: Function, delay: number) => {
|
||||||
|
let timeoutId: NodeJS.Timeout
|
||||||
|
return (...args: any[]) => {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
timeoutId = setTimeout(() => func.apply(null, args), delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineOptions({ name: 'SystemRegulation' })
|
defineOptions({ name: 'SystemRegulation' })
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: '制度名称', dataIndex: 'title', key: 'title' },
|
{ title: '制度名称', dataIndex: 'title', key: 'title' },
|
||||||
{ title: '制度类型', dataIndex: 'regulationType', key: 'regulationType' },
|
{ title: '制度类型', dataIndex: 'regulationType', key: 'regulationType' },
|
||||||
{ title: '发布人', dataIndex: 'createBy', key: 'createBy' },
|
{ title: '公示人', dataIndex: 'createByName', key: 'createByName' },
|
||||||
{ title: '发布时间', dataIndex: 'publishTime', key: 'publishTime' },
|
{ title: '公示时间', dataIndex: 'publishTime', key: 'publishTime' },
|
||||||
{ title: '生效日期', dataIndex: 'effectiveTime', key: 'effectiveTime' },
|
{ title: '生效日期', dataIndex: 'effectiveTime', key: 'effectiveTime' },
|
||||||
{ title: '确认状态', dataIndex: 'confirmStatus', key: 'confirmStatus', slotName: 'confirmStatus' },
|
{ title: '确认状态', dataIndex: 'confirmStatus', key: 'confirmStatus', slotName: 'confirmStatus' },
|
||||||
{ title: '操作', key: 'operations', slotName: 'operations', width: 250 }
|
{ title: '操作', key: 'operations', slotName: 'operations', width: 250 }
|
||||||
|
@ -133,6 +198,13 @@ const pagination = reactive({
|
||||||
showPageSize: true
|
showPageSize: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
const searchForm = reactive({
|
||||||
|
title: '',
|
||||||
|
createByName: '',
|
||||||
|
confirmStatus: ''
|
||||||
|
})
|
||||||
|
|
||||||
// 弹窗相关
|
// 弹窗相关
|
||||||
const detailModalVisible = ref(false)
|
const detailModalVisible = ref(false)
|
||||||
const confirmModalVisible = ref(false)
|
const confirmModalVisible = ref(false)
|
||||||
|
@ -149,7 +221,10 @@ const getTableData = async () => {
|
||||||
const response = await regulationApi.getPublishedRegulationList({
|
const response = await regulationApi.getPublishedRegulationList({
|
||||||
page: pagination.current,
|
page: pagination.current,
|
||||||
size: pagination.pageSize,
|
size: pagination.pageSize,
|
||||||
status: "PUBLISHED"
|
status: "PUBLISHED",
|
||||||
|
title: searchForm.title || undefined,
|
||||||
|
createByName: searchForm.createByName || undefined,
|
||||||
|
confirmStatus: searchForm.confirmStatus || undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
|
@ -161,13 +236,36 @@ const getTableData = async () => {
|
||||||
Message.error('获取数据失败')
|
Message.error('获取数据失败')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取已发布制度列表失败:', error)
|
console.error('获取已公示制度列表失败:', error)
|
||||||
Message.error('获取数据失败')
|
Message.error('获取数据失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防抖搜索函数
|
||||||
|
const debouncedSearch = debounce(() => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}, 300)
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const search = () => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const reset = () => {
|
||||||
|
Object.assign(searchForm, {
|
||||||
|
title: '',
|
||||||
|
createByName: '',
|
||||||
|
confirmStatus: ''
|
||||||
|
})
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
// 分页事件
|
// 分页事件
|
||||||
const onPageChange = (page: number) => {
|
const onPageChange = (page: number) => {
|
||||||
pagination.current = page
|
pagination.current = page
|
||||||
|
@ -257,6 +355,45 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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 {
|
.regulation-detail {
|
||||||
.detail-header {
|
.detail-header {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
|
@ -13,14 +13,56 @@
|
||||||
@refresh="search"
|
@refresh="search"
|
||||||
>
|
>
|
||||||
<template #top>
|
<template #top>
|
||||||
<GiForm
|
<div class="search-container">
|
||||||
v-model="searchForm"
|
<a-form layout="inline" :model="searchForm" class="search-form">
|
||||||
search
|
<a-form-item label="类型名称">
|
||||||
:columns="queryFormColumns"
|
<a-input
|
||||||
size="medium"
|
v-model="searchForm.typeName"
|
||||||
@search="search"
|
placeholder="请输入类型名称"
|
||||||
@reset="reset"
|
allow-clear
|
||||||
/>
|
style="width: 200px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="状态">
|
||||||
|
<a-select
|
||||||
|
v-model="searchForm.isEnabled"
|
||||||
|
placeholder="请选择状态"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@change="debouncedSearch"
|
||||||
|
>
|
||||||
|
<a-option value="">全部</a-option>
|
||||||
|
<a-option value="1">启用</a-option>
|
||||||
|
<a-option value="0">禁用</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="备注">
|
||||||
|
<a-input
|
||||||
|
v-model="searchForm.remark"
|
||||||
|
placeholder="请输入备注内容"
|
||||||
|
allow-clear
|
||||||
|
style="width: 200px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</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>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #toolbar-left>
|
<template #toolbar-left>
|
||||||
|
@ -29,6 +71,9 @@
|
||||||
<template #icon><icon-plus /></template>
|
<template #icon><icon-plus /></template>
|
||||||
<template #default>新增类型</template>
|
<template #default>新增类型</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
<span class="search-result-info">
|
||||||
|
共找到 <strong>{{ pagination.total }}</strong> 条记录
|
||||||
|
</span>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -101,8 +146,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted, watch } from 'vue'
|
||||||
import { Message } from '@arco-design/web-vue'
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import { IconSearch, IconRefresh } from '@arco-design/web-vue/es/icon'
|
||||||
import { regulationApi } from '@/apis/regulation'
|
import { regulationApi } from '@/apis/regulation'
|
||||||
import {
|
import {
|
||||||
type RegulationType,
|
type RegulationType,
|
||||||
|
@ -110,6 +156,15 @@ import {
|
||||||
type UpdateRegulationTypeRequest
|
type UpdateRegulationTypeRequest
|
||||||
} from '@/apis/regulation/type'
|
} from '@/apis/regulation/type'
|
||||||
|
|
||||||
|
// 防抖函数
|
||||||
|
const debounce = (func: Function, delay: number) => {
|
||||||
|
let timeoutId: NodeJS.Timeout
|
||||||
|
return (...args: any[]) => {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
timeoutId = setTimeout(() => func.apply(null, args), delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineOptions({ name: 'RegulationType' })
|
defineOptions({ name: 'RegulationType' })
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
|
@ -117,31 +172,13 @@ const tableColumns = [
|
||||||
{ title: '类型名称', dataIndex: 'typeName', key: 'typeName', width: 150 },
|
{ title: '类型名称', dataIndex: 'typeName', key: 'typeName', width: 150 },
|
||||||
{ title: '备注', dataIndex: 'remark', key: 'remark', width: 200 },
|
{ title: '备注', dataIndex: 'remark', key: 'remark', width: 200 },
|
||||||
{ title: '状态', dataIndex: 'isEnabled', key: 'isEnabled', slotName: 'isEnabled', width: 100 },
|
{ title: '状态', dataIndex: 'isEnabled', key: 'isEnabled', slotName: 'isEnabled', width: 100 },
|
||||||
{ title: '创建人', dataIndex: 'createBy', key: 'createBy', width: 120 },
|
{ title: '创建人', dataIndex: 'createrName', key: 'createrName', width: 120 },
|
||||||
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
|
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
|
||||||
{ title: '排序', dataIndex: 'sortOrder', key: 'sortOrder', width: 100 },
|
{ title: '排序', dataIndex: 'sortOrder', key: 'sortOrder', width: 100 },
|
||||||
{ title: '操作', key: 'action', slotName: 'action', width: 150, fixed: 'right' }
|
{ title: '操作', key: 'action', slotName: 'action', width: 150, fixed: 'right' }
|
||||||
]
|
]
|
||||||
|
|
||||||
// 查询表单列定义
|
|
||||||
const queryFormColumns = [
|
|
||||||
{
|
|
||||||
label: '类型名称',
|
|
||||||
field: 'typeName',
|
|
||||||
component: 'a-input',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '请输入类型名称'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '备注',
|
|
||||||
field: 'remark',
|
|
||||||
component: 'a-input',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '请输入备注内容'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const dataList = ref<RegulationType[]>([])
|
const dataList = ref<RegulationType[]>([])
|
||||||
|
@ -158,6 +195,7 @@ const pagination = reactive({
|
||||||
// 查询表单
|
// 查询表单
|
||||||
const searchForm = reactive({
|
const searchForm = reactive({
|
||||||
typeName: '',
|
typeName: '',
|
||||||
|
isEnabled: '',
|
||||||
remark: ''
|
remark: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -188,6 +226,7 @@ const getTableData = async () => {
|
||||||
page: pagination.current,
|
page: pagination.current,
|
||||||
size: pagination.pageSize,
|
size: pagination.pageSize,
|
||||||
typeName: searchForm.typeName || undefined,
|
typeName: searchForm.typeName || undefined,
|
||||||
|
isEnabled: searchForm.isEnabled || undefined,
|
||||||
remark: searchForm.remark || undefined
|
remark: searchForm.remark || undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -206,16 +245,25 @@ const getTableData = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防抖搜索函数
|
||||||
|
const debouncedSearch = debounce(() => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}, 300)
|
||||||
|
|
||||||
// 搜索
|
// 搜索
|
||||||
const search = () => {
|
const search = () => {
|
||||||
pagination.current = 1
|
pagination.current = 1
|
||||||
getTableData()
|
getTableData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
Object.assign(searchForm, {
|
Object.assign(searchForm, {
|
||||||
typeName: '',
|
typeName: '',
|
||||||
|
isEnabled: '',
|
||||||
remark: ''
|
remark: ''
|
||||||
})
|
})
|
||||||
pagination.current = 1
|
pagination.current = 1
|
||||||
|
@ -330,4 +378,43 @@ onMounted(() => {
|
||||||
margin-bottom: 16px;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
Loading…
Reference in New Issue