提交宿管代码

This commit is contained in:
zlwu committed 2025-07-21 14:00:18 +08:00
1 parent 49899ca537
commit 225a268e32
80 files changed
+6931 -15

No files matched your search

@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { DormManagerSourceVO, DormManagerSourceForm, DormManagerSourceQuery } from '@/api/glysqgx/dormManagerSource/types';
/**
* 查询管理员授权关系列表
* @param query
* @returns {*}
*/
export const listDormManagerSource = (query?: DormManagerSourceQuery): AxiosPromise<DormManagerSourceVO[]> => {
return request({
url: '/glysqgx/dormManagerSource/list',
method: 'get',
params: query
});
};
/**
* 查询管理员授权关系详细
* @param id
*/
export const getDormManagerSource = (id: string | number): AxiosPromise<DormManagerSourceVO> => {
return request({
url: '/glysqgx/dormManagerSource/' + id,
method: 'get'
});
};
/**
* 新增管理员授权关系
* @param data
*/
export const addDormManagerSource = (data: DormManagerSourceForm) => {
return request({
url: '/glysqgx/dormManagerSource',
method: 'post',
data: data
});
};
/**
* 修改管理员授权关系
* @param data
*/
export const updateDormManagerSource = (data: DormManagerSourceForm) => {
return request({
url: '/glysqgx/dormManagerSource',
method: 'put',
data: data
});
};
/**
* 删除管理员授权关系
* @param id
*/
export const delDormManagerSource = (id: string | number | Array<string | number>) => {
return request({
url: '/glysqgx/dormManagerSource/' + id,
method: 'delete'
});
};
@@ -0,0 +1,126 @@
export interface DormManagerSourceVO {
/**
* 主键ID
*/
id: string | number;
/**
* 管理员ID
*/
managerId: string | number;
/**
* 权限类型(1查看 2编辑 3完全管理)
*/
permissionType: string;
/**
* 授权类型(1全校级 2校区级 3宿舍区级 4楼栋级)
*/
authType: string;
/**
* 授权来源ID(对应校区ID或宿舍区ID或楼栋ID)
*/
authSource: number;
/**
* 状态(0有效 1已撤销)
*/
status: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted: string;
/**
* 备注
*/
remark: string;
}
export interface DormManagerSourceForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 管理员ID
*/
managerId?: string | number;
/**
* 权限类型(1查看 2编辑 3完全管理)
*/
permissionType?: string;
/**
* 授权类型(1全校级 2校区级 3宿舍区级 4楼栋级)
*/
authType?: string;
/**
* 授权来源ID(对应校区ID或宿舍区ID或楼栋ID)
*/
authSource?: number;
/**
* 状态(0有效 1已撤销)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 备注
*/
remark?: string;
}
export interface DormManagerSourceQuery extends PageQuery {
/**
* 管理员ID
*/
managerId?: string | number;
/**
* 权限类型(1查看 2编辑 3完全管理)
*/
permissionType?: string;
/**
* 授权类型(1全校级 2校区级 3宿舍区级 4楼栋级)
*/
authType?: string;
/**
* 授权来源ID(对应校区ID或宿舍区ID或楼栋ID)
*/
authSource?: number;
/**
* 状态(0有效 1已撤销)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 日期范围参数
*/
params?: any;
}
@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { DormManagerBuildingVO, DormManagerBuildingForm, DormManagerBuildingQuery } from '@/api/glysslqxgx/dormManagerBuilding/types';
/**
* 查询管理员宿舍楼权限关系列表
* @param query
* @returns {*}
*/
export const listDormManagerBuilding = (query?: DormManagerBuildingQuery): AxiosPromise<DormManagerBuildingVO[]> => {
return request({
url: '/glysslqxgx/dormManagerBuilding/list',
method: 'get',
params: query
});
};
/**
* 查询管理员宿舍楼权限关系详细
* @param id
*/
export const getDormManagerBuilding = (id: string | number): AxiosPromise<DormManagerBuildingVO> => {
return request({
url: '/glysslqxgx/dormManagerBuilding/' + id,
method: 'get'
});
};
/**
* 新增管理员宿舍楼权限关系
* @param data
*/
export const addDormManagerBuilding = (data: DormManagerBuildingForm) => {
return request({
url: '/glysslqxgx/dormManagerBuilding',
method: 'post',
data: data
});
};
/**
* 修改管理员宿舍楼权限关系
* @param data
*/
export const updateDormManagerBuilding = (data: DormManagerBuildingForm) => {
return request({
url: '/glysslqxgx/dormManagerBuilding',
method: 'put',
data: data
});
};
/**
* 删除管理员宿舍楼权限关系
* @param id
*/
export const delDormManagerBuilding = (id: string | number | Array<string | number>) => {
return request({
url: '/glysslqxgx/dormManagerBuilding/' + id,
method: 'delete'
});
};
@@ -0,0 +1,96 @@
export interface DormManagerBuildingVO {
/**
* 主键ID
*/
id: string | number;
/**
* 管理员ID
*/
managerId: string | number;
/**
* 宿舍楼ID
*/
buildingId: string | number;
/**
* 状态(0有效 1已撤销)
*/
status: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted: string;
/**
* 备注
*/
remark: string;
}
export interface DormManagerBuildingForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 管理员ID
*/
managerId?: string | number;
/**
* 宿舍楼ID
*/
buildingId?: string | number;
/**
* 状态(0有效 1已撤销)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 备注
*/
remark?: string;
}
export interface DormManagerBuildingQuery extends PageQuery {
/**
* 管理员ID
*/
managerId?: string | number;
/**
* 宿舍楼ID
*/
buildingId?: string | number;
/**
* 状态(0有效 1已撤销)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 日期范围参数
*/
params?: any;
}
+63
View File
@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { DormManagerVO, DormManagerForm, DormManagerQuery } from '@/api/ssglyxx/dormManager/types';
/**
* 查询宿舍管理员信息列表
* @param query
* @returns {*}
*/
export const listDormManager = (query?: DormManagerQuery): AxiosPromise<DormManagerVO[]> => {
return request({
url: '/ssglyxx/dormManager/list',
method: 'get',
params: query
});
};
/**
* 查询宿舍管理员信息详细
* @param id
*/
export const getDormManager = (id: string | number): AxiosPromise<DormManagerVO> => {
return request({
url: '/ssglyxx/dormManager/' + id,
method: 'get'
});
};
/**
* 新增宿舍管理员信息
* @param data
*/
export const addDormManager = (data: DormManagerForm) => {
return request({
url: '/ssglyxx/dormManager',
method: 'post',
data: data
});
};
/**
* 修改宿舍管理员信息
* @param data
*/
export const updateDormManager = (data: DormManagerForm) => {
return request({
url: '/ssglyxx/dormManager',
method: 'put',
data: data
});
};
/**
* 删除宿舍管理员信息
* @param id
*/
export const delDormManager = (id: string | number | Array<string | number>) => {
return request({
url: '/ssglyxx/dormManager/' + id,
method: 'delete'
});
};
+156
View File
@@ -0,0 +1,156 @@
export interface DormManagerVO {
/**
* 主键ID
*/
id: string | number;
/**
* 管理员姓名
*/
managerName: string;
/**
* 管理员类型(1全校管理员 2校区管理员 3宿舍区管理员 4宿舍楼管理员)
*/
managerType: string;
/**
* 管理级别(1-5,1为最高)
*/
managerLevel: number;
/**
* 关联用户ID
*/
userId: string | number;
/**
* 联系电话
*/
phone: string;
/**
* 性别(0男 1女 2未知)
*/
gender: string;
/**
* 状态(0正常 1停用)
*/
status: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted: string;
/**
* 备注
*/
remark: string;
}
export interface DormManagerForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 管理员姓名
*/
managerName?: string;
/**
* 管理员类型(1全校管理员 2校区管理员 3宿舍区管理员 4宿舍楼管理员)
*/
managerType?: string;
/**
* 管理级别(1-5,1为最高)
*/
managerLevel?: number;
/**
* 关联用户ID
*/
userId?: string | number;
/**
* 联系电话
*/
phone?: string;
/**
* 性别(0男 1女 2未知)
*/
gender?: string;
/**
* 状态(0正常 1停用)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 备注
*/
remark?: string;
}
export interface DormManagerQuery extends PageQuery {
/**
* 管理员姓名
*/
managerName?: string;
/**
* 管理员类型(1全校管理员 2校区管理员 3宿舍区管理员 4宿舍楼管理员)
*/
managerType?: string;
/**
* 管理级别(1-5,1为最高)
*/
managerLevel?: number;
/**
* 关联用户ID
*/
userId?: string | number;
/**
* 联系电话
*/
phone?: string;
/**
* 性别(0男 1女 2未知)
*/
gender?: string;
/**
* 状态(0正常 1停用)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 日期范围参数
*/
params?: any;
}
+85
View File
@@ -0,0 +1,85 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { DormBuildingVO, DormBuildingForm, DormBuildingQuery } from '@/api/sslxx/dormBuilding/types';
/**
* 查询宿舍楼信息列表
* @param query
* @returns {*}
*/
export const listDormBuilding = (query?: DormBuildingQuery): AxiosPromise<DormBuildingVO[]> => {
return request({
url: '/sslxx/dormBuilding/list',
method: 'get',
params: query
});
};
/**
* 查询宿舍楼信息详细
* @param id
*/
export const getDormBuilding = (id: string | number): AxiosPromise<DormBuildingVO> => {
return request({
url: '/sslxx/dormBuilding/' + id,
method: 'get'
});
};
/**
* 新增宿舍楼信息
* @param data
*/
export const addDormBuilding = (data: DormBuildingForm) => {
return request({
url: '/sslxx/dormBuilding',
method: 'post',
data: data
});
};
/**
* 修改宿舍楼信息
* @param data
*/
export const updateDormBuilding = (data: DormBuildingForm) => {
return request({
url: '/sslxx/dormBuilding',
method: 'put',
data: data
});
};
/**
* 删除宿舍楼信息
* @param id
*/
export const delDormBuilding = (id: string | number | Array<string | number>) => {
return request({
url: '/sslxx/dormBuilding/' + id,
method: 'delete'
});
};
/**
* 获取校区选项列表
*/
export const listCampusOptions = (): AxiosPromise<any> => {
return request({
url: '/xqxx/dormCampus/list',
method: 'get'
});
};
/**
* 获取宿舍区树形数据
* @param campusId 校区ID,如果指定则只返回该校区的宿舍区
*/
export const listAreaTreeData = (campusId?: string | number): AxiosPromise<any> => {
return request({
url: '/ssqxx/dormArea/list',
method: 'get',
params: { campusId }
});
};
+126
View File
@@ -0,0 +1,126 @@
export interface DormBuildingVO {
/**
* 主键ID
*/
id: string | number;
/**
* 宿舍楼编码
*/
buildingCode: string;
/**
* 宿舍楼名称
*/
buildingName: string;
/**
* 所属宿舍区ID
*/
areaId: string | number;
/**
* 所属校区ID
*/
campusId: string | number;
/**
* 宿舍楼类型(1男生楼 2女生楼 3混合楼)
*/
buildingType: string;
/**
* 宿舍楼描述
*/
buildingDescription: string;
/**
* 排序号
*/
sortOrder: number;
}
export interface DormBuildingForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 宿舍楼编码
*/
buildingCode?: string;
/**
* 宿舍楼名称
*/
buildingName?: string;
/**
* 所属宿舍区ID
*/
areaId?: string | number;
/**
* 所属校区ID
*/
campusId?: string | number;
/**
* 宿舍楼类型(1男生楼 2女生楼 3混合楼)
*/
buildingType?: string;
/**
* 宿舍楼描述
*/
buildingDescription?: string;
/**
* 排序号
*/
sortOrder?: number;
}
export interface DormBuildingQuery extends PageQuery {
/**
* 宿舍楼编码
*/
buildingCode?: string;
/**
* 宿舍楼名称
*/
buildingName?: string;
/**
* 所属宿舍区ID
*/
areaId?: string | number;
/**
* 所属校区ID
*/
campusId?: string | number;
/**
* 宿舍楼类型(1男生楼 2女生楼 3混合楼)
*/
buildingType?: string;
/**
* 排序号
*/
sortOrder?: number;
/**
* 日期范围参数
*/
params?: any;
}
+63
View File
@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { DormAreaVO, DormAreaForm, DormAreaQuery } from '@/api/ssqxx/dormArea/types';
/**
* 查询宿舍区信息列表
* @param query
* @returns {*}
*/
export const listDormArea = (query?: DormAreaQuery): AxiosPromise<DormAreaVO[]> => {
return request({
url: '/ssqxx/dormArea/list',
method: 'get',
params: query
});
};
/**
* 查询宿舍区信息详细
* @param id
*/
export const getDormArea = (id: string | number): AxiosPromise<DormAreaVO> => {
return request({
url: '/ssqxx/dormArea/' + id,
method: 'get'
});
};
/**
* 新增宿舍区信息
* @param data
*/
export const addDormArea = (data: DormAreaForm) => {
return request({
url: '/ssqxx/dormArea',
method: 'post',
data: data
});
};
/**
* 修改宿舍区信息
* @param data
*/
export const updateDormArea = (data: DormAreaForm) => {
return request({
url: '/ssqxx/dormArea',
method: 'put',
data: data
});
};
/**
* 删除宿舍区信息
* @param id
*/
export const delDormArea = (id: string | number | Array<string | number>) => {
return request({
url: '/ssqxx/dormArea/' + id,
method: 'delete'
});
};
+91
View File
@@ -0,0 +1,91 @@
export interface DormAreaVO {
/**
* 主键ID
*/
id: string | number;
/**
* 宿舍区编码
*/
areaCode: string;
/**
* 宿舍区名称
*/
areaName: string;
/**
* 所属校区ID
*/
campusId: string | number;
/**
* 宿舍区描述
*/
areaDescription: string;
/**
* 排序号
*/
sortOrder: number;
}
export interface DormAreaForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 宿舍区编码
*/
areaCode?: string;
/**
* 宿舍区名称
*/
areaName?: string;
/**
* 所属校区ID
*/
campusId?: string | number;
/**
* 宿舍区描述
*/
areaDescription?: string;
/**
* 排序号
*/
sortOrder?: number;
}
export interface DormAreaQuery extends PageQuery {
/**
* 宿舍区编码
*/
areaCode?: string;
/**
* 宿舍区名称
*/
areaName?: string;
/**
* 宿舍区描述
*/
areaDescription?: string;
/**
* 日期范围参数
*/
params?: any;
}
+63
View File
@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { DormCampusVO, DormCampusForm, DormCampusQuery } from '@/api/xqxx/dormCampus/types';
/**
* 查询校区信息列表
* @param query
* @returns {*}
*/
export const listDormCampus = (query?: DormCampusQuery): AxiosPromise<DormCampusVO[]> => {
return request({
url: '/xqxx/dormCampus/list',
method: 'get',
params: query
});
};
/**
* 查询校区信息详细
* @param id
*/
export const getDormCampus = (id: string | number): AxiosPromise<DormCampusVO> => {
return request({
url: '/xqxx/dormCampus/' + id,
method: 'get'
});
};
/**
* 新增校区信息
* @param data
*/
export const addDormCampus = (data: DormCampusForm) => {
return request({
url: '/xqxx/dormCampus',
method: 'post',
data: data
});
};
/**
* 修改校区信息
* @param data
*/
export const updateDormCampus = (data: DormCampusForm) => {
return request({
url: '/xqxx/dormCampus',
method: 'put',
data: data
});
};
/**
* 删除校区信息
* @param id
*/
export const delDormCampus = (id: string | number | Array<string | number>) => {
return request({
url: '/xqxx/dormCampus/' + id,
method: 'delete'
});
};
+86
View File
@@ -0,0 +1,86 @@
export interface DormCampusVO {
/**
* 主键ID
*/
id: string | number;
/**
* 校区编码
*/
campusCode: string;
/**
* 校区名称
*/
campusName: string;
/**
* 校区描述
*/
campusDescription: string;
/**
* 排序号
*/
sortOrder: number;
/**
* 备注
*/
remark: string;
}
export interface DormCampusForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 校区编码
*/
campusCode?: string;
/**
* 校区名称
*/
campusName?: string;
/**
* 校区描述
*/
campusDescription?: string;
/**
* 排序号
*/
sortOrder?: number;
/**
* 备注
*/
remark?: string;
}
export interface DormCampusQuery extends PageQuery {
/**
* 校区编码
*/
campusCode?: string;
/**
* 校区名称
*/
campusName?: string;
/**
* 日期范围参数
*/
params?: any;
}
+53
View File
@@ -0,0 +1,53 @@
import request from '@/utils/request';
// 获取教师列表(根据role_key=teacher筛选)
export function getTeacherList(name?: string, managerType?: string) {
return request({
url: '/ssglyxx/dormManager/teachers',
method: 'get',
params: { name, managerType }
});
}
// 查询宿舍管理员列表
export function listDormManager(query: any) {
return request({
url: '/ssglyxx/dormManager/list',
method: 'get',
params: query
});
}
// 查询宿舍管理员详情
export function getDormManager(id: number) {
return request({
url: `/ssglyxx/dormManager/${id}`,
method: 'get'
});
}
// 新增宿舍管理员
export function addDormManager(data: any) {
return request({
url: '/ssglyxx/dormManager',
method: 'post',
data
});
}
// 修改宿舍管理员
export function updateDormManager(data: any) {
return request({
url: '/ssglyxx/dormManager',
method: 'put',
data
});
}
// 删除宿舍管理员
export function deleteDormManager(ids: number | number[]) {
return request({
url: `/ssglyxx/dormManager/${ids instanceof Array ? ids.join(',') : ids}`,
method: 'delete'
});
}
+540
View File
@@ -0,0 +1,540 @@
<template>
<div class="p-2 page-container">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="宿舍楼编码" prop="buildingCode">
<el-input v-model="queryParams.buildingCode" placeholder="请输入宿舍楼编码" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="宿舍楼名称" prop="buildingName">
<el-input v-model="queryParams.buildingName" placeholder="请输入宿舍楼名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="所属校区" prop="campusId">
<el-select v-model="queryParams.campusId" placeholder="请选择所属校区" clearable @change="handleCampusChange">
<el-option v-for="item in campusList" :key="item.id" :label="item.campusName" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="所属宿舍区" prop="areaId">
<el-tree-select
v-model="queryParams.areaId"
:data="areaTreeData"
:props="{ label: 'areaName', value: 'id' }"
placeholder="请选择所属宿舍区"
clearable
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="宿舍楼类型" prop="buildingType">
<el-select v-model="queryParams.buildingType" placeholder="请选择宿舍楼类型" clearable>
<el-option v-for="dict in dorm_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24" class="search-btn-container">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['sslxx:dormBuilding:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['sslxx:dormBuilding:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['sslxx:dormBuilding:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['sslxx:dormBuilding:export']">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="dormBuildingList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="id" v-if="true" />
<el-table-column label="宿舍楼编码" align="center" prop="buildingCode" />
<el-table-column label="宿舍楼名称" align="center" prop="buildingName" />
<el-table-column label="所属校区" align="center" prop="campusName" />
<el-table-column label="所属宿舍区" align="center" prop="areaName" />
<el-table-column label="宿舍楼类型" align="center" prop="buildingType">
<template #default="scope">
<dict-tag :options="dorm_type" :value="scope.row.buildingType" />
</template>
</el-table-column>
<el-table-column label="宿舍楼描述" align="center" prop="buildingDescription" />
<el-table-column label="排序号" align="center" prop="sortOrder" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['sslxx:dormBuilding:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['sslxx:dormBuilding:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改宿舍楼信息对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="dormBuildingFormRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="所属校区" prop="campusId">
<el-select v-model="form.campusId" placeholder="请选择所属校区" clearable @change="handleFormCampusChange">
<el-option v-for="item in campusList" :key="item.id" :label="item.campusName" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="所属宿舍区" prop="areaId">
<el-tree-select
v-model="form.areaId"
:data="formAreaTreeData"
:props="{ label: 'areaName', value: 'id' }"
placeholder="请选择所属宿舍区"
clearable
/>
</el-form-item>
<el-form-item label="宿舍楼编码" prop="buildingCode">
<el-input v-model="form.buildingCode" placeholder="请输入宿舍楼编码" />
</el-form-item>
<el-form-item label="宿舍楼名称" prop="buildingName">
<el-input v-model="form.buildingName" placeholder="请输入宿舍楼名称" />
</el-form-item>
<el-form-item label="宿舍楼类型" prop="buildingType">
<el-select v-model="form.buildingType" placeholder="请选择宿舍楼类型">
<el-option v-for="dict in dorm_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="宿舍楼描述" prop="buildingDescription">
<el-input v-model="form.buildingDescription" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="form.sortOrder" placeholder="请输入排序号" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="DormBuilding" lang="ts">
import {
listDormBuilding,
getDormBuilding,
delDormBuilding,
addDormBuilding,
updateDormBuilding,
listCampusOptions,
listAreaTreeData
} from '@/api/sslxx/dormBuilding';
import { DormBuildingVO, DormBuildingQuery, DormBuildingForm } from '@/api/sslxx/dormBuilding/types';
import { DormCampusVO } from '@/api/xqxx/dormCampus/types';
import { DormAreaVO } from '@/api/ssqxx/dormArea/types';
import { getCurrentInstance, ComponentInternalInstance, ref, reactive, toRefs, onMounted } from 'vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { dorm_type } = toRefs<any>(proxy?.useDict('dorm_type'));
const dormBuildingList = ref<DormBuildingVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const campusList = ref<DormCampusVO[]>([]); // 校区列表
const areaTreeData = ref<any[]>([]); // 宿舍区树形数据
const formAreaTreeData = ref<any[]>([]); // 表单宿舍区树形数据
const queryFormRef = ref<ElFormInstance>();
const dormBuildingFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: DormBuildingForm = {
id: undefined,
buildingCode: undefined,
buildingName: undefined,
areaId: undefined,
campusId: undefined,
buildingType: undefined,
buildingDescription: undefined,
sortOrder: undefined
};
const data = reactive<PageData<DormBuildingForm, DormBuildingQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
buildingCode: undefined,
buildingName: undefined,
areaId: undefined,
campusId: undefined,
buildingType: undefined,
sortOrder: undefined,
params: {}
},
rules: {
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
buildingCode: [{ required: true, message: '宿舍楼编码不能为空', trigger: 'blur' }],
buildingName: [{ required: true, message: '宿舍楼名称不能为空', trigger: 'blur' }],
areaId: [{ required: true, message: '所属宿舍区ID不能为空', trigger: 'blur' }],
campusId: [{ required: true, message: '所属校区ID不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询宿舍楼信息列表 */
const getList = async () => {
loading.value = true;
const res = await listDormBuilding(queryParams.value);
dormBuildingList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 加载校区数据 */
const loadCampusOptions = async () => {
const res = await listCampusOptions();
campusList.value = res.rows || [];
};
/** 加载宿舍区树形数据 */
const loadAreaTreeData = async (campusId?: string | number) => {
const res = await listAreaTreeData(campusId);
if (campusId) {
// 如果指定了校区ID,只展示该校区的宿舍区
areaTreeData.value = res.rows || [];
formAreaTreeData.value = res.rows || []; // 同时更新表单树形数据
} else {
// 如果没有指定校区ID,按照校区分组展示宿舍区
const campusMap = new Map();
// 先将校区列表转为Map
campusList.value.forEach((campus) => {
campusMap.set(campus.id, {
id: campus.id,
areaName: campus.campusName,
children: []
});
});
// 将宿舍区按校区分组
const areas = res.rows || [];
areas.forEach((area: DormAreaVO) => {
if (campusMap.has(area.campusId)) {
campusMap.get(area.campusId).children.push({
id: area.id,
areaName: area.areaName
});
}
});
// 转换为树形结构
areaTreeData.value = Array.from(campusMap.values());
formAreaTreeData.value = Array.from(campusMap.values());
}
};
/** 校区选择变化处理函数 */
const handleCampusChange = (value: string | number) => {
queryParams.value.areaId = undefined; // 清空已选择的宿舍区
loadAreaTreeData(value);
};
/** 表单校区选择变化处理函数 */
const handleFormCampusChange = (value: string | number) => {
form.value.areaId = undefined; // 清空已选择的宿舍区
loadFormAreaTreeData(value);
};
/** 加载表单宿舍区树形数据 */
const loadFormAreaTreeData = async (campusId?: string | number) => {
const res = await listAreaTreeData(campusId);
if (campusId) {
// 如果指定了校区ID,只展示该校区的宿舍区
formAreaTreeData.value = res.rows || [];
} else {
// 如果没有指定校区ID,按照校区分组展示宿舍区
const campusMap = new Map();
// 先将校区列表转为Map
campusList.value.forEach((campus) => {
campusMap.set(campus.id, {
id: campus.id,
areaName: campus.campusName,
children: []
});
});
// 将宿舍区按校区分组
const areas = res.rows || [];
areas.forEach((area: DormAreaVO) => {
if (campusMap.has(area.campusId)) {
campusMap.get(area.campusId).children.push({
id: area.id,
areaName: area.areaName
});
}
});
// 转换为树形结构
formAreaTreeData.value = Array.from(campusMap.values());
}
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
dormBuildingFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: DormBuildingVO[]) => {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加宿舍楼信息';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: DormBuildingVO) => {
reset();
const _id = row?.id || ids.value[0];
const res = await getDormBuilding(_id);
Object.assign(form.value, res.data);
// 加载表单中的宿舍区数据
if (form.value.campusId) {
loadFormAreaTreeData(form.value.campusId);
}
dialog.visible = true;
dialog.title = '修改宿舍楼信息';
};
/** 提交按钮 */
const submitForm = () => {
dormBuildingFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateDormBuilding(form.value).finally(() => (buttonLoading.value = false));
} else {
await addDormBuilding(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: DormBuildingVO) => {
const _ids = row?.id || ids.value;
let confirmMsg = '';
if (row) {
confirmMsg = `是否确认删除宿舍楼信息编号为"${row?.buildingName}"的数据项?`;
} else if (Array.isArray(ids.value) && ids.value.length > 1) {
confirmMsg = `是否确认删除选中的${ids.value.length}个宿舍楼信息?`;
} else {
confirmMsg = '是否确认删除选中的宿舍楼信息?';
}
await proxy?.$modal.confirm(confirmMsg).finally(() => (loading.value = false));
await delDormBuilding(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'sslxx/dormBuilding/export',
{
...queryParams.value
},
`dormBuilding_${new Date().getTime()}.xlsx`
);
};
onMounted(() => {
getList();
loadCampusOptions().then(() => {
loadAreaTreeData();
});
});
</script>
<style scoped>
/* 页面容器样式 */
.page-container {
padding: 8px;
}
/* 表格卡片布局 */
.table-card {
margin-top: 0;
}
.table-card :deep(.el-card__body) {
padding: 0px 20px 20px 20px !important;
}
/* 移除按钮栏底部边框 */
.button-card :deep(.el-card__header) {
border-bottom: none !important;
}
.image-gallery {
display: flex;
flex-wrap: wrap;
gap: 12px;
padding: 8px;
}
.image-item {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #dcdfe6;
border-radius: 6px;
background-color: #fff;
padding: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.image-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
.no-image {
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 80px;
border: 1px dashed #dcdfe6;
border-radius: 4px;
background-color: #fafafa;
}
.no-image-text {
color: #909399;
font-size: 12px;
text-align: center;
}
.table-no-image {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
border: 1px dashed #dcdfe6;
border-radius: 4px;
background-color: #fafafa;
margin: 0 auto;
}
.table-no-image-text {
color: #909399;
font-size: 10px;
text-align: center;
}
.view-text {
font-size: 14px;
color: #303133;
line-height: 1.5;
}
.view-description {
padding: 12px;
border: 1px solid #e4e7ed;
border-radius: 4px;
width: 100%;
height: 200px;
font-size: 14px;
color: #303133;
line-height: 1.6;
white-space: pre-wrap;
word-break: break-word;
overflow-y: auto;
}
/* 搜索按钮容器样式 */
.search-btn-container {
display: flex;
justify-content: flex-end;
margin-top: 10px;
.el-form-item {
margin-bottom: 0 !important;
}
}
</style>
+392
View File
@@ -0,0 +1,392 @@
<template>
<div class="p-2 page-container">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="宿舍区编码" prop="areaCode">
<el-input v-model="queryParams.areaCode" placeholder="请输入宿舍区编码" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="宿舍区名称" prop="areaName">
<el-input v-model="queryParams.areaName" placeholder="请输入宿舍区名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<!-- <el-col :span="6">
<el-form-item label="宿舍区描述" prop="areaDescription">
<el-input v-model="queryParams.areaDescription" placeholder="请输入宿舍区描述" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col> -->
</el-row>
<el-row>
<el-col :span="24" class="search-btn-container">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['ssqxx:dormArea:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['ssqxx:dormArea:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['ssqxx:dormArea:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['ssqxx:dormArea:export']">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="dormAreaList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="id" v-if="true" />
<el-table-column label="宿舍区编码" align="center" prop="areaCode" label-width="100px" />
<el-table-column label="宿舍区名称" align="center" prop="areaName" label-width="100px" />
<el-table-column label="所属校区ID" align="center" prop="campusId" label-width="100px" />
<el-table-column label="所属校区" align="center" prop="campusName" label-width="100px" />
<el-table-column label="宿舍区描述" align="center" prop="areaDescription" />
<el-table-column label="排序号" align="center" prop="sortOrder" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['ssqxx:dormArea:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['ssqxx:dormArea:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改宿舍区信息对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="dormAreaFormRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="所属校区" prop="campusId">
<el-select v-model="form.campusId" placeholder="请选择所属校区" filterable clearable>
<el-option v-for="item in campusOptions" :key="item.id" :label="item.campusName" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="宿舍区编码" prop="areaCode">
<el-input v-model="form.areaCode" placeholder="请输入宿舍区编码" />
</el-form-item>
<el-form-item label="宿舍区名称" prop="areaName">
<el-input v-model="form.areaName" placeholder="请输入宿舍区名称" />
</el-form-item>
<el-form-item label="宿舍区描述" prop="areaDescription">
<el-input v-model="form.areaDescription" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="form.sortOrder" placeholder="请输入排序号" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="DormArea" lang="ts">
import { listDormArea, getDormArea, delDormArea, addDormArea, updateDormArea } from '@/api/ssqxx/dormArea';
import { DormAreaVO, DormAreaQuery, DormAreaForm } from '@/api/ssqxx/dormArea/types';
import { listDormCampus } from '@/api/xqxx/dormCampus';
import type { DormCampusVO } from '@/api/xqxx/dormCampus/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const dormAreaList = ref<DormAreaVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const dormAreaFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const campusOptions = ref<DormCampusVO[]>([]);
const initFormData: DormAreaForm = {
id: undefined,
areaCode: undefined,
areaName: undefined,
campusId: undefined,
areaDescription: undefined,
sortOrder: undefined
};
const data = reactive<PageData<DormAreaForm, DormAreaQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
areaCode: undefined,
areaName: undefined,
areaDescription: undefined,
params: {}
},
rules: {
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
areaCode: [{ required: true, message: '宿舍区编码不能为空', trigger: 'blur' }],
areaName: [{ required: true, message: '宿舍区名称不能为空', trigger: 'blur' }],
campusId: [{ required: true, message: '所属校区ID不能为空', trigger: 'change' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询宿舍区信息列表 */
const getList = async () => {
loading.value = true;
const res = await listDormArea(queryParams.value);
dormAreaList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
dormAreaFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: DormAreaVO[]) => {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = async () => {
reset();
await loadCampusOptions();
dialog.visible = true;
dialog.title = '添加宿舍区信息';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: DormAreaVO) => {
reset();
await loadCampusOptions();
const _id = row?.id || ids.value[0];
const res = await getDormArea(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改宿舍区信息';
};
/** 提交按钮 */
const submitForm = () => {
dormAreaFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateDormArea(form.value).finally(() => (buttonLoading.value = false));
} else {
await addDormArea(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: DormAreaVO) => {
const _ids = row?.id || ids.value;
let confirmMsg = '';
if (row) {
confirmMsg = `是否确认删除宿舍区信息编号为"${row?.areaName}"的数据项?`;
} else if (Array.isArray(ids.value) && ids.value.length > 1) {
confirmMsg = `是否确认删除选中的${ids.value.length}个宿舍区信息?`;
} else {
confirmMsg = '是否确认删除选中的宿舍区信息?';
}
await proxy?.$modal.confirm(confirmMsg).finally(() => (loading.value = false));
await delDormArea(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'ssqxx/dormArea/export',
{
...queryParams.value
},
`dormArea_${new Date().getTime()}.xlsx`
);
};
const loadCampusOptions = async () => {
const res = await listDormCampus();
// 兼容分页和非分页返回
campusOptions.value = Array.isArray(res) ? res : res.rows || [];
};
onMounted(() => {
getList();
});
</script>
<style scoped>
/* 页面容器样式 */
.page-container {
padding: 8px;
}
/* 表格卡片布局 */
.table-card {
margin-top: 0;
}
.table-card :deep(.el-card__body) {
padding: 0px 20px 20px 20px !important;
}
/* 移除按钮栏底部边框 */
.button-card :deep(.el-card__header) {
border-bottom: none !important;
}
.image-gallery {
display: flex;
flex-wrap: wrap;
gap: 12px;
padding: 8px;
}
.image-item {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #dcdfe6;
border-radius: 6px;
background-color: #fff;
padding: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.image-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
.no-image {
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 80px;
border: 1px dashed #dcdfe6;
border-radius: 4px;
background-color: #fafafa;
}
.no-image-text {
color: #909399;
font-size: 12px;
text-align: center;
}
.table-no-image {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
border: 1px dashed #dcdfe6;
border-radius: 4px;
background-color: #fafafa;
margin: 0 auto;
}
.table-no-image-text {
color: #909399;
font-size: 10px;
text-align: center;
}
.view-text {
font-size: 14px;
color: #303133;
line-height: 1.5;
}
.view-description {
padding: 12px;
border: 1px solid #e4e7ed;
border-radius: 4px;
width: 100%;
height: 200px;
font-size: 14px;
color: #303133;
line-height: 1.6;
white-space: pre-wrap;
word-break: break-word;
overflow-y: auto;
}
/* 搜索按钮容器样式 */
.search-btn-container {
display: flex;
justify-content: flex-end;
margin-top: 10px;
.el-form-item {
margin-bottom: 0 !important;
}
}
</style>
+250
View File
@@ -0,0 +1,250 @@
<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="校区编码" prop="campusCode">
<el-input v-model="queryParams.campusCode" placeholder="请输入校区编码" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="校区名称" prop="campusName">
<el-input v-model="queryParams.campusName" placeholder="请输入校区名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['xqxx:dormCampus:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['xqxx:dormCampus:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['xqxx:dormCampus:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['xqxx:dormCampus:export']">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="dormCampusList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="id" v-if="true" />
<el-table-column label="校区编码" align="center" prop="campusCode" />
<el-table-column label="校区名称" align="center" prop="campusName" />
<el-table-column label="校区描述" align="center" prop="campusDescription" />
<el-table-column label="排序号" align="center" prop="sortOrder" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" plain icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['xqxx:dormCampus:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" plain icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['xqxx:dormCampus:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改校区信息对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="dormCampusFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="校区编码" prop="campusCode">
<el-input v-model="form.campusCode" placeholder="请输入校区编码" />
</el-form-item>
<el-form-item label="校区名称" prop="campusName">
<el-input v-model="form.campusName" placeholder="请输入校区名称" />
</el-form-item>
<el-form-item label="校区描述" prop="campusDescription">
<el-input v-model="form.campusDescription" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="form.sortOrder" placeholder="请输入排序号" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="DormCampus" lang="ts">
import { listDormCampus, getDormCampus, delDormCampus, addDormCampus, updateDormCampus } from '@/api/xqxx/dormCampus';
import { DormCampusVO, DormCampusQuery, DormCampusForm } from '@/api/xqxx/dormCampus/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const dormCampusList = ref<DormCampusVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const dormCampusFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: DormCampusForm = {
id: undefined,
campusCode: undefined,
campusName: undefined,
campusDescription: undefined,
sortOrder: undefined,
remark: undefined
};
const data = reactive<PageData<DormCampusForm, DormCampusQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
campusCode: undefined,
campusName: undefined,
params: {}
},
rules: {
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
campusCode: [{ required: true, message: '校区编码不能为空', trigger: 'blur' }],
campusName: [{ required: true, message: '校区名称不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询校区信息列表 */
const getList = async () => {
loading.value = true;
const res = await listDormCampus(queryParams.value);
dormCampusList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
dormCampusFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: DormCampusVO[]) => {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加校区信息';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: DormCampusVO) => {
reset();
const _id = row?.id || ids.value[0];
const res = await getDormCampus(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改校区信息';
};
/** 提交按钮 */
const submitForm = () => {
dormCampusFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateDormCampus(form.value).finally(() => (buttonLoading.value = false));
} else {
await addDormCampus(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: DormCampusVO) => {
const _ids = row?.id || ids.value;
let confirmMsg = '';
if (row) {
confirmMsg = `是否确认删除校区信息编号为"${row.campusName}"的数据项?`;
} else if (Array.isArray(ids.value) && ids.value.length > 1) {
confirmMsg = `是否确认删除选中的${ids.value.length}个校区信息?`;
} else {
confirmMsg = '是否确认删除选中的校区信息?';
}
await proxy?.$modal.confirm(confirmMsg).finally(() => (loading.value = false));
await delDormCampus(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'xqxx/dormCampus/export',
{
...queryParams.value
},
`dormCampus_${new Date().getTime()}.xlsx`
);
};
onMounted(() => {
getList();
});
</script>
@@ -0,0 +1,355 @@
<template>
<el-dialog :title="getDialogTitle()" v-model="dialogVisible" width="500px" append-to-body>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="姓名" prop="name">
<template v-if="mode === 'edit'">
<el-input v-model="form.name" disabled class="w-full" />
</template>
<template v-else>
<el-select
v-model="form.name"
filterable
remote
reserve-keyword
placeholder="请输入姓名"
:remote-method="queryTeachers"
:loading="loading"
clearable
class="w-full"
@change="handleTeacherSelect"
@focus="handleFocus"
>
<el-option v-for="item in teacherOptions" :key="item.value" :label="item.label" :value="item.value" :data-info="item" />
</el-select>
</template>
</el-form-item>
<el-form-item label="手机号码" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号码" clearable />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="form.sex">
<el-radio :label="0">男</el-radio>
<el-radio :label="1">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="dialogVisible = false">取 消</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, watch, onMounted } from 'vue';
import { getTeacherList } from '@/api/xsssgly/dormManager';
import { addDormManager, updateDormManager } from '@/api/ssglyxx/dormManager/index';
import { ElMessage } from 'element-plus';
export default defineComponent({
name: 'AdminDialog',
props: {
modelValue: {
type: Boolean,
default: false
},
mode: {
type: String,
default: 'add'
},
admin: {
type: Object,
default: () => ({})
},
type: {
type: String,
default: 'school'
}
},
emits: ['update:modelValue', 'submit'],
setup(props, { emit }) {
const loading = ref(false);
const teacherOptions = ref<any[]>([]);
// 根据类型获取对话框标题
const getDialogTitle = () => {
const typeText =
{
'school': '全校',
'campus': '校区',
'area': '宿舍区',
'building': '宿舍楼'
}[props.type] || '';
return props.mode === 'add' ? `新增${typeText}管理员` : `编辑${typeText}管理员`;
};
// 对话框可见性
const dialogVisible = computed({
get: () => props.modelValue,
set: (val) => {
emit('update:modelValue', val);
}
});
const formRef = ref();
const form = reactive({
id: null,
name: '',
phone: '',
remark: '',
nickName: '',
sex: 0,
userId: null // 存储选中的用户ID
});
const rules = {
name: [{ required: true, message: '请选择姓名', trigger: 'change' }],
phone: [
{ required: true, message: '请输入手机号码', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
],
sex: [{ required: true, message: '请选择性别', trigger: 'change' }]
};
// 使用真实API查询教师用户
const queryTeachers = async (query: string) => {
loading.value = true;
try {
const res = await getTeacherList(
query,
(() => {
switch (props.type) {
case 'school':
return '1';
case 'campus':
return '2';
case 'area':
return '3';
case 'building':
return '4';
default:
return '1';
}
})()
);
if (res.code === 200 && res.data) {
teacherOptions.value = res.data.map((item: any) => {
return {
value: item.value,
label: item.label,
username: item.username,
nickName: item.label,
userId: item.value, // 直接使用API返回的value作为userId
phonenumber: item.phonenumber, // 保存手机号码
sex: item.sex // 保存性别
};
});
}
} catch (error) {
console.error('获取教师数据失败', error);
} finally {
loading.value = false;
}
};
// 监听admin属性变化,更新表单
watch(
() => props.admin,
(newVal) => {
if (newVal) {
Object.assign(form, newVal);
// 如果没有性别值,设置默认值0
if (form.sex === undefined) {
form.sex = 0;
} else {
// 确保性别值为数字类型
form.sex = Number(form.sex);
}
}
},
{ deep: true, immediate: true }
);
// 选择教师后处理逻辑
const handleTeacherSelect = (value: any) => {
const selectedTeacher = teacherOptions.value.find((item) => item.value === value);
if (selectedTeacher) {
form.userId = selectedTeacher.userId;
// 自动填充手机号码和性别
form.phone = selectedTeacher.phonenumber || '';
// 确保性别值为数字类型
form.sex = selectedTeacher.sex !== undefined ? Number(selectedTeacher.sex) : 0;
form.nickName = selectedTeacher.nickName;
form.name = selectedTeacher.label;
// form.id = selectedTeacher.userId;
form.remark = '';
console.log('选中教师信息:', selectedTeacher, '转换后性别值:', form.sex);
}
};
// 处理下拉框获得焦点事件
const handleFocus = async () => {
loading.value = true;
try {
const res = await getTeacherList(
'',
(() => {
switch (props.type) {
case 'school':
return '1';
case 'campus':
return '2';
case 'area':
return '3';
case 'building':
return '4';
default:
return '1';
}
})()
);
if (res.code === 200 && res.data) {
teacherOptions.value = res.data.map((item: any) => {
return {
value: item.value,
label: item.label,
username: item.username,
userId: item.value,
nickName: item.label,
phonenumber: item.phonenumber, // 保存手机号码
sex: item.sex // 保存性别
};
});
}
} catch (error) {
console.error('获取教师数据失败', error);
} finally {
loading.value = false;
}
};
// 页面加载时预加载一些教师数据
onMounted(async () => {
try {
const res = await getTeacherList(
'',
(() => {
switch (props.type) {
case 'school':
return '1';
case 'campus':
return '2';
case 'area':
return '3';
case 'building':
return '4';
default:
return '1';
}
})()
);
if (res.code === 200 && res.data) {
teacherOptions.value = res.data.map((item: any) => {
return {
value: item.value,
label: item.label,
username: item.username,
userId: item.value,
nickName: item.label,
phonenumber: item.phonenumber, // 保存手机号码
sex: item.sex // 保存性别
};
});
}
} catch (error) {
console.error('初始化教师数据失败', error);
}
});
// 提交表单
const submitForm = async () => {
formRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
// 字段映射
const payload: any = {
id: form.id,
managerName: form.nickName || form.name,
gender: String(form.sex),
userId: form.userId,
phone: form.phone,
remark: form.remark,
// 下面字段可根据props.type补充
managerType: (() => {
switch (props.type) {
case 'school':
return '1';
case 'campus':
return '2';
case 'area':
return '3';
case 'building':
return '4';
default:
return '1';
}
})(),
managerLevel: (() => {
switch (props.type) {
case 'school':
return 1;
case 'campus':
return 2;
case 'area':
return 3;
case 'building':
return 4;
default:
return 1;
}
})()
};
console.log(payload);
try {
if (props.mode === 'add') {
await addDormManager(payload);
ElMessage.success('新增成功');
} else if (props.mode === 'edit') {
await updateDormManager(payload);
ElMessage.success('修改成功');
}
emit('submit', { ...form }); // 通知父组件刷新
dialogVisible.value = false;
} catch (e) {
ElMessage.error(props.mode === 'add' ? '新增失败' : '修改失败');
}
});
};
return {
dialogVisible,
form,
formRef,
loading,
teacherOptions,
rules,
getDialogTitle,
queryTeachers,
handleTeacherSelect,
handleFocus,
submitForm
};
}
});
</script>
<style scoped>
.dialog-footer {
text-align: right;
}
</style>
@@ -0,0 +1,21 @@
<template>
<div>
<el-button type="primary" @click="$emit('add')" style="margin-bottom: 16px">新增管理员</el-button>
<el-table :data="data" border style="width: 100%">
<el-table-column prop="name" label="姓名" width="120" />
<el-table-column prop="phone" label="手机号" width="150" />
<el-table-column prop="remark" label="备注" />
<el-table-column v-if="showScope" prop="scope" label="数据范围" />
<el-table-column label="操作" width="220">
<template #default="{ row }">
<el-button v-if="showScope" size="small" @click="$emit('scope', row)">数据范围</el-button>
<el-button size="small" @click="$emit('edit', row)">修改</el-button>
<el-button size="small" type="danger" @click="$emit('delete', row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup lang="ts">
defineProps<{ data: any[]; showScope?: boolean }>();
</script>
@@ -0,0 +1,153 @@
<template>
<el-dialog title="分配管理范围" v-model="dialogVisible" width="500px" append-to-body>
<el-form ref="formRef" :model="form" label-width="100px">
<el-form-item label="管理员姓名">
<span>{{ admin?.name }}</span>
</el-form-item>
<el-form-item label="管理范围" prop="scope">
<el-select
v-model="form.scope"
placeholder="请选择管理范围"
style="width: 100%"
clearable
filterable
:multiple="isCampusType"
collapse-tags
collapse-tags-tooltip
>
<el-option v-for="item in scopeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="dialogVisible = false">取 消</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, watch, onMounted } from 'vue';
import { listDormCampus } from '@/api/xqxx/dormCampus';
export default defineComponent({
name: 'ScopeDialog',
props: {
modelValue: {
type: Boolean,
default: false
},
admin: {
type: Object,
default: () => ({})
},
type: {
type: String,
default: ''
}
},
emits: ['update:modelValue', 'submit'],
setup(props, { emit }) {
const dialogVisible = computed({
get: () => props.modelValue,
set: (val) => {
emit('update:modelValue', val);
}
});
// 判断是否为校区类型的计算属性
const isCampusType = computed(() => props.type === 'campus');
const formRef = ref();
const form = reactive({
scope: isCampusType.value ? [] : ''
});
// 选项数据
const scopeOptions = ref<any[]>([]);
// 根据类型加载选项
const loadScopeOptions = async () => {
if (isCampusType.value) {
// 调用API获取校区列表
const res = await listDormCampus();
// 适配el-select格式
console.log(res);
scopeOptions.value = (res.rows || []).map((item: any) => ({
value: item.id,
label: item.campusName
}));
// 校区支持多选,初始化为数组
form.scope = Array.isArray(form.scope) ? form.scope : [];
} else if (props.type === 'area') {
scopeOptions.value = [
{ value: '1号宿舍区', label: '1号宿舍区' },
{ value: '2号宿舍区', label: '2号宿舍区' },
{ value: '3号宿舍区', label: '3号宿舍区' }
];
// 非校区为单选,初始化为字符串
form.scope = Array.isArray(form.scope) ? '' : form.scope;
} else if (props.type === 'building') {
scopeOptions.value = [
{ value: '1号楼', label: '1号楼' },
{ value: '2号楼', label: '2号楼' },
{ value: '3号楼', label: '3号楼' },
{ value: '4号楼', label: '4号楼' }
];
// 非校区为单选,初始化为字符串
form.scope = Array.isArray(form.scope) ? '' : form.scope;
} else {
scopeOptions.value = [];
}
};
// 监听type变化,动态加载选项
watch(
() => props.type,
() => {
loadScopeOptions();
},
{ immediate: true }
);
watch(
() => props.admin,
(newVal) => {
if (newVal && newVal.scope) {
// 根据类型决定如何设置scope值
if (isCampusType.value) {
// 校区支持多选,确保scope是数组
form.scope = Array.isArray(newVal.scope) ? newVal.scope : [newVal.scope];
} else {
// 其他类型是单选
form.scope = newVal.scope;
}
}
},
{ deep: true, immediate: true }
);
const submitForm = () => {
emit('submit', form.scope);
dialogVisible.value = false;
};
return {
dialogVisible,
form,
formRef,
scopeOptions,
submitForm,
isCampusType
};
}
});
</script>
<style scoped>
.dialog-footer {
text-align: right;
}
</style>
+445
View File
@@ -0,0 +1,445 @@
<template>
<div class="p-2 page-container">
<el-card>
<el-tabs v-model="activeTab">
<el-tab-pane label="全校管理员" name="school">
<!-- 检索栏(全校管理员) -->
<div class="mb-[10px]">
<el-card shadow="hover">
<el-form :inline="true" :model="schoolSearchForm" class="search-form">
<el-form-item label="姓名">
<el-input v-model="schoolSearchForm.name" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('school')" />
</el-form-item>
<el-form-item label="手机号码">
<el-input v-model="schoolSearchForm.phone" placeholder="请输入手机号码" clearable @keyup.enter="handleSearch('school')" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleSearch('school')">搜索</el-button>
<el-button icon="Refresh" @click="handleReset('school')">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
<!-- 按钮+列表区域(参考校区信息管理) -->
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="onAdd('school')">新增管理员</el-button>
</el-col>
</el-row>
</template>
<el-table :data="filteredAdmins('school')" border>
<el-table-column prop="name" label="姓名" align="center" />
<el-table-column prop="phone" label="手机号码" align="center" />
<el-table-column prop="sex" label="性别" align="center">
<template #default="scope">
{{ scope.row.sex === 0 ? '男' : '女' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" align="center" />
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="编辑" placement="top">
<el-button link type="primary" plain icon="Edit" @click="onEdit('school', scope.row)" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" plain icon="Delete" @click="onDelete('school', scope.row)" />
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tab-pane>
<el-tab-pane label="校区管理员" name="campus">
<!-- 检索栏(校区管理员) -->
<div class="mb-[10px]">
<el-card shadow="hover">
<el-form :inline="true" :model="campusSearchForm" class="search-form">
<el-form-item label="姓名">
<el-input v-model="campusSearchForm.name" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('campus')" />
</el-form-item>
<el-form-item label="手机号码">
<el-input v-model="campusSearchForm.phone" placeholder="请输入手机号码" clearable @keyup.enter="handleSearch('campus')" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleSearch('campus')">搜索</el-button>
<el-button icon="Refresh" @click="handleReset('campus')">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="onAdd('campus')">新增管理员</el-button>
</el-col>
</el-row>
</template>
<el-table :data="filteredAdmins('campus')" border>
<el-table-column prop="name" label="姓名" align="center" />
<el-table-column prop="phone" label="手机号码" align="center" />
<el-table-column prop="sex" label="性别" align="center">
<template #default="scope">
{{ scope.row.sex === 0 ? '男' : '女' }}
</template>
</el-table-column>
<el-table-column prop="scope" label="校区" align="center" />
<el-table-column prop="remark" label="备注" align="center" />
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="编辑" placement="top">
<el-button link type="primary" plain icon="Edit" @click="onEdit('campus', scope.row)" />
</el-tooltip>
<el-tooltip content="分配范围" placement="top">
<el-button link type="warning" plain icon="Setting" @click="onScope('campus', scope.row)" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" plain icon="Delete" @click="onDelete('campus', scope.row)" />
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tab-pane>
<el-tab-pane label="宿舍区管理员" name="area">
<!-- 检索栏(宿舍区管理员) -->
<div class="mb-[10px]">
<el-card shadow="hover">
<el-form :inline="true" :model="areaSearchForm" class="search-form">
<el-form-item label="姓名">
<el-input v-model="areaSearchForm.name" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('area')" />
</el-form-item>
<el-form-item label="手机号码">
<el-input v-model="areaSearchForm.phone" placeholder="请输入手机号码" clearable @keyup.enter="handleSearch('area')" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleSearch('area')">搜索</el-button>
<el-button icon="Refresh" @click="handleReset('area')">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="onAdd('area')">新增管理员</el-button>
</el-col>
</el-row>
</template>
<el-table :data="filteredAdmins('area')" border>
<el-table-column prop="name" label="姓名" align="center" />
<el-table-column prop="phone" label="手机号码" align="center" />
<el-table-column prop="sex" label="性别" align="center">
<template #default="scope">
{{ scope.row.sex === 0 ? '男' : '女' }}
</template>
</el-table-column>
<el-table-column prop="scope" label="宿舍区" align="center" />
<el-table-column prop="remark" label="备注" align="center" />
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="编辑" placement="top">
<el-button link type="primary" plain icon="Edit" @click="onEdit('area', scope.row)" />
</el-tooltip>
<el-tooltip content="分配范围" placement="top">
<el-button link type="warning" plain icon="Setting" @click="onScope('area', scope.row)" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" plain icon="Delete" @click="onDelete('area', scope.row)" />
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tab-pane>
<el-tab-pane label="宿舍楼管理员" name="building">
<!-- 检索栏(宿舍楼管理员) -->
<div class="mb-[10px]">
<el-card shadow="hover">
<el-form :inline="true" :model="buildingSearchForm" class="search-form">
<el-form-item label="姓名">
<el-input v-model="buildingSearchForm.name" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('building')" />
</el-form-item>
<el-form-item label="手机号码">
<el-input v-model="buildingSearchForm.phone" placeholder="请输入手机号码" clearable @keyup.enter="handleSearch('building')" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleSearch('building')">搜索</el-button>
<el-button icon="Refresh" @click="handleReset('building')">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="onAdd('building')">新增管理员</el-button>
</el-col>
</el-row>
</template>
<el-table :data="filteredAdmins('building')" border>
<el-table-column prop="name" label="姓名" align="center" />
<el-table-column prop="phone" label="手机号码" align="center" />
<el-table-column prop="sex" label="性别" align="center">
<template #default="scope">
{{ scope.row.sex === 0 ? '男' : '女' }}
</template>
</el-table-column>
<el-table-column prop="scope" label="宿舍楼" align="center" />
<el-table-column prop="remark" label="备注" align="center" />
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="编辑" placement="top">
<el-button link type="primary" plain icon="Edit" @click="onEdit('building', scope.row)" />
</el-tooltip>
<el-tooltip content="分配范围" placement="top">
<el-button link type="warning" plain icon="Setting" @click="onScope('building', scope.row)" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" plain icon="Delete" @click="onDelete('building', scope.row)" />
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tab-pane>
</el-tabs>
<admin-dialog v-model="dialogVisible" :mode="dialogMode" :admin="currentAdmin" :type="activeTab" @submit="onDialogSubmit" />
<scope-dialog v-model="scopeDialogVisible" :admin="currentAdmin" :type="scopeType" @submit="onScopeSubmit" />
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import AdminDialog from './components/AdminDialog.vue';
import ScopeDialog from './components/ScopeDialog.vue';
import axios from 'axios';
import { listDormManager } from '@/api/ssglyxx/dormManager';
import { delDormManager } from '@/api/ssglyxx/dormManager';
import { ElMessage, ElMessageBox } from 'element-plus';
const activeTab = ref('school');
// 各tab独立检索表单
const schoolSearchForm = reactive({ name: '', phone: '' });
const campusSearchForm = reactive({ name: '', phone: '' });
const areaSearchForm = reactive({ name: '', phone: '' });
const buildingSearchForm = reactive({ name: '', phone: '' });
// 管理员数据
const schoolAdmins = ref([]);
const campusAdmins = ref([]);
const areaAdmins = ref([]);
const buildingAdmins = ref([]);
const dialogVisible = ref(false);
const dialogMode = ref<'add' | 'edit'>('add');
const currentAdmin = ref<any>(null);
const scopeDialogVisible = ref(false);
const scopeType = ref('');
// API请求方法
async function fetchAdmins(type: string) {
let managerType = 1;
switch (type) {
case 'school':
managerType = 1;
break;
case 'campus':
managerType = 2;
break;
case 'area':
managerType = 3;
break;
case 'building':
managerType = 4;
break;
}
// 检索条件
let form;
switch (type) {
case 'school':
form = schoolSearchForm;
break;
case 'campus':
form = campusSearchForm;
break;
case 'area':
form = areaSearchForm;
break;
case 'building':
form = buildingSearchForm;
break;
default:
form = schoolSearchForm;
}
const params: any = {
managerType: managerType,
managerName: form.name,
phone: form.phone
};
// 移除空参数
Object.keys(params).forEach((key) => {
if (params[key] === '' || params[key] === undefined) delete params[key];
});
// const res = await axios.get('/ssglyxx/dormManager/list', { params });
const res = await listDormManager(params);
// 兼容TableDataInfo和R结构
let data = [];
if (Array.isArray(res.data)) {
data = res.data;
} else if (res.rows) {
data = res?.rows;
}
// console.log(data);
const mappedData = data.map((item: any) => ({
id: item.id,
name: item.managerName, // 映射
phone: item.phone,
sex: typeof item.gender === 'number' ? item.gender : Number(item.gender), // gender转数字
remark: item.remark
// 其他字段按需添加
}));
// console.log(mappedData);
switch (type) {
case 'school':
schoolAdmins.value = mappedData;
break;
case 'campus':
campusAdmins.value = mappedData;
break;
case 'area':
areaAdmins.value = mappedData;
break;
case 'building':
buildingAdmins.value = mappedData;
break;
}
}
onMounted(() => {
fetchAdmins('school');
fetchAdmins('campus');
fetchAdmins('area');
fetchAdmins('building');
});
function onAdd(type: string) {
dialogMode.value = 'add';
currentAdmin.value = { id: null, name: '', phone: '', sex: 0, remark: '', scope: '' };
activeTab.value = type; // 确保当前标签页与点击的按钮一致
dialogVisible.value = true;
}
function onEdit(type: string, admin: any) {
console.log('onEdit=============');
console.log(admin);
dialogMode.value = 'edit';
currentAdmin.value = { ...admin };
activeTab.value = type; // 确保当前标签页与编辑的管理员类型一致
dialogVisible.value = true;
}
async function onDelete(type: string, admin: any) {
// 二次确认
ElMessageBox.confirm(`确定要删除管理员【${admin.name}】吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
try {
await delDormManager(admin.id);
ElMessage.success('删除成功');
fetchAdmins(type); // 删除后刷新
} catch (e) {
ElMessage.error('删除失败');
}
})
.catch(() => {
// 用户取消
});
}
function onScope(type: string, admin: any) {
currentAdmin.value = { ...admin };
scopeType.value = type;
scopeDialogVisible.value = true;
}
function onDialogSubmit(admin: any) {
// TODO: 新增/编辑时调用API,成功后刷新
const list = getListByType(activeTab.value);
if (dialogMode.value === 'add') {
admin.id = Date.now();
list.value.push(admin);
} else {
const idx = list.value.findIndex((a: any) => a.id === admin.id);
if (idx !== -1) list.value[idx] = { ...admin };
}
dialogVisible.value = false;
}
function onScopeSubmit(scope: string) {
// TODO: 分配范围时调用API,成功后刷新
const list = getListByType(scopeType.value);
const idx = list.value.findIndex((a: any) => a.id === currentAdmin.value.id);
if (idx !== -1) list.value[idx].scope = scope;
scopeDialogVisible.value = false;
}
function getListByType(type: string) {
switch (type) {
case 'school':
return schoolAdmins;
case 'campus':
return campusAdmins;
case 'area':
return areaAdmins;
case 'building':
return buildingAdmins;
default:
return schoolAdmins;
}
}
// 前端过滤(按tab区分检索表单)
function filteredAdmins(type: string) {
// 真实API已做过滤,这里直接返回
return getListByType(type).value;
}
function handleSearch(type: string) {
fetchAdmins(type);
}
function handleReset(type: string) {
switch (type) {
case 'school':
schoolSearchForm.name = '';
schoolSearchForm.phone = '';
break;
case 'campus':
campusSearchForm.name = '';
campusSearchForm.phone = '';
break;
case 'area':
areaSearchForm.name = '';
areaSearchForm.phone = '';
break;
case 'building':
buildingSearchForm.name = '';
buildingSearchForm.phone = '';
break;
}
fetchAdmins(type);
}
</script>
<style scoped>
.el-card {
/* min-height: 600px; */
padding: 8px !important;
}
.search-form {
display: flex;
flex-wrap: wrap;
align-items: center;
}
</style>