add 项目管理
This commit is contained in:
parent
09eb888093
commit
c7a5299466
@ -1,6 +1,7 @@
|
||||
import { ServiceResponse } from './response';
|
||||
import { ServiceRequestPage } from './pageInput'
|
||||
import { PageResponse } from './pageResponse'
|
||||
import { ProjectUser, ProjectPrincipal } from './projectUserType'
|
||||
|
||||
// 过滤条件
|
||||
export interface ProjectFilter {
|
||||
@ -30,8 +31,18 @@ export interface ProjectDto {
|
||||
status?: boolean
|
||||
/** 创建时间 */
|
||||
createdTime?: string | null
|
||||
|
||||
/** 创建人姓名 */
|
||||
createdUserName?: string | null
|
||||
|
||||
/** 修改时间 */
|
||||
modifiedTime?: string | null
|
||||
|
||||
/** 项目成员 */
|
||||
projectUsers?: ProjectUser[]
|
||||
|
||||
/** 项目负责人 */
|
||||
projectPrincipals?: ProjectPrincipal[]
|
||||
}
|
||||
|
||||
/** 项目添加和更新输入接口 */
|
||||
@ -48,11 +59,17 @@ export interface ProjectAddInputAndUpdateInput {
|
||||
principalId?: number
|
||||
/** 状态 */
|
||||
status?: boolean
|
||||
|
||||
/** 项目成员 */
|
||||
projectUsers?: ProjectUser[]
|
||||
|
||||
/** 项目负责人 */
|
||||
projectPrincipals?: ProjectPrincipal[]
|
||||
}
|
||||
|
||||
// API 类型定义
|
||||
export type ProjectPageInput = ServiceRequestPage<ProjectFilter>;
|
||||
export type ProjectPageResponse = PageResponse<ProjectDto>;
|
||||
export type ProjectPageResponse = ServiceResponse<PageResponse<ProjectDto>>;
|
||||
export type ProjectOutput = ServiceResponse<ProjectDto>;
|
||||
export type ProjectAddInput = ProjectAddInputAndUpdateInput;
|
||||
export type ProjectUpdateInput = ProjectAddInputAndUpdateInput;
|
61
src/api/types/projectUserType.ts
Normal file
61
src/api/types/projectUserType.ts
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* 项目用户权限类型定义
|
||||
*/
|
||||
|
||||
/**
|
||||
* 项目用户权限信息
|
||||
*/
|
||||
export interface ProjectUser {
|
||||
/** ID */
|
||||
id?: number;
|
||||
|
||||
/** 项目ID */
|
||||
projectId?: number;
|
||||
|
||||
/** 所属组ID */
|
||||
groupId?: number;
|
||||
|
||||
/** 用户ID */
|
||||
userId: number;
|
||||
|
||||
/** 用户过期时间 */
|
||||
limitToDate?: string;
|
||||
|
||||
/** 上传权限 */
|
||||
upload: boolean;
|
||||
|
||||
/** 撤回上传权限 */
|
||||
revokeUpload: boolean;
|
||||
|
||||
/** 审核权限 */
|
||||
review: boolean;
|
||||
|
||||
/** 撤回审核权限 */
|
||||
revokeReview: boolean;
|
||||
|
||||
/** 签名权限 */
|
||||
signature: boolean;
|
||||
|
||||
/** 撤回签名权限 */
|
||||
revokeSignature: boolean;
|
||||
|
||||
/** 审核(二)权限 */
|
||||
verify: boolean;
|
||||
|
||||
/** 撤回审核(二)权限 */
|
||||
revokeVerify: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目负责人信息
|
||||
*/
|
||||
export interface ProjectPrincipal {
|
||||
/** ID */
|
||||
id?: number;
|
||||
|
||||
/** 项目ID */
|
||||
projectId?: number;
|
||||
|
||||
/** 用户ID */
|
||||
userId: number;
|
||||
}
|
@ -1,43 +1,128 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" :title="title" width="600px" append-to-body class="project-form-dialog">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" class="project-form">
|
||||
<el-form-item label="部门" prop="departmentId">
|
||||
<el-select v-model="form.departmentId" placeholder="请选择部门" style="width: 100%" filterable>
|
||||
<el-option v-for="item in state.departmentOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="项目编号" prop="projectNo">
|
||||
<el-input v-model="form.projectNo" placeholder="请输入项目编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="form.projectName" placeholder="请输入项目名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="责任人" prop="principalId">
|
||||
<el-select v-model="form.principalId" placeholder="请选择责任人" style="width: 100%" filterable>
|
||||
<el-option v-for="item in state.principalOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-switch v-model="form.status" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
destroy-on-close
|
||||
:title="title"
|
||||
draggable
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
width="1400px"
|
||||
>
|
||||
<div class="project-form-container">
|
||||
<!-- 左侧:项目基础信息 -->
|
||||
<div class="left-panel">
|
||||
<h4 class="panel-title">基础信息</h4>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" size="default">
|
||||
<el-form-item label="项目编号" prop="projectNo">
|
||||
<el-input v-model="form.projectNo" placeholder="请输入项目编号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="form.projectName" placeholder="请输入项目名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="责任人" prop="principalIds">
|
||||
<el-select v-model="form.principalIds" multiple placeholder="请选择责任人" style="width: 100%" filterable clearable>
|
||||
<el-option v-for="item in state.principalOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-switch v-model="form.status" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:项目人员列表 -->
|
||||
<div class="right-panel">
|
||||
<h4 class="panel-title">项目人员列表</h4>
|
||||
<div class="user-actions">
|
||||
<el-button type="primary" size="default" @click="handleAddUser">添加人员</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:data="form.projectUsers"
|
||||
style="width: 100%"
|
||||
size="default"
|
||||
border
|
||||
max-height="500"
|
||||
>
|
||||
<el-table-column prop="userName" label="用户名称" min-width="120" />
|
||||
<el-table-column label="审核权限" width="180">
|
||||
<template #default="{ row }">
|
||||
<div class="permission-grid">
|
||||
<el-checkbox v-model="row.upload" size="default">上传</el-checkbox>
|
||||
<el-checkbox v-model="row.verify" size="default">审核</el-checkbox>
|
||||
<el-checkbox v-model="row.review" size="default">下游审核</el-checkbox>
|
||||
<el-checkbox v-model="row.signature" size="default">签名</el-checkbox>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="撤回权限" width="230">
|
||||
<template #default="{ row }">
|
||||
<div class="permission-grid">
|
||||
<el-checkbox v-model="row.revokeUpload" size="default">撤回上传</el-checkbox>
|
||||
<el-checkbox v-model="row.revokeVerify" size="default">撤回审核</el-checkbox>
|
||||
<el-checkbox v-model="row.revokeReview" size="default">撤回下游审核</el-checkbox>
|
||||
<el-checkbox v-model="row.revokeSignature" size="default">撤回签名</el-checkbox>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="limitToDate" label="有效日期" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-date-picker
|
||||
v-model="row.limitToDate"
|
||||
type="date"
|
||||
placeholder="有效日期"
|
||||
size="default"
|
||||
style="width: 100%"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80" fixed="right">
|
||||
<template #default="{ $index }">
|
||||
<el-button
|
||||
type="danger"
|
||||
size="default"
|
||||
text
|
||||
@click="handleRemoveUser($index)"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="OnCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" :loading="state.sureLoading" @click="submitForm" size="default">确 定</el-button>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="OnCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" :loading="state.sureLoading" @click="submitForm" size="default">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<user-select
|
||||
ref="userSelectRef"
|
||||
:title="`添加【${form.projectName}】人员`"
|
||||
multiple
|
||||
:sure-loading="state.sureLoading"
|
||||
@sure="onSureUser"
|
||||
></user-select>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="admin/project/form">
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
import { ref, reactive, onMounted, getCurrentInstance, defineAsyncComponent } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { ProjectApi } from '../../../../api/admin/ProjectApi'
|
||||
import { ProjectApi } from '/@/api/admin/ProjectApi'
|
||||
import { OrgApi } from '/@/api/admin/Org'
|
||||
import { UserApi } from '/@/api/admin/User'
|
||||
import { ProjectAddInputAndUpdateInput } from '/@/api/types/projectType'
|
||||
import { ProjectUser } from '/@/api/types/projectUserType'
|
||||
import {
|
||||
UserGetPageOutput,
|
||||
} from '/@/api/admin/data-contracts'
|
||||
import eventBus from '/@/utils/mitt'
|
||||
|
||||
const UserSelect = defineAsyncComponent(() => import('/@/views/admin/user/components/user-select.vue'))
|
||||
const { proxy } = getCurrentInstance() as any
|
||||
|
||||
const props = defineProps<{
|
||||
@ -46,42 +131,51 @@ const props = defineProps<{
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const formRef = ref<FormInstance>()
|
||||
const form = reactive<ProjectAddInputAndUpdateInput>({
|
||||
departmentId: undefined,
|
||||
const userSelectRef = ref()
|
||||
|
||||
// 扩展项目表单接口
|
||||
interface ProjectFormData {
|
||||
id?: number
|
||||
projectNo: string
|
||||
projectName: string
|
||||
principalIds: number[]
|
||||
projectUsers: Array<{
|
||||
id?: number
|
||||
userId: number
|
||||
userName?: string
|
||||
groupId?: number
|
||||
groupName?: string
|
||||
limitToDate?: string
|
||||
upload: boolean
|
||||
revokeUpload: boolean
|
||||
review: boolean
|
||||
revokeReview: boolean
|
||||
signature: boolean
|
||||
revokeSignature: boolean
|
||||
verify: boolean
|
||||
revokeVerify: boolean
|
||||
}>
|
||||
status: boolean
|
||||
}
|
||||
|
||||
const form = reactive<ProjectFormData>({
|
||||
projectNo: '',
|
||||
projectName: '',
|
||||
principalId: undefined,
|
||||
principalIds: [],
|
||||
projectUsers: [],
|
||||
status: true
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
sureLoading: false,
|
||||
departmentOptions: [] as Array<{ id: number; name: string }>,
|
||||
principalOptions: [] as Array<{ id: number; name: string }>
|
||||
})
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
departmentId: [{ required: true, message: '请选择部门', trigger: 'change' }],
|
||||
projectNo: [{ required: true, message: '请输入项目编号', trigger: 'blur' }],
|
||||
projectName: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
|
||||
principalId: [{ required: true, message: '请选择责任人', trigger: 'change' }]
|
||||
projectName: [{ required: true, message: '请输入项目名称', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
/** 获取部门列表 */
|
||||
const getDepartmentOptions = async () => {
|
||||
try {
|
||||
const res = await new OrgApi().getList()
|
||||
if (res?.success && res.data) {
|
||||
state.departmentOptions = res.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.name
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取部门列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取负责人列表 */
|
||||
const getPrincipalOptions = async () => {
|
||||
try {
|
||||
@ -101,30 +195,55 @@ const getPrincipalOptions = async () => {
|
||||
}
|
||||
|
||||
const open = async (id?: number) => {
|
||||
proxy.$modal.loading()
|
||||
|
||||
// 先打开弹窗,避免loading遮罩造成的刷新感
|
||||
dialogVisible.value = true
|
||||
|
||||
// 如果是编辑模式且有ID,才显示loading
|
||||
if (id && id > 0) {
|
||||
const res = await new ProjectApi().get({ id }, { loading: true })
|
||||
if (res?.success && res.data) {
|
||||
const formData = res.data as unknown as ProjectAddInputAndUpdateInput
|
||||
Object.assign(form, formData)
|
||||
state.sureLoading = true
|
||||
try {
|
||||
const res = await new ProjectApi().get({ id }, { loading: false })
|
||||
if (res?.success && res.data) {
|
||||
const formData = res.data as any
|
||||
form.principalIds = Array.isArray(res.data.projectPrincipals)
|
||||
? res.data.projectPrincipals.map((item: any) => item.userId)
|
||||
: []
|
||||
|
||||
// TODO 负责人多选控件不能加载问题
|
||||
console.log("form.principalIds", form.principalIds)
|
||||
|
||||
form.projectUsers = Array.isArray(formData.projectUsers) ? formData.projectUsers : []
|
||||
form.projectUsers.forEach((item: any) => {
|
||||
item.userName = state.principalOptions.find((a) => a.id === item.userId)?.name || ''
|
||||
})
|
||||
|
||||
Object.assign(form, {
|
||||
id: formData.id,
|
||||
projectNo: formData.projectNo || '',
|
||||
projectName: formData.projectName || '',
|
||||
principalIds: formData.projectPrincipalIds || [],
|
||||
projectUsers: formData.projectUsers || [],
|
||||
status: formData.status !== undefined ? formData.status : true
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取项目详情失败:', error)
|
||||
} finally {
|
||||
state.sureLoading = false
|
||||
}
|
||||
} else {
|
||||
// 新增模式,直接重置表单
|
||||
Object.assign(form, {
|
||||
departmentId: undefined,
|
||||
projectNo: '',
|
||||
projectName: '',
|
||||
principalId: undefined,
|
||||
principalIds: [],
|
||||
projectUsers: [],
|
||||
status: true
|
||||
})
|
||||
}
|
||||
proxy.$modal.closeLoading()
|
||||
dialogVisible.value = true
|
||||
|
||||
await Promise.all([
|
||||
getDepartmentOptions(),
|
||||
getPrincipalOptions()
|
||||
])
|
||||
if (state.principalOptions.length === 0) {
|
||||
await getPrincipalOptions()
|
||||
}
|
||||
}
|
||||
|
||||
/** 取消 */
|
||||
@ -141,7 +260,16 @@ const submitForm = async () => {
|
||||
state.sureLoading = true
|
||||
try {
|
||||
const api = new ProjectApi()
|
||||
const res = form.id ? await api.update(form) : await api.add(form)
|
||||
// 转换数据格式以匹配后端API
|
||||
const submitData = {
|
||||
id: form.id,
|
||||
projectNo: form.projectNo,
|
||||
projectName: form.projectName,
|
||||
status: form.status,
|
||||
projectPrincipals: form.principalIds.map((id: number) => ({ userId: id })),
|
||||
projectUsers: form.projectUsers.length > 0 ? form.projectUsers : []
|
||||
}
|
||||
const res = form.id ? await api.update(submitData as any) : await api.add(submitData as any)
|
||||
if (res.success) {
|
||||
ElMessage.success(form.id ? '修改成功' : '新增成功')
|
||||
dialogVisible.value = false
|
||||
@ -159,9 +287,53 @@ const submitForm = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getDepartmentOptions()
|
||||
getPrincipalOptions()
|
||||
const handleAddUser = () => {
|
||||
userSelectRef.value.open()
|
||||
}
|
||||
|
||||
const onSureUser = async (users: UserGetPageOutput[]) => {
|
||||
if (!(users?.length > 0)) {
|
||||
userSelectRef.value.close()
|
||||
return
|
||||
}
|
||||
|
||||
state.sureLoading = true
|
||||
// 过滤掉 id 为 undefined 的用户,保证 userId 类型安全
|
||||
const validUsers = users?.filter((u) => typeof u.id === 'number') ?? []
|
||||
|
||||
// 避免重复添加
|
||||
const existingUserIds = form.projectUsers.map((u) => u.userId)
|
||||
const newUsers = validUsers.filter((u) => !existingUserIds.includes(u.id as number))
|
||||
|
||||
const newUserList = newUsers.map((u) => ({
|
||||
userId: u.id as number, // 明确断言为 number,避免类型错误
|
||||
userName: u.userName ?? '',
|
||||
groupName: '',
|
||||
limitToDate: '',
|
||||
upload: false,
|
||||
revokeUpload: false,
|
||||
review: false,
|
||||
revokeReview: false,
|
||||
signature: false,
|
||||
revokeSignature: false,
|
||||
verify: false,
|
||||
revokeVerify: false
|
||||
}))
|
||||
form.projectUsers.push(...newUserList)
|
||||
state.sureLoading = false
|
||||
userSelectRef.value.close()
|
||||
}
|
||||
|
||||
/** 删除用户 */
|
||||
const handleRemoveUser = (index: number) => {
|
||||
form.projectUsers.splice(index, 1)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 组件挂载时就加载选项数据,避免弹窗打开时的延迟
|
||||
await Promise.all([
|
||||
getPrincipalOptions()
|
||||
])
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
@ -170,15 +342,105 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.project-form-dialog {
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 20px 30px;
|
||||
.project-form-container {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
min-height: 650px;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
flex: 0 0 350px;
|
||||
padding: 20px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 6px;
|
||||
background-color: #fafafa;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 6px;
|
||||
background-color: #fafafa;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
margin: 0 0 20px 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #409eff;
|
||||
}
|
||||
|
||||
.user-actions {
|
||||
margin-bottom: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
:deep(.el-table) {
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.el-table .el-table__body-wrapper) {
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #c1c1c1 #f1f1f1;
|
||||
}
|
||||
|
||||
:deep(.el-table .el-table__body-wrapper::-webkit-scrollbar) {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
:deep(.el-table .el-table__body-wrapper::-webkit-scrollbar-track) {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-table .el-table__body-wrapper::-webkit-scrollbar-thumb) {
|
||||
background: #c1c1c1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-table .el-table__body-wrapper::-webkit-scrollbar-thumb:hover) {
|
||||
background: #a0a0a0;
|
||||
}
|
||||
|
||||
.permission-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
|
||||
.el-checkbox {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.project-form {
|
||||
.el-form-item {
|
||||
margin-bottom: 22px;
|
||||
@media (max-width: 768px) {
|
||||
:deep(.el-dialog) {
|
||||
height: 95vh;
|
||||
width: 95vw !important;
|
||||
}
|
||||
|
||||
.project-form-container {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.left-panel,
|
||||
.right-panel {
|
||||
flex: none;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.permission-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,37 +1,27 @@
|
||||
<template>
|
||||
<my-layout>
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-form :inline="true" :model="state.filter" class="demo-form-inline">
|
||||
<el-form-item label="关键字">
|
||||
<el-input v-model="state.filter.keyWord" placeholder="请输入关键字" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门">
|
||||
<el-select v-model="state.filter.departmentId" placeholder="请选择部门" clearable filterable>
|
||||
<el-option v-for="item in state.departmentOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||
<el-button @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button v-auth="'api:admin:project:add'" type="primary" @click="handleAdd">新增</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 查询区 -->
|
||||
<el-card class="my-query-box mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
|
||||
<el-form :inline="true" label-width="auto" :model="state.filter" class="demo-form-inline" @submit.stop.prevent>
|
||||
<el-form-item label="关键字">
|
||||
<el-input v-model="state.filter.keyWord" placeholder="请输入关键字" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="ele-Search" @click="handleQuery"> 查询 </el-button>
|
||||
<el-button v-auth="'api:admin:project:add'" type="primary" icon="ele-Plus" @click="handleAdd"> 新增 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-table v-loading="loading" :data="state.projectList" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<!-- 表格区 -->
|
||||
<el-card class="my-fill mt8" shadow="never">
|
||||
<div class="my-tools-box mb8 my-flex my-flex-between">
|
||||
<!-- 可添加工具栏内容,如批量操作等 -->
|
||||
</div>
|
||||
<el-table v-loading="loading" :data="state.projectList" style="width: 100%" border row-key="projectNo">
|
||||
<el-table-column prop="projectNo" label="项目编号" />
|
||||
<el-table-column prop="projectName" label="项目名称" />
|
||||
<el-table-column prop="departmentName" label="部门" />
|
||||
<el-table-column prop="principalName" label="责任人" />
|
||||
<el-table-column prop="status" label="状态" width="80">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status ? 'success' : 'danger'">{{ row.status ? '启用' : '禁用' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdUserName" label="创建人" />
|
||||
<el-table-column prop="createdTime" label="创建时间" width="180" />
|
||||
<el-table-column label="操作" width="180" fixed="right" header-align="center" align="center">
|
||||
<template #default="{ row }">
|
||||
@ -72,14 +62,12 @@ const state = reactive({
|
||||
total: 0,
|
||||
filter: {
|
||||
keyWord: '',
|
||||
departmentId: undefined as number | undefined
|
||||
},
|
||||
pageInput: {
|
||||
currentPage: 1,
|
||||
pageSize: 20,
|
||||
} as ProjectPageInput,
|
||||
projectList: [] as Array<ProjectDto>,
|
||||
departmentOptions: [] as Array<{ id: number; name: string }>
|
||||
projectList: [] as Array<ProjectDto>
|
||||
})
|
||||
|
||||
/** 查询列表 */
|
||||
@ -88,8 +76,8 @@ const getList = async () => {
|
||||
state.pageInput.filter = state.filter
|
||||
try {
|
||||
const res = await new ProjectApi().getPage(state.pageInput)
|
||||
state.projectList = res.list || []
|
||||
state.total = res.total || 0
|
||||
state.projectList = res.data?.list || []
|
||||
state.total = res.data?.total || 0
|
||||
} catch (error) {
|
||||
console.error('获取列表失败:', error)
|
||||
} finally {
|
||||
@ -97,21 +85,6 @@ const getList = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取部门列表 */
|
||||
const getDepartmentOptions = async () => {
|
||||
try {
|
||||
const res = await new OrgApi().getList()
|
||||
if (res?.success && res.data) {
|
||||
state.departmentOptions = res.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.name
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取部门列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
state.pageInput.currentPage = 1
|
||||
@ -122,7 +95,6 @@ const handleQuery = () => {
|
||||
const resetQuery = () => {
|
||||
state.filter = {
|
||||
keyWord: '',
|
||||
departmentId: undefined
|
||||
}
|
||||
handleQuery()
|
||||
}
|
||||
@ -172,7 +144,6 @@ const handleCurrentChange = (val: number) => {
|
||||
|
||||
onMounted(() => {
|
||||
getList()
|
||||
getDepartmentOptions()
|
||||
eventBus.on('refreshProject', getList)
|
||||
})
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user