resolve: 解决合并冲突
No files matched your search
@@ -1,386 +1,105 @@
|
|||||||
# Cursor Rules - Web 前端开发规范
|
# Vue 3 + TypeScript 前端开发规范
|
||||||
|
|
||||||
## 适用范围
|
## 技术栈规范
|
||||||
|
- Vue 3.5.13
|
||||||
|
- TypeScript 5.8.3
|
||||||
|
- Element Plus UI
|
||||||
|
- Art Design Pro UI 设计规范
|
||||||
|
|
||||||
- **项目目录**: `web/` (基于 Vue 3 + TypeScript + Element Plus)
|
## 表格组件开发规范
|
||||||
- **开发环境**: Node.js 20.15.x+, npm 10.7.x+
|
|
||||||
- **前端访问**: http://localhost (默认 80 端口)
|
|
||||||
|
|
||||||
---
|
### 1. 表格行双击查看功能(强制性)
|
||||||
|
|
||||||
# Web 前端开发规范 (web/)
|
#### 实现要求
|
||||||
|
- **✅ 必须实现**: 所有数据表格必须支持行双击查看详情功能
|
||||||
|
- **🎯 目标**: 提升用户体验,快速查看数据详情
|
||||||
|
|
||||||
## 1. 技术栈规范
|
#### 标准实现方式
|
||||||
|
|
||||||
### 核心技术
|
|
||||||
|
|
||||||
- **框架**: Vue 3.5.13 + TypeScript 5.8.3
|
|
||||||
- **UI 组件库**: Element Plus 2.9.8
|
|
||||||
- **构建工具**: Vite 6.3.2
|
|
||||||
- **状态管理**: Pinia 3.0.2
|
|
||||||
- **路由管理**: Vue Router 4.5.0
|
|
||||||
- **HTTP 客户端**: Axios 1.8.4
|
|
||||||
- **代码风格**: ESLint 9.21.0 + Prettier 3.5.2
|
|
||||||
- **样式预处理**: SCSS (Sass 1.87.0)
|
|
||||||
- **原子化 CSS**: UnoCSS 66.0.0
|
|
||||||
- **Node.js**: 20.15.x+ (推荐 20.15.0)
|
|
||||||
- **npm**: 10.7.x+
|
|
||||||
|
|
||||||
### 环境要求
|
|
||||||
|
|
||||||
- **开发环境**: 支持本地环境或阿里云测试环境
|
|
||||||
- **数据库**: MySQL/Redis 支持本机安装或使用阿里云环境
|
|
||||||
- **前端访问**: http://localhost (默认 80 端口)
|
|
||||||
- **后端服务**: http://localhost:8080
|
|
||||||
|
|
||||||
## 🔴 前端模块管理规范(强制性,2025-01-23新增)
|
|
||||||
|
|
||||||
### 📦 前端模块文件夹规范
|
|
||||||
|
|
||||||
**⚠️ 基于后端模块工程统一规划,前端必须建立对应的模块文件夹结构!**
|
|
||||||
|
|
||||||
#### 🏗️ 模块命名和位置规范
|
|
||||||
|
|
||||||
**界面文件夹位置**: `web/src/views/{模块简称}/`
|
|
||||||
**API文件夹位置**: `web/src/api/{模块简称}/`
|
|
||||||
|
|
||||||
**已规划模块列表**:
|
|
||||||
- ✅ `hq` - 后勤管理模块 (已完成)
|
|
||||||
- ✅ `rs` - 人事管理模块
|
|
||||||
- ✅ `cw` - 财务管理模块
|
|
||||||
- ✅ `aqbw` - 安全保卫管理模块
|
|
||||||
- ✅ `zsjy` - 招生就业管理模块
|
|
||||||
- ✅ `xg` - 学工管理模块
|
|
||||||
|
|
||||||
#### 📁 标准目录结构
|
|
||||||
|
|
||||||
**界面文件夹结构** (web/src/views/{模块简称}/):
|
|
||||||
```
|
|
||||||
web/src/views/{模块简称}/
|
|
||||||
├── README.md # 模块说明文档
|
|
||||||
├── {功能模块1}/ # 按功能模块细分
|
|
||||||
│ ├── index.vue # 列表页面
|
|
||||||
│ ├── add.vue # 新增页面
|
|
||||||
│ ├── edit.vue # 编辑页面
|
|
||||||
│ └── detail.vue # 详情页面
|
|
||||||
├── {功能模块2}/
|
|
||||||
│ └── ...
|
|
||||||
└── components/ # 模块内公共组件
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
**API文件夹结构** (web/src/api/{模块简称}/):
|
|
||||||
```
|
|
||||||
web/src/api/{模块简称}/
|
|
||||||
├── index.ts # API入口文件
|
|
||||||
├── README.md # API接口说明文档
|
|
||||||
├── types.ts # 类型定义文件
|
|
||||||
├── {功能模块1}/ # 按功能模块细分
|
|
||||||
│ └── index.ts # 功能模块API接口
|
|
||||||
├── {功能模块2}/
|
|
||||||
│ └── index.ts
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 🎯 文件命名规范
|
|
||||||
|
|
||||||
**Vue组件文件**:
|
|
||||||
- 页面组件: PascalCase (如: `UserList.vue`)
|
|
||||||
- 组件文件: kebab-case (如: `user-form.vue`)
|
|
||||||
|
|
||||||
**TypeScript文件**:
|
|
||||||
- API文件: kebab-case (如: `user-api.ts`)
|
|
||||||
- 类型文件: kebab-case (如: `user-types.ts`)
|
|
||||||
|
|
||||||
**路由命名**:
|
|
||||||
- 路由路径: kebab-case (如: `/rs/employee-list`)
|
|
||||||
- 路由名称: camelCase (如: `rsEmployeeList`)
|
|
||||||
|
|
||||||
#### 🔐 权限命名规范
|
|
||||||
|
|
||||||
**前端权限指令格式**: `v-hasPermi="'{模块简称}:{功能}:{操作}'"`
|
|
||||||
|
|
||||||
**示例**:
|
|
||||||
```vue
|
```vue
|
||||||
<!-- 人事模块员工新增权限 -->
|
<!-- 表格组件 -->
|
||||||
<el-button v-hasPermi="'rs:employee:add'" type="primary">新增员工</el-button>
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="dataList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@row-dblclick="handleView">
|
||||||
|
<!-- 表格列配置 -->
|
||||||
|
</el-table>
|
||||||
|
|
||||||
<!-- 财务模块预算查看权限 -->
|
<!-- 查看详情对话框 -->
|
||||||
<el-button v-hasPermi="'cw:budget:view'" type="primary">查看预算</el-button>
|
<el-dialog
|
||||||
|
:title="viewDialog.title"
|
||||||
<!-- 学工模块学生编辑权限 -->
|
v-model="viewDialog.visible"
|
||||||
<el-button v-hasPermi="'xg:student:edit'" link type="primary">编辑</el-button>
|
width="800px"
|
||||||
|
append-to-body>
|
||||||
|
<!-- 详情表单内容 -->
|
||||||
|
</el-dialog>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 📋 路由配置规范
|
#### 标准事件处理
|
||||||
|
|
||||||
**路由路径格式**: `/{模块简称}/{功能模块}`
|
|
||||||
|
|
||||||
**router配置示例**:
|
|
||||||
```typescript
|
```typescript
|
||||||
// router/modules/rs.ts - 人事管理模块路由
|
/** 查看按钮操作 */
|
||||||
export default {
|
const handleView = async (row: any) => {
|
||||||
path: '/rs',
|
// 1. 复制数据到查看表单
|
||||||
name: 'Rs',
|
Object.assign(viewForm, row);
|
||||||
component: () => import('@/layout/index.vue'),
|
|
||||||
redirect: '/rs/employee',
|
// 2. 处理特殊字段(如图片列表等)
|
||||||
meta: {
|
if (row.images) {
|
||||||
title: '人事管理',
|
viewImageList.value = row.images.split(',').filter((img: string) => img.trim() !== '');
|
||||||
icon: 'peoples',
|
|
||||||
rank: 3
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/rs/employee',
|
|
||||||
name: 'RsEmployee',
|
|
||||||
component: () => import('@/views/rs/employee/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '员工管理',
|
|
||||||
keepAlive: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/rs/department',
|
|
||||||
name: 'RsDepartment',
|
|
||||||
component: () => import('@/views/rs/department/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '部门管理',
|
|
||||||
keepAlive: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. 显示对话框
|
||||||
|
viewDialog.visible = true;
|
||||||
|
viewDialog.title = '查看详情';
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 🚨 前端模块开发检查清单
|
#### 最佳实践建议
|
||||||
|
1. 查看对话框宽度建议 800px-1000px,根据内容自适应
|
||||||
|
2. 详情展示采用只读表单形式,提供良好的数据展示结构
|
||||||
|
3. 对于图片、文件等特殊字段,需要合适的预览组件
|
||||||
|
4. 长文本内容建议使用滚动容器限制高度
|
||||||
|
5. 必要时可以在详情页面添加相关操作按钮
|
||||||
|
|
||||||
**创建新模块前必须检查**:
|
### 2. 表格长文本显示规范(强制性)
|
||||||
- [ ] 模块文件夹是否按规范命名?(`web/src/views/{简称}/`)
|
|
||||||
- [ ] API文件夹是否对应创建?(`web/src/api/{简称}/`)
|
|
||||||
- [ ] 是否创建了模块说明文档?(README.md)
|
|
||||||
- [ ] 路由配置是否符合规范?
|
|
||||||
- [ ] 权限指令是否使用正确的编码格式?
|
|
||||||
- [ ] 是否遵循前端开发规范和UI设计标准?
|
|
||||||
- [ ] 组件和文件命名是否符合规范?
|
|
||||||
- [ ] API接口类型定义是否与后端VO保持一致?
|
|
||||||
|
|
||||||
#### 💡 模块开发最佳实践
|
#### 实现要求
|
||||||
|
- **✅ 必须实现**: 所有表格中的长文本字段必须限制显示行数
|
||||||
**1. 组件复用**:
|
- **🎯 目标**: 保持表格整洁美观,同时提供完整内容的查看方式
|
||||||
- 模块内公共组件放在`components/`目录
|
|
||||||
- 跨模块公共组件放在`@/components/`目录
|
|
||||||
- 使用组合式API提高代码复用性
|
|
||||||
|
|
||||||
**2. 状态管理**:
|
|
||||||
- 模块相关状态使用Pinia store管理
|
|
||||||
- Store文件命名:`@/stores/{模块简称}.ts`
|
|
||||||
- 避免不同模块间的状态耦合
|
|
||||||
|
|
||||||
**3. 样式管理**:
|
|
||||||
- 使用SCSS变量和mixin提高样式复用
|
|
||||||
- 遵循Art Design Pro UI设计规范
|
|
||||||
- 统一使用轮廓式按钮设计
|
|
||||||
|
|
||||||
**4. 类型安全**:
|
|
||||||
- 所有API接口必须定义TypeScript类型
|
|
||||||
- 类型定义与后端VO对象保持一致
|
|
||||||
- 使用泛型提高类型复用性
|
|
||||||
|
|
||||||
#### 📝 注意事项
|
|
||||||
|
|
||||||
**模块间解耦**:
|
|
||||||
- 避免模块间直接依赖,通过事件总线或状态管理通信
|
|
||||||
- API接口按模块严格分离
|
|
||||||
- 路由按模块独立配置,避免交叉引用
|
|
||||||
|
|
||||||
**性能优化**:
|
|
||||||
- 页面组件使用懒加载
|
|
||||||
- 合理使用keep-alive缓存页面状态
|
|
||||||
- 图片资源优化和懒加载
|
|
||||||
|
|
||||||
**用户体验**:
|
|
||||||
- 统一的加载状态和错误处理
|
|
||||||
- 合理的页面过渡动画
|
|
||||||
- 响应式设计支持多设备访问
|
|
||||||
|
|
||||||
## 2. Art Design Pro UI 规范
|
|
||||||
|
|
||||||
### 设计理念
|
|
||||||
|
|
||||||
基于 Art Design Pro 的设计语言,追求现代化、精致、用户友好的界面体验。注重细节、动效和用户交互的流畅性。
|
|
||||||
|
|
||||||
### 颜色系统 🎨
|
|
||||||
|
|
||||||
#### 主色调 (Primary Colors) - 2025 年最新版本
|
|
||||||
|
|
||||||
```css
|
|
||||||
/* 亮色主题 */
|
|
||||||
:root {
|
|
||||||
--art-primary: 93, 135, 255; /* 主品牌色 - 亮蓝色 #5d87ff */
|
|
||||||
--art-secondary: 73, 190, 255; /* 辅助色 - 天蓝色 #49beff */
|
|
||||||
--art-success: 0, 167, 58; /* 成功色 - 绿色 #00a73a */
|
|
||||||
--art-warning: 142, 91, 0; /* 警告色 - 橙色 #8e5b00 */
|
|
||||||
--art-error: 250, 137, 107; /* 错误色 - 红色 #fa896b */
|
|
||||||
--art-info: 0, 75, 178; /* 信息色 - 蓝色 #004bb2 */
|
|
||||||
--art-danger: 255, 77, 79; /* 危险色 - 红色 #ff4d4f */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 暗色主题 */
|
|
||||||
html.dark {
|
|
||||||
--art-primary: 93, 135, 255; /* 主品牌色 - 亮蓝色 #5d87ff */
|
|
||||||
--art-secondary: 73, 190, 255; /* 辅助色 - 天蓝色 #49beff */
|
|
||||||
--art-success: 19, 222, 185; /* 成功色 - 绿色 #13deb9 */
|
|
||||||
--art-warning: 255, 174, 31; /* 警告色 - 橙色 #ffae1f */
|
|
||||||
--art-error: 250, 137, 107; /* 错误色 - 红色 #fa896b */
|
|
||||||
--art-info: 83, 155, 255; /* 信息色 - 蓝色 #539bff */
|
|
||||||
--art-danger: 255, 77, 79; /* 危险色 - 红色 #ff4d4f */
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 背景色系统
|
|
||||||
|
|
||||||
```css
|
|
||||||
/* 浅色主题 */
|
|
||||||
:root {
|
|
||||||
--art-bg-color: #fafbfc; /* 页面底色 */
|
|
||||||
--art-main-bg-color: #ffffff; /* 主要内容背景 */
|
|
||||||
--art-bg-primary: 236, 242, 255; /* 主色背景 */
|
|
||||||
--art-bg-secondary: 232, 247, 255; /* 辅助背景 */
|
|
||||||
--art-bg-success: 230, 255, 250; /* 成功背景 */
|
|
||||||
--art-bg-warning: 254, 245, 229; /* 警告背景 */
|
|
||||||
--art-bg-error: 253, 237, 232; /* 错误背景 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 暗色主题 */
|
|
||||||
html.dark {
|
|
||||||
--art-bg-color: #070707; /* 页面底色 */
|
|
||||||
--art-main-bg-color: #161618; /* 主要内容背景 */
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 灰色系统
|
|
||||||
|
|
||||||
```css
|
|
||||||
:root {
|
|
||||||
--art-gray-100: #f9f9f9; /* 浅灰 */
|
|
||||||
--art-gray-200: #f1f1f4; /* 较浅灰 */
|
|
||||||
--art-gray-300: #dbdfe9; /* 中浅灰 */
|
|
||||||
--art-gray-400: #c4cada; /* 中灰 */
|
|
||||||
--art-gray-500: #99a1b7; /* 中深灰 */
|
|
||||||
--art-gray-600: #78829d; /* 深灰 */
|
|
||||||
--art-gray-700: #4b5675; /* 较深灰 */
|
|
||||||
--art-gray-800: #252f4a; /* 很深灰 */
|
|
||||||
--art-gray-900: #071437; /* 最深灰 */
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 轮廓式按钮设计系统 🔘
|
|
||||||
|
|
||||||
#### 🎨 设计理念
|
|
||||||
|
|
||||||
全面采用轮廓式(Outline)按钮设计,提供更加优雅、现代和一致的用户界面体验。
|
|
||||||
|
|
||||||
#### 核心规范
|
|
||||||
|
|
||||||
- **Primary 按钮**: 轮廓式主色设计,主色边框和文字,5%透明度主色背景
|
|
||||||
- **Success 按钮**: 轮廓式成功色设计,成功色边框和文字,5%透明度成功色背景
|
|
||||||
- **Warning 按钮**: 轮廓式警告色设计,警告色边框和文字,5%透明度警告色背景
|
|
||||||
- **Danger 按钮**: 轮廓式危险色设计,危险色边框和文字,5%透明度危险色背景
|
|
||||||
- **Info 按钮**: 轮廓式信息色设计,信息色边框和文字,5%透明度信息色背景
|
|
||||||
- **Default 按钮**: 白色背景,灰色边框,灰色文字
|
|
||||||
|
|
||||||
#### 交互效果
|
|
||||||
|
|
||||||
- **悬浮状态**: 上移 1px + 背景透明度变为 10% + 边框透明度变为 80% + 彩色阴影
|
|
||||||
- **点击状态**: 98%缩放 + 0.1s 快速过渡 + 背景透明度变为 15%
|
|
||||||
- **禁用状态**: 50%透明度,禁用所有交互和变换
|
|
||||||
|
|
||||||
### 🔘 列表页面按钮使用规范(2025 年最新标准)
|
|
||||||
|
|
||||||
#### 工具栏按钮规范
|
|
||||||
|
|
||||||
|
#### 标准实现方式
|
||||||
```vue
|
```vue
|
||||||
<!-- 标准工具栏按钮配置 -->
|
<!-- 表格长文本列配置 -->
|
||||||
<template #header>
|
<el-table-column label="描述文本" align="center" prop="description">
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<!-- ✅ 第一个新增按钮:必须使用 type="primary" -->
|
|
||||||
<el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<!-- ✅ 其他按钮:不添加type,使用默认样式 -->
|
|
||||||
<el-button icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button icon="Download" @click="handleExport">导出</el-button>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 操作列按钮规范
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<!-- 表格操作列按钮配置 -->
|
|
||||||
<el-table-column label="操作" align="center" width="160">
|
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip content="修改" placement="top">
|
<div class="description-cell">{{ scope.row.description }}</div>
|
||||||
<!-- ✅ 操作列按钮:统一使用 link type="primary" -->
|
|
||||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="删除" placement="top">
|
|
||||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 按钮使用规范总结
|
#### 标准样式定义
|
||||||
|
|
||||||
| 位置 | 按钮类型 | 样式规范 | 示例 |
|
|
||||||
| -------------------- | ---------------- | ---------------------- | -------------------------------------------------------------- |
|
|
||||||
| 工具栏第一个新增按钮 | 新增 | `type="primary" plain` | `<el-button type="primary" plain icon="Plus">新增</el-button>` |
|
|
||||||
| 工具栏其他按钮 | 修改/删除/导出等 | 无 type(默认) | `<el-button icon="Edit">修改</el-button>` |
|
|
||||||
| 表格操作列 | 所有操作按钮 | `link type="primary"` | `<el-button link type="primary" icon="Edit"></el-button>` |
|
|
||||||
| 弹窗底部 | 确认按钮 | `type="primary"` | `<el-button type="primary">确定</el-button>` |
|
|
||||||
| 弹窗底部 | 取消按钮 | 无 type(默认) | `<el-button>取消</el-button>` |
|
|
||||||
|
|
||||||
### 圆角系统
|
|
||||||
|
|
||||||
```css
|
```css
|
||||||
:root {
|
/* 长文本单元格样式 */
|
||||||
--border-radius-xs: 4px; /* 超小元素 (checkbox等) */
|
.description-cell {
|
||||||
--border-radius-sm: 6px; /* 小元素 (下拉选项、关闭按钮等) */
|
display: -webkit-box;
|
||||||
--border-radius-md: 8px; /* 表单控件 (input、select、button等) */
|
-webkit-box-orient: vertical;
|
||||||
--border-radius-lg: 12px; /* 容器组件 (card、table、dialog等) */
|
-webkit-line-clamp: 3; /* 显示3行 */
|
||||||
--border-radius-xl: 12px;
|
overflow: hidden;
|
||||||
--border-radius-2xl: 16px;
|
text-overflow: ellipsis;
|
||||||
--border-radius-full: 50%;
|
line-height: 1.5;
|
||||||
|
max-height: 4.5em; /* 3行 * 1.5行高 */
|
||||||
|
text-align: left;
|
||||||
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 间距系统
|
#### 最佳实践建议
|
||||||
|
1. 统一使用3行显示限制,超出显示省略号
|
||||||
|
2. 使用左对齐方式,提高长文本可读性
|
||||||
|
3. 设置合适的行高和内边距
|
||||||
|
4. 配合表格行双击查看功能,在详情弹窗中显示完整内容
|
||||||
|
5. 必要时可以添加鼠标悬停提示(el-tooltip)显示完整内容
|
||||||
|
|
||||||
```css
|
### 3. 组件开发标准和页面模板
|
||||||
:root {
|
|
||||||
--space-xs: 4px;
|
|
||||||
--space-sm: 8px;
|
|
||||||
--space-md: 12px;
|
|
||||||
--space-lg: 16px;
|
|
||||||
--space-xl: 20px;
|
|
||||||
--space-2xl: 24px;
|
|
||||||
--space-3xl: 32px;
|
|
||||||
--space-4xl: 48px;
|
|
||||||
--space-5xl: 64px;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. 组件开发规范
|
|
||||||
|
|
||||||
### Vue 组件结构标准
|
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
@@ -425,8 +144,6 @@ onMounted(() => {
|
|||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 页面开发规范
|
|
||||||
|
|
||||||
#### 列表页面标准模板
|
#### 列表页面标准模板
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
@@ -604,9 +321,7 @@ const resetForm = () => {
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. API 开发规范
|
### 3. API接口定义和状态管理
|
||||||
|
|
||||||
### API 接口定义标准
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// api/[module]/index.ts
|
// api/[module]/index.ts
|
||||||
@@ -816,7 +531,89 @@ const moduleRouter: RouteRecordRaw = {
|
|||||||
export default moduleRouter;
|
export default moduleRouter;
|
||||||
```
|
```
|
||||||
|
|
||||||
## 7. 项目架构规范
|
## 7. 搜索表单布局规范(强制性)
|
||||||
|
|
||||||
|
### 7.1 设计目标
|
||||||
|
|
||||||
|
1. **一致性**:所有列表页面的检索栏保持统一外观和交互。
|
||||||
|
2. **响应式**:在 1920/1440/1280 等常用分辨率下均能保持整洁布局。
|
||||||
|
3. **易维护**:通过统一的栅格 + 样式类,后续页面可快速复用。
|
||||||
|
|
||||||
|
### 7.2 栅格布局
|
||||||
|
|
||||||
|
1. 采用 Element Plus `el-row` / `el-col` 栅格系统。
|
||||||
|
2. **每行固定 4 个检索元素**,每项 `:span="6"`(24 ÷ 4)。
|
||||||
|
3. 若检索项不足 4 个,也应保持占位对齐,避免按钮漂移。
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||||
|
<!-- 第一行 -->
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="字段1" prop="field1">
|
||||||
|
<el-input v-model="queryParams.field1" placeholder="请输入字段1" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="字段2" prop="field2">
|
||||||
|
<el-input v-model="queryParams.field2" placeholder="请输入字段2" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<!-- 其余两列同理 -->
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 更多行按需添加,仍保持 4 列规则 -->
|
||||||
|
|
||||||
|
<!-- 操作按钮行 -->
|
||||||
|
<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>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.3 按钮固定右侧
|
||||||
|
|
||||||
|
1. 统一在搜索表单尾部添加按钮行。
|
||||||
|
2. 使用 `.search-btn-container` 类,将按钮通过 Flex **右对齐**。
|
||||||
|
|
||||||
|
```scss
|
||||||
|
/* 搜索按钮容器样式(全局复用,可写在组件 scoped 内部)*/
|
||||||
|
.search-btn-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 0 !important; // 清除默认 margin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.4 应用示例
|
||||||
|
|
||||||
|
所有新页面或改造页面 **必须** 遵循以上规范。例如:
|
||||||
|
|
||||||
|
* `hq/pm/repairOrder/index.vue`
|
||||||
|
* `hq/pm/repairCategory/index.vue`
|
||||||
|
* `hq/hallAudit/index.vue`
|
||||||
|
* `hq/hallInfo/index.vue`
|
||||||
|
* `hq/hallReservation/index.vue`
|
||||||
|
|
||||||
|
### 7.5 代码检查要点
|
||||||
|
|
||||||
|
1. 检查是否存在 `:inline="true"`,如有应移除。
|
||||||
|
2. 确认每行 4 列,使用 `span=6`。
|
||||||
|
3. 搜索/重置按钮是否放置在 `.search-btn-container` 内。
|
||||||
|
4. scoped 样式内是否包含上述 `.search-btn-container` 定义。
|
||||||
|
|
||||||
|
遵循此规范,可显著提升列表页检索区域的统一性与用户体验。
|
||||||
|
|
||||||
|
## 8. 项目架构规范
|
||||||
|
|
||||||
### 目录结构
|
### 目录结构
|
||||||
|
|
||||||
@@ -853,7 +650,7 @@ web/src/
|
|||||||
- **工具文件**: camelCase,如 `formatUtils.ts`
|
- **工具文件**: camelCase,如 `formatUtils.ts`
|
||||||
- **类型文件**: PascalCase,如 `UserTypes.ts`
|
- **类型文件**: PascalCase,如 `UserTypes.ts`
|
||||||
|
|
||||||
## 8. 样式开发规范
|
## 9. 样式开发规范
|
||||||
|
|
||||||
### SCSS 变量使用
|
### SCSS 变量使用
|
||||||
|
|
||||||
@@ -890,7 +687,7 @@ web/src/
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
## 9. 性能优化规范
|
## 10. 性能优化规范
|
||||||
|
|
||||||
### 组件懒加载
|
### 组件懒加载
|
||||||
|
|
||||||
@@ -911,7 +708,7 @@ const AsyncComponent = defineAsyncComponent(() => import('@/components/HeavyComp
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
## 10. 开发最佳实践
|
## 11. 开发最佳实践
|
||||||
|
|
||||||
### 代码规范
|
### 代码规范
|
||||||
|
|
||||||
@@ -952,7 +749,7 @@ interface UserForm {
|
|||||||
const user = data as UserForm;
|
const user = data as UserForm;
|
||||||
```
|
```
|
||||||
|
|
||||||
## 11. 测试规范
|
## 12. 测试规范
|
||||||
|
|
||||||
### 单元测试
|
### 单元测试
|
||||||
|
|
||||||
@@ -970,7 +767,7 @@ describe('UserForm', () => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## 12. 构建与部署
|
## 13. 构建与部署
|
||||||
|
|
||||||
### 环境配置
|
### 环境配置
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import org.dromara.common.excel.utils.ExcelUtil;
|
|||||||
import org.dromara.hq.domain.vo.HqHallReservationVo;
|
import org.dromara.hq.domain.vo.HqHallReservationVo;
|
||||||
import org.dromara.hq.domain.bo.HqHallReservationBo;
|
import org.dromara.hq.domain.bo.HqHallReservationBo;
|
||||||
import org.dromara.hq.domain.bo.HqHallReservationAuditBo;
|
import org.dromara.hq.domain.bo.HqHallReservationAuditBo;
|
||||||
|
import org.dromara.hq.domain.bo.HqHallTimeCheckBo;
|
||||||
|
import org.dromara.hq.domain.vo.HqHallTimeCheckVo;
|
||||||
import org.dromara.hq.service.IHqHallReservationService;
|
import org.dromara.hq.service.IHqHallReservationService;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
|
||||||
@@ -112,4 +114,14 @@ public class HqHallReservationController extends BaseController {
|
|||||||
public R<Void> audit(@RequestBody HqHallReservationAuditBo auditBo) {
|
public R<Void> audit(@RequestBody HqHallReservationAuditBo auditBo) {
|
||||||
return toAjax(hqHallReservationService.auditByIds(auditBo));
|
return toAjax(hqHallReservationService.auditByIds(auditBo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查报告厅时间冲突
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("hq:hallReservation:query")
|
||||||
|
@PostMapping("/checkTimeConflict")
|
||||||
|
public R<HqHallTimeCheckVo> checkTimeConflict(@Validated @RequestBody HqHallTimeCheckBo timeCheckBo) {
|
||||||
|
HqHallTimeCheckVo result = hqHallReservationService.checkTimeConflict(timeCheckBo);
|
||||||
|
return R.ok(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -15,9 +15,9 @@ import org.dromara.common.log.enums.BusinessType;
|
|||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.hq.domain.bo.PmRepairAttachmentBo;
|
import org.dromara.hq.domain.bo.HqPmRepairAttachmentBo;
|
||||||
import org.dromara.hq.domain.vo.PmRepairAttachmentVo;
|
import org.dromara.hq.domain.vo.HqPmRepairAttachmentVo;
|
||||||
import org.dromara.hq.service.IPmRepairAttachmentService;
|
import org.dromara.hq.service.IHqPmRepairAttachmentService;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -35,16 +35,16 @@ import java.util.List;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/hq/pm/attachment")
|
@RequestMapping("/hq/pm/attachment")
|
||||||
public class PmRepairAttachmentController extends BaseController {
|
public class HqPmRepairAttachmentController extends BaseController {
|
||||||
|
|
||||||
private final IPmRepairAttachmentService attachmentService;
|
private final IHqPmRepairAttachmentService attachmentService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报修附件列表
|
* 查询报修附件列表
|
||||||
*/
|
*/
|
||||||
// @SaCheckPermission("pm:attachment:list")
|
// @SaCheckPermission("pm:attachment:list")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<PmRepairAttachmentVo> list(PmRepairAttachmentBo bo, PageQuery pageQuery) {
|
public TableDataInfo<HqPmRepairAttachmentVo> list(HqPmRepairAttachmentBo bo, PageQuery pageQuery) {
|
||||||
return attachmentService.queryPageList(bo, pageQuery);
|
return attachmentService.queryPageList(bo, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
// @SaCheckPermission("pm:attachment:list")
|
// @SaCheckPermission("pm:attachment:list")
|
||||||
@GetMapping("/order/{orderId}")
|
@GetMapping("/order/{orderId}")
|
||||||
public R<List<PmRepairAttachmentVo>> getByOrderId(@PathVariable("orderId") Long orderId) {
|
public R<List<HqPmRepairAttachmentVo>> getByOrderId(@PathVariable("orderId") Long orderId) {
|
||||||
List<PmRepairAttachmentVo> list = attachmentService.queryByOrderId(orderId);
|
List<HqPmRepairAttachmentVo> list = attachmentService.queryByOrderId(orderId);
|
||||||
return R.ok(list);
|
return R.ok(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
// @SaCheckPermission("pm:attachment:query")
|
// @SaCheckPermission("pm:attachment:query")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public R<PmRepairAttachmentVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
public R<HqPmRepairAttachmentVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||||
return R.ok(attachmentService.queryById(id));
|
return R.ok(attachmentService.queryById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
@Log(title = "报修附件", businessType = BusinessType.INSERT)
|
@Log(title = "报修附件", businessType = BusinessType.INSERT)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody PmRepairAttachmentBo bo) {
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody HqPmRepairAttachmentBo bo) {
|
||||||
return toAjax(attachmentService.insertByBo(bo));
|
return toAjax(attachmentService.insertByBo(bo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
@Log(title = "报修附件", businessType = BusinessType.UPDATE)
|
@Log(title = "报修附件", businessType = BusinessType.UPDATE)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PmRepairAttachmentBo bo) {
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HqPmRepairAttachmentBo bo) {
|
||||||
return toAjax(attachmentService.updateByBo(bo));
|
return toAjax(attachmentService.updateByBo(bo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
// @SaCheckPermission("pm:attachment:upload")
|
// @SaCheckPermission("pm:attachment:upload")
|
||||||
@Log(title = "上传报修附件", businessType = BusinessType.INSERT)
|
@Log(title = "上传报修附件", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/upload")
|
@PostMapping("/upload")
|
||||||
public R<PmRepairAttachmentVo> uploadFile(
|
public R<HqPmRepairAttachmentVo> uploadFile(
|
||||||
@RequestParam("orderId") Long orderId,
|
@RequestParam("orderId") Long orderId,
|
||||||
@RequestParam(value = "uploadStage", defaultValue = "1") String uploadStage,
|
@RequestParam(value = "uploadStage", defaultValue = "1") String uploadStage,
|
||||||
@RequestParam("file") MultipartFile file,
|
@RequestParam("file") MultipartFile file,
|
||||||
@@ -117,7 +117,7 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PmRepairAttachmentVo result = attachmentService.uploadFile(orderId, uploadStage, file, description);
|
HqPmRepairAttachmentVo result = attachmentService.uploadFile(orderId, uploadStage, file, description);
|
||||||
return R.ok(result);
|
return R.ok(result);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return R.fail("上传失败: " + e.getMessage());
|
return R.fail("上传失败: " + e.getMessage());
|
||||||
@@ -130,7 +130,7 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
// @SaCheckPermission("pm:attachment:upload")
|
// @SaCheckPermission("pm:attachment:upload")
|
||||||
@Log(title = "批量上传报修附件", businessType = BusinessType.INSERT)
|
@Log(title = "批量上传报修附件", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/upload/batch")
|
@PostMapping("/upload/batch")
|
||||||
public R<List<PmRepairAttachmentVo>> uploadFiles(
|
public R<List<HqPmRepairAttachmentVo>> uploadFiles(
|
||||||
@RequestParam("orderId") Long orderId,
|
@RequestParam("orderId") Long orderId,
|
||||||
@RequestParam(value = "uploadStage", defaultValue = "1") String uploadStage,
|
@RequestParam(value = "uploadStage", defaultValue = "1") String uploadStage,
|
||||||
@RequestParam("files") MultipartFile[] files,
|
@RequestParam("files") MultipartFile[] files,
|
||||||
@@ -141,7 +141,7 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<PmRepairAttachmentVo> results = attachmentService.uploadFiles(orderId, uploadStage, files,
|
List<HqPmRepairAttachmentVo> results = attachmentService.uploadFiles(orderId, uploadStage, files,
|
||||||
descriptions);
|
descriptions);
|
||||||
return R.ok(results);
|
return R.ok(results);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -165,7 +165,7 @@ public class PmRepairAttachmentController extends BaseController {
|
|||||||
// @SaCheckPermission("pm:attachment:download")
|
// @SaCheckPermission("pm:attachment:download")
|
||||||
@GetMapping("/download/{id}")
|
@GetMapping("/download/{id}")
|
||||||
public void downloadFile(@PathVariable("id") Long id, HttpServletResponse response) {
|
public void downloadFile(@PathVariable("id") Long id, HttpServletResponse response) {
|
||||||
PmRepairAttachmentVo attachment = attachmentService.queryById(id);
|
HqPmRepairAttachmentVo attachment = attachmentService.queryById(id);
|
||||||
if (attachment == null) {
|
if (attachment == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -17,9 +17,9 @@ import org.dromara.common.core.validate.AddGroup;
|
|||||||
import org.dromara.common.core.validate.EditGroup;
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
import org.dromara.common.log.enums.BusinessType;
|
import org.dromara.common.log.enums.BusinessType;
|
||||||
import org.dromara.common.excel.utils.ExcelUtil;
|
import org.dromara.common.excel.utils.ExcelUtil;
|
||||||
import org.dromara.hq.domain.vo.PmRepairCategoryVo;
|
import org.dromara.hq.domain.vo.HqPmRepairCategoryVo;
|
||||||
import org.dromara.hq.domain.bo.PmRepairCategoryBo;
|
import org.dromara.hq.domain.bo.HqPmRepairCategoryBo;
|
||||||
import org.dromara.hq.service.IPmRepairCategoryService;
|
import org.dromara.hq.service.IHqPmRepairCategoryService;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,16 +32,16 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/hq/pm/repairCategory")
|
@RequestMapping("/hq/pm/repairCategory")
|
||||||
public class PmRepairCategoryController extends BaseController {
|
public class HqPmRepairCategoryController extends BaseController {
|
||||||
|
|
||||||
private final IPmRepairCategoryService repairCategoryService;
|
private final IHqPmRepairCategoryService repairCategoryService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询维修类型列表
|
* 查询维修类型列表
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("pm:category:list")
|
@SaCheckPermission("pm:category:list")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<PmRepairCategoryVo> list(PmRepairCategoryBo bo, PageQuery pageQuery) {
|
public TableDataInfo<HqPmRepairCategoryVo> list(HqPmRepairCategoryBo bo, PageQuery pageQuery) {
|
||||||
return repairCategoryService.queryPageList(bo, pageQuery);
|
return repairCategoryService.queryPageList(bo, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,9 +51,9 @@ public class PmRepairCategoryController extends BaseController {
|
|||||||
@SaCheckPermission("pm:category:export")
|
@SaCheckPermission("pm:category:export")
|
||||||
@Log(title = "维修类型", businessType = BusinessType.EXPORT)
|
@Log(title = "维修类型", businessType = BusinessType.EXPORT)
|
||||||
@PostMapping("/export")
|
@PostMapping("/export")
|
||||||
public void export(PmRepairCategoryBo bo, HttpServletResponse response) {
|
public void export(HqPmRepairCategoryBo bo, HttpServletResponse response) {
|
||||||
List<PmRepairCategoryVo> list = repairCategoryService.queryList(bo);
|
List<HqPmRepairCategoryVo> list = repairCategoryService.queryList(bo);
|
||||||
ExcelUtil.exportExcel(list, "维修类型", PmRepairCategoryVo.class, response);
|
ExcelUtil.exportExcel(list, "维修类型", HqPmRepairCategoryVo.class, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,7 +61,7 @@ public class PmRepairCategoryController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@SaCheckPermission("pm:category:query")
|
@SaCheckPermission("pm:category:query")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public R<PmRepairCategoryVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
public R<HqPmRepairCategoryVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||||
return R.ok(repairCategoryService.queryById(id));
|
return R.ok(repairCategoryService.queryById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ public class PmRepairCategoryController extends BaseController {
|
|||||||
@Log(title = "维修类型", businessType = BusinessType.INSERT)
|
@Log(title = "维修类型", businessType = BusinessType.INSERT)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PostMapping()
|
@PostMapping()
|
||||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody PmRepairCategoryBo bo) {
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody HqPmRepairCategoryBo bo) {
|
||||||
return toAjax(repairCategoryService.insertByBo(bo));
|
return toAjax(repairCategoryService.insertByBo(bo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ public class PmRepairCategoryController extends BaseController {
|
|||||||
@Log(title = "维修类型", businessType = BusinessType.UPDATE)
|
@Log(title = "维修类型", businessType = BusinessType.UPDATE)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PutMapping()
|
@PutMapping()
|
||||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PmRepairCategoryBo bo) {
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HqPmRepairCategoryBo bo) {
|
||||||
return toAjax(repairCategoryService.updateByBo(bo));
|
return toAjax(repairCategoryService.updateByBo(bo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ public class PmRepairCategoryController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@SaCheckPermission("pm:category:tree")
|
@SaCheckPermission("pm:category:tree")
|
||||||
@GetMapping("/tree")
|
@GetMapping("/tree")
|
||||||
public R<List<PmRepairCategoryVo>> tree() {
|
public R<List<HqPmRepairCategoryVo>> tree() {
|
||||||
return R.ok(repairCategoryService.queryTree());
|
return R.ok(repairCategoryService.queryTree());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ public class PmRepairCategoryController extends BaseController {
|
|||||||
@SaCheckPermission("pm:category:options")
|
@SaCheckPermission("pm:category:options")
|
||||||
@GetMapping("/options")
|
@GetMapping("/options")
|
||||||
public R<List<java.util.Map<String, Object>>> options() {
|
public R<List<java.util.Map<String, Object>>> options() {
|
||||||
List<PmRepairCategoryVo> list = repairCategoryService.queryTree();
|
List<HqPmRepairCategoryVo> list = repairCategoryService.queryTree();
|
||||||
List<java.util.Map<String, Object>> options = buildCategoryOptions(list);
|
List<java.util.Map<String, Object>> options = buildCategoryOptions(list);
|
||||||
return R.ok(options);
|
return R.ok(options);
|
||||||
}
|
}
|
||||||
@@ -120,9 +120,9 @@ public class PmRepairCategoryController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 构建维修类型下拉选项
|
* 构建维修类型下拉选项
|
||||||
*/
|
*/
|
||||||
private List<java.util.Map<String, Object>> buildCategoryOptions(List<PmRepairCategoryVo> list) {
|
private List<java.util.Map<String, Object>> buildCategoryOptions(List<HqPmRepairCategoryVo> list) {
|
||||||
List<java.util.Map<String, Object>> result = new java.util.ArrayList<>();
|
List<java.util.Map<String, Object>> result = new java.util.ArrayList<>();
|
||||||
for (PmRepairCategoryVo item : list) {
|
for (HqPmRepairCategoryVo item : list) {
|
||||||
java.util.Map<String, Object> option = new java.util.HashMap<>();
|
java.util.Map<String, Object> option = new java.util.HashMap<>();
|
||||||
option.put("value", item.getId());
|
option.put("value", item.getId());
|
||||||
option.put("label", item.getCategoryName());
|
option.put("label", item.getCategoryName());
|
||||||
@@ -17,11 +17,11 @@ import org.dromara.common.core.validate.AddGroup;
|
|||||||
import org.dromara.common.core.validate.EditGroup;
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
import org.dromara.common.log.enums.BusinessType;
|
import org.dromara.common.log.enums.BusinessType;
|
||||||
import org.dromara.common.excel.utils.ExcelUtil;
|
import org.dromara.common.excel.utils.ExcelUtil;
|
||||||
import org.dromara.hq.domain.vo.PmRepairOrderVo;
|
import org.dromara.hq.domain.vo.HqPmRepairOrderVo;
|
||||||
import org.dromara.hq.domain.bo.PmRepairOrderBo;
|
import org.dromara.hq.domain.bo.HqPmRepairOrderBo;
|
||||||
import org.dromara.hq.domain.vo.PmRepairAttachmentVo;
|
import org.dromara.hq.domain.vo.HqPmRepairAttachmentVo;
|
||||||
import org.dromara.hq.service.IPmRepairOrderService;
|
import org.dromara.hq.service.IHqPmRepairOrderService;
|
||||||
import org.dromara.hq.service.IPmRepairAttachmentService;
|
import org.dromara.hq.service.IHqPmRepairAttachmentService;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,18 +34,18 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/hq/pm/repairOrder")
|
@RequestMapping("/hq/pm/repairOrder")
|
||||||
public class PmRepairOrderController extends BaseController {
|
public class HqPmRepairOrderController extends BaseController {
|
||||||
|
|
||||||
private final IPmRepairOrderService repairOrderService;
|
private final IHqPmRepairOrderService repairOrderService;
|
||||||
private final IPmRepairAttachmentService attachmentService;
|
private final IHqPmRepairAttachmentService attachmentService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报修工单列表
|
* 查询报修工单列表
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("pm:repairOrder:list")
|
@SaCheckPermission("pm:repairOrder:list")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<PmRepairOrderVo> list(PmRepairOrderBo bo, PageQuery pageQuery) {
|
public TableDataInfo<HqPmRepairOrderVo> list(HqPmRepairOrderBo bo, PageQuery pageQuery) {
|
||||||
TableDataInfo<PmRepairOrderVo> result = repairOrderService.queryPageList(bo, pageQuery);
|
TableDataInfo<HqPmRepairOrderVo> result = repairOrderService.queryPageList(bo, pageQuery);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,9 +55,9 @@ public class PmRepairOrderController extends BaseController {
|
|||||||
@SaCheckPermission("pm:repairOrder:export")
|
@SaCheckPermission("pm:repairOrder:export")
|
||||||
@Log(title = "报修工单", businessType = BusinessType.EXPORT)
|
@Log(title = "报修工单", businessType = BusinessType.EXPORT)
|
||||||
@PostMapping("/export")
|
@PostMapping("/export")
|
||||||
public void export(PmRepairOrderBo bo, HttpServletResponse response) {
|
public void export(HqPmRepairOrderBo bo, HttpServletResponse response) {
|
||||||
List<PmRepairOrderVo> list = repairOrderService.queryList(bo);
|
List<HqPmRepairOrderVo> list = repairOrderService.queryList(bo);
|
||||||
ExcelUtil.exportExcel(list, "报修工单", PmRepairOrderVo.class, response);
|
ExcelUtil.exportExcel(list, "报修工单", HqPmRepairOrderVo.class, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,7 +65,7 @@ public class PmRepairOrderController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@SaCheckPermission("pm:repairOrder:query")
|
@SaCheckPermission("pm:repairOrder:query")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public R<PmRepairOrderVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
public R<HqPmRepairOrderVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||||
return R.ok(repairOrderService.queryById(id));
|
return R.ok(repairOrderService.queryById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ public class PmRepairOrderController extends BaseController {
|
|||||||
@Log(title = "报修工单", businessType = BusinessType.INSERT)
|
@Log(title = "报修工单", businessType = BusinessType.INSERT)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PostMapping()
|
@PostMapping()
|
||||||
public R<Long> add(@Validated(AddGroup.class) @RequestBody PmRepairOrderBo bo) {
|
public R<Long> add(@Validated(AddGroup.class) @RequestBody HqPmRepairOrderBo bo) {
|
||||||
boolean success = repairOrderService.insertByBo(bo);
|
boolean success = repairOrderService.insertByBo(bo);
|
||||||
if (success) {
|
if (success) {
|
||||||
// 返回创建的工单ID,供前端上传附件使用
|
// 返回创建的工单ID,供前端上传附件使用
|
||||||
@@ -93,7 +93,7 @@ public class PmRepairOrderController extends BaseController {
|
|||||||
@Log(title = "报修工单", businessType = BusinessType.UPDATE)
|
@Log(title = "报修工单", businessType = BusinessType.UPDATE)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PutMapping()
|
@PutMapping()
|
||||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PmRepairOrderBo bo) {
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HqPmRepairOrderBo bo) {
|
||||||
return toAjax(repairOrderService.updateByBo(bo));
|
return toAjax(repairOrderService.updateByBo(bo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,9 +323,9 @@ public class PmRepairOrderController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@SaCheckPermission("pm:repairOrder:query")
|
@SaCheckPermission("pm:repairOrder:query")
|
||||||
@GetMapping("/{orderId}/attachments")
|
@GetMapping("/{orderId}/attachments")
|
||||||
public R<List<PmRepairAttachmentVo>> getRepairAttachments(
|
public R<List<HqPmRepairAttachmentVo>> getRepairAttachments(
|
||||||
@NotNull(message = "工单ID不能为空") @PathVariable Long orderId) {
|
@NotNull(message = "工单ID不能为空") @PathVariable Long orderId) {
|
||||||
List<PmRepairAttachmentVo> attachments = attachmentService.queryByOrderId(orderId);
|
List<HqPmRepairAttachmentVo> attachments = attachmentService.queryByOrderId(orderId);
|
||||||
return R.ok(attachments);
|
return R.ok(attachments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10,15 +10,15 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
|||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修附件对象 pm_repair_attachment
|
* 报修附件对象 hq_pm_repair_attachment
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("pm_repair_attachment")
|
@TableName("hq_pm_repair_attachment")
|
||||||
public class PmRepairAttachment extends TenantEntity {
|
public class HqPmRepairAttachment extends TenantEntity {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -30,7 +30,7 @@ public class PmRepairAttachment extends TenantEntity {
|
|||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修工单ID,关联pm_repair_order.id
|
* 报修工单ID,关联hq_pm_repair_order.id
|
||||||
*/
|
*/
|
||||||
private Long orderId;
|
private Long orderId;
|
||||||
|
|
||||||
@@ -11,15 +11,15 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
|||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 维修类型对象 pm_repair_category
|
* 维修类型对象 hq_pm_repair_category
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("pm_repair_category")
|
@TableName("hq_pm_repair_category")
|
||||||
public class PmRepairCategory extends TenantEntity {
|
public class HqPmRepairCategory extends TenantEntity {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -11,15 +11,15 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
|||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修工单对象 pm_repair_order
|
* 报修工单对象 hq_pm_repair_order
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("pm_repair_order")
|
@TableName("hq_pm_repair_order")
|
||||||
public class PmRepairOrder extends TenantEntity {
|
public class HqPmRepairOrder extends TenantEntity {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -51,7 +51,7 @@ public class PmRepairOrder extends TenantEntity {
|
|||||||
private String repairLocation;
|
private String repairLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 维修类型ID,关联pm_repair_category.id
|
* 维修类型ID,关联hq_pm_repair_category.id
|
||||||
*/
|
*/
|
||||||
private Long categoryId;
|
private Long categoryId;
|
||||||
|
|
||||||
@@ -18,8 +18,8 @@ import java.io.Serial;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("pm_repair_progress")
|
@TableName("hq_pm_repair_progress")
|
||||||
public class PmRepairProgress extends TenantEntity {
|
public class HqPmRepairProgress extends TenantEntity {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -31,7 +31,7 @@ public class PmRepairProgress extends TenantEntity {
|
|||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修工单ID,关联pm_repair_order.id
|
* 报修工单ID,关联hq_pm_repair_order.id
|
||||||
*/
|
*/
|
||||||
private Long orderId;
|
private Long orderId;
|
||||||
|
|
||||||
@@ -11,15 +11,15 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
|||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务评价对象 pm_service_evaluation
|
* 服务评价对象 hq_pm_service_evaluation
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("pm_service_evaluation")
|
@TableName("hq_pm_service_evaluation")
|
||||||
public class PmServiceEvaluation extends TenantEntity {
|
public class HqPmServiceEvaluation extends TenantEntity {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -31,7 +31,7 @@ public class PmServiceEvaluation extends TenantEntity {
|
|||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修工单ID,关联pm_repair_order.id
|
* 报修工单ID,关联hq_pm_repair_order.id
|
||||||
*/
|
*/
|
||||||
private Long orderId;
|
private Long orderId;
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.dromara.hq.domain.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import java.util.Date;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报告厅时间冲突检查业务对象
|
||||||
|
*
|
||||||
|
* @author wuzilong
|
||||||
|
* @date 2025-01-09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class HqHallTimeCheckBo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报告厅ID
|
||||||
|
*/
|
||||||
|
@NotNull(message = "报告厅ID不能为空")
|
||||||
|
private Long hallId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
@NotNull(message = "开始时间不能为空")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
@NotNull(message = "结束时间不能为空")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排除的预约ID(编辑时排除自己)
|
||||||
|
*/
|
||||||
|
private Long excludeId;
|
||||||
|
}
|
||||||
@@ -9,20 +9,20 @@ import lombok.EqualsAndHashCode;
|
|||||||
import org.dromara.common.core.validate.AddGroup;
|
import org.dromara.common.core.validate.AddGroup;
|
||||||
import org.dromara.common.core.validate.EditGroup;
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
import org.dromara.hq.domain.PmRepairAttachment;
|
import org.dromara.hq.domain.HqPmRepairAttachment;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修附件业务对象 pm_repair_attachment
|
* 报修附件业务对象 hq_pm_repair_attachment
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-26
|
* @date 2025-01-26
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@AutoMapper(target = PmRepairAttachment.class, reverseConvertGenerate = false)
|
@AutoMapper(target = HqPmRepairAttachment.class, reverseConvertGenerate = false)
|
||||||
public class PmRepairAttachmentBo extends BaseEntity {
|
public class HqPmRepairAttachmentBo extends BaseEntity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主键ID
|
* 主键ID
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.dromara.hq.domain.bo;
|
package org.dromara.hq.domain.bo;
|
||||||
|
|
||||||
import org.dromara.hq.domain.PmRepairCategory;
|
import org.dromara.hq.domain.HqPmRepairCategory;
|
||||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
import org.dromara.common.core.validate.AddGroup;
|
import org.dromara.common.core.validate.AddGroup;
|
||||||
import org.dromara.common.core.validate.EditGroup;
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
@@ -14,15 +14,15 @@ import java.util.List;
|
|||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 维修类型业务对象 pm_repair_category
|
* 维修类型业务对象 hq_pm_repair_category
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@AutoMapper(target = PmRepairCategory.class, reverseConvertGenerate = false)
|
@AutoMapper(target = HqPmRepairCategory.class, reverseConvertGenerate = false)
|
||||||
public class PmRepairCategoryBo extends BaseEntity {
|
public class HqPmRepairCategoryBo extends BaseEntity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主键ID
|
* 主键ID
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.dromara.hq.domain.bo;
|
package org.dromara.hq.domain.bo;
|
||||||
|
|
||||||
import org.dromara.hq.domain.PmRepairOrder;
|
import org.dromara.hq.domain.HqPmRepairOrder;
|
||||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
import org.dromara.common.core.validate.AddGroup;
|
import org.dromara.common.core.validate.AddGroup;
|
||||||
import org.dromara.common.core.validate.EditGroup;
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
@@ -14,15 +14,15 @@ import java.util.List;
|
|||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修工单业务对象 pm_repair_order
|
* 报修工单业务对象 hq_pm_repair_order
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@AutoMapper(target = PmRepairOrder.class, reverseConvertGenerate = false)
|
@AutoMapper(target = HqPmRepairOrder.class, reverseConvertGenerate = false)
|
||||||
public class PmRepairOrderBo extends BaseEntity {
|
public class HqPmRepairOrderBo extends BaseEntity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主键ID
|
* 主键ID
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package org.dromara.hq.domain.bo;
|
||||||
|
|
||||||
|
import org.dromara.hq.domain.HqPmRepairProgress;
|
||||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
|
import org.dromara.common.core.validate.AddGroup;
|
||||||
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import jakarta.validation.constraints.*;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 维修进度记录业务对象 hq_pm_repair_progress
|
||||||
|
*
|
||||||
|
* @author Cursor AI
|
||||||
|
* @date 2025-01-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@AutoMapper(target = HqPmRepairProgress.class, reverseConvertGenerate = false)
|
||||||
|
public class HqPmRepairProgressBo extends BaseEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报修工单ID,关联hq_pm_repair_order.id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "报修工单ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度类型:1-工单分派,2-接收确认,3-到达现场,4-开始维修,5-进度更新,6-完成维修,7-用户评价,8-工单归档,9-其他
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "进度类型不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String progressType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度状态描述
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "进度状态描述不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String progressStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度详细描述
|
||||||
|
*/
|
||||||
|
private String progressDetail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人ID,关联sys_user.id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "操作人ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人姓名
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "操作人姓名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String operatorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人角色:user-用户,admin-管理员,worker-维修员
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "操作人角色不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String operatorRole;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作位置信息
|
||||||
|
*/
|
||||||
|
private String locationInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPS纬度
|
||||||
|
*/
|
||||||
|
private BigDecimal gpsLatitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPS经度
|
||||||
|
*/
|
||||||
|
private BigDecimal gpsLongitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作时间
|
||||||
|
*/
|
||||||
|
@NotNull(message = "操作时间不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Date operationTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预计耗时(分钟)
|
||||||
|
*/
|
||||||
|
private Integer estimatedDuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联附件ID列表(逗号分隔)
|
||||||
|
*/
|
||||||
|
private String attachmentIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下一步计划
|
||||||
|
*/
|
||||||
|
private String nextStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 遇到的问题
|
||||||
|
*/
|
||||||
|
private String issuesEncountered;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要的材料
|
||||||
|
*/
|
||||||
|
private String materialsNeeded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注信息
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package org.dromara.hq.domain.bo;
|
||||||
|
|
||||||
|
import org.dromara.hq.domain.HqPmServiceEvaluation;
|
||||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
|
import org.dromara.common.core.validate.AddGroup;
|
||||||
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import jakarta.validation.constraints.*;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务评价业务对象 hq_pm_service_evaluation
|
||||||
|
*
|
||||||
|
* @author Cursor AI
|
||||||
|
* @date 2025-01-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@AutoMapper(target = HqPmServiceEvaluation.class, reverseConvertGenerate = false)
|
||||||
|
public class HqPmServiceEvaluationBo extends BaseEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报修工单ID,关联hq_pm_repair_order.id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "报修工单ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评价人ID,关联sys_user.id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "评价人ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Long evaluatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评价人姓名
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "评价人姓名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String evaluatorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 被评价维修员ID,关联sys_user.id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "被评价维修员ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Long evaluatedWorkerId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 被评价维修员姓名
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "被评价维修员姓名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String evaluatedWorkerName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 综合评价得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@NotNull(message = "综合评价得分不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
@DecimalMin(value = "1.0", message = "综合评价得分不能小于1.0")
|
||||||
|
@DecimalMax(value = "5.0", message = "综合评价得分不能大于5.0")
|
||||||
|
private BigDecimal overallScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 维修质量得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@DecimalMin(value = "1.0", message = "维修质量得分不能小于1.0")
|
||||||
|
@DecimalMax(value = "5.0", message = "维修质量得分不能大于5.0")
|
||||||
|
private BigDecimal qualityScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务态度得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@DecimalMin(value = "1.0", message = "服务态度得分不能小于1.0")
|
||||||
|
@DecimalMax(value = "5.0", message = "服务态度得分不能大于5.0")
|
||||||
|
private BigDecimal attitudeScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应速度得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@DecimalMin(value = "1.0", message = "响应速度得分不能小于1.0")
|
||||||
|
@DecimalMax(value = "5.0", message = "响应速度得分不能大于5.0")
|
||||||
|
private BigDecimal responseSpeedScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 沟通效果得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@DecimalMin(value = "1.0", message = "沟通效果得分不能小于1.0")
|
||||||
|
@DecimalMax(value = "5.0", message = "沟通效果得分不能大于5.0")
|
||||||
|
private BigDecimal communicationScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文字评价内容
|
||||||
|
*/
|
||||||
|
private String evaluationContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 满意度等级:1-非常满意,2-满意,3-一般,4-不满意,5-非常不满意
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "满意度等级不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String satisfactionLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否匿名评价(0-实名,1-匿名)
|
||||||
|
*/
|
||||||
|
private Integer isAnonymous;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否公开显示(0-不公开,1-公开)
|
||||||
|
*/
|
||||||
|
private Integer isPublic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评价时间
|
||||||
|
*/
|
||||||
|
@NotNull(message = "评价时间不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Date evaluationTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务开始时间
|
||||||
|
*/
|
||||||
|
private Date serviceStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务结束时间
|
||||||
|
*/
|
||||||
|
private Date serviceEndTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务时长(分钟)
|
||||||
|
*/
|
||||||
|
private Integer serviceDuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 正面标签(逗号分隔)
|
||||||
|
*/
|
||||||
|
private String positiveTags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 负面标签(逗号分隔)
|
||||||
|
*/
|
||||||
|
private String negativeTags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 改进建议
|
||||||
|
*/
|
||||||
|
private String improvementSuggestions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注信息
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -113,4 +113,29 @@ public class HqHallReservationVo implements Serializable {
|
|||||||
@ExcelProperty(value = "审核备注")
|
@ExcelProperty(value = "审核备注")
|
||||||
private String auditRemark;
|
private String auditRemark;
|
||||||
|
|
||||||
|
// ========== 基础字段(强制性,所有VO类必须包含) ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建者
|
||||||
|
*/
|
||||||
|
private Long createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@ExcelProperty(value = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新者
|
||||||
|
*/
|
||||||
|
private Long updateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package org.dromara.hq.domain.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报告厅时间冲突检查结果视图对象
|
||||||
|
*
|
||||||
|
* @author wuzilong
|
||||||
|
* @date 2025-01-09
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class HqHallTimeCheckVo implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否存在时间冲突
|
||||||
|
*/
|
||||||
|
private Boolean hasConflict;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 冲突的预约记录列表
|
||||||
|
*/
|
||||||
|
private List<HqHallReservationVo> conflictList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 冲突描述信息
|
||||||
|
*/
|
||||||
|
private String conflictMessage;
|
||||||
|
|
||||||
|
public HqHallTimeCheckVo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public HqHallTimeCheckVo(Boolean hasConflict, List<HqHallReservationVo> conflictList, String conflictMessage) {
|
||||||
|
this.hasConflict = hasConflict;
|
||||||
|
this.conflictList = conflictList;
|
||||||
|
this.conflictMessage = conflictMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建无冲突结果
|
||||||
|
*/
|
||||||
|
public static HqHallTimeCheckVo noConflict() {
|
||||||
|
return new HqHallTimeCheckVo(false, List.of(), "无时间冲突");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建有冲突结果
|
||||||
|
*/
|
||||||
|
public static HqHallTimeCheckVo hasConflict(List<HqHallReservationVo> conflictList, String message) {
|
||||||
|
return new HqHallTimeCheckVo(true, conflictList, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,22 +5,22 @@ import cn.idev.excel.annotation.ExcelProperty;
|
|||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.dromara.hq.domain.PmRepairAttachment;
|
import org.dromara.hq.domain.HqPmRepairAttachment;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修附件视图对象 pm_repair_attachment
|
* 报修附件视图对象 hq_pm_repair_attachment
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-26
|
* @date 2025-01-26
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
@AutoMapper(target = PmRepairAttachment.class)
|
@AutoMapper(target = HqPmRepairAttachment.class)
|
||||||
public class PmRepairAttachmentVo implements Serializable {
|
public class HqPmRepairAttachmentVo implements Serializable {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -4,7 +4,7 @@ import java.util.Date;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import org.dromara.hq.domain.PmRepairCategory;
|
import org.dromara.hq.domain.HqPmRepairCategory;
|
||||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import cn.idev.excel.annotation.ExcelProperty;
|
import cn.idev.excel.annotation.ExcelProperty;
|
||||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||||
@@ -16,15 +16,15 @@ import java.io.Serial;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 维修类型视图对象 pm_repair_category
|
* 维修类型视图对象 hq_pm_repair_category
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
@AutoMapper(target = PmRepairCategory.class)
|
@AutoMapper(target = HqPmRepairCategory.class)
|
||||||
public class PmRepairCategoryVo implements Serializable {
|
public class HqPmRepairCategoryVo implements Serializable {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -156,6 +156,6 @@ public class PmRepairCategoryVo implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 子分类列表(用于树形结构)
|
* 子分类列表(用于树形结构)
|
||||||
*/
|
*/
|
||||||
private List<PmRepairCategoryVo> children;
|
private List<HqPmRepairCategoryVo> children;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ package org.dromara.hq.domain.vo;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import org.dromara.hq.domain.PmRepairOrder;
|
import org.dromara.hq.domain.HqPmRepairOrder;
|
||||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import cn.idev.excel.annotation.ExcelProperty;
|
import cn.idev.excel.annotation.ExcelProperty;
|
||||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||||
@@ -15,15 +15,15 @@ import java.io.Serial;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报修工单视图对象 pm_repair_order
|
* 报修工单视图对象 hq_pm_repair_order
|
||||||
*
|
*
|
||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
@AutoMapper(target = PmRepairOrder.class)
|
@AutoMapper(target = HqPmRepairOrder.class)
|
||||||
public class PmRepairOrderVo implements Serializable {
|
public class HqPmRepairOrderVo implements Serializable {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package org.dromara.hq.domain.vo;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.dromara.hq.domain.HqPmRepairProgress;
|
||||||
|
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import cn.idev.excel.annotation.ExcelProperty;
|
||||||
|
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||||
|
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 维修进度记录视图对象 hq_pm_repair_progress
|
||||||
|
*
|
||||||
|
* @author Cursor AI
|
||||||
|
* @date 2025-01-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
@AutoMapper(target = HqPmRepairProgress.class)
|
||||||
|
public class HqPmRepairProgressVo implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "主键ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报修工单ID,关联hq_pm_repair_order.id
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "报修工单ID")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度类型:1-工单分派,2-接收确认,3-到达现场,4-开始维修,5-进度更新,6-完成维修,7-用户评价,8-工单归档,9-其他
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "进度类型", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(dictType = "pm_progress_type")
|
||||||
|
private String progressType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度状态描述
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "进度状态描述")
|
||||||
|
private String progressStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度详细描述
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "进度详细描述")
|
||||||
|
private String progressDetail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人ID,关联sys_user.id
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "操作人ID")
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人姓名
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "操作人姓名")
|
||||||
|
private String operatorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人角色:user-用户,admin-管理员,worker-维修员
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "操作人角色", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(dictType = "pm_operator_role")
|
||||||
|
private String operatorRole;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作位置信息
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "操作位置信息")
|
||||||
|
private String locationInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPS纬度
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "GPS纬度")
|
||||||
|
private BigDecimal gpsLatitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPS经度
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "GPS经度")
|
||||||
|
private BigDecimal gpsLongitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作时间
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "操作时间")
|
||||||
|
private Date operationTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预计耗时(分钟)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "预计耗时(分钟)")
|
||||||
|
private Integer estimatedDuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联附件ID列表(逗号分隔)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "关联附件ID列表")
|
||||||
|
private String attachmentIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下一步计划
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "下一步计划")
|
||||||
|
private String nextStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 遇到的问题
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "遇到的问题")
|
||||||
|
private String issuesEncountered;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要的材料
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "需要的材料")
|
||||||
|
private String materialsNeeded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注信息
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "备注信息")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 租户ID
|
||||||
|
*/
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建部门
|
||||||
|
*/
|
||||||
|
private Long createDept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建者
|
||||||
|
*/
|
||||||
|
private Long createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新者
|
||||||
|
*/
|
||||||
|
private Long updateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
package org.dromara.hq.domain.vo;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.dromara.hq.domain.HqPmServiceEvaluation;
|
||||||
|
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import cn.idev.excel.annotation.ExcelProperty;
|
||||||
|
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||||
|
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务评价视图对象 hq_pm_service_evaluation
|
||||||
|
*
|
||||||
|
* @author Cursor AI
|
||||||
|
* @date 2025-01-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
@AutoMapper(target = HqPmServiceEvaluation.class)
|
||||||
|
public class HqPmServiceEvaluationVo implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "主键ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报修工单ID,关联hq_pm_repair_order.id
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "报修工单ID")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评价人ID,关联sys_user.id
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "评价人ID")
|
||||||
|
private Long evaluatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评价人姓名
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "评价人姓名")
|
||||||
|
private String evaluatorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 被评价维修员ID,关联sys_user.id
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "维修员ID")
|
||||||
|
private Long evaluatedWorkerId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 被评价维修员姓名
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "维修员姓名")
|
||||||
|
private String evaluatedWorkerName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 综合评价得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "综合评价得分")
|
||||||
|
private BigDecimal overallScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 维修质量得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "维修质量得分")
|
||||||
|
private BigDecimal qualityScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务态度得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "服务态度得分")
|
||||||
|
private BigDecimal attitudeScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应速度得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "响应速度得分")
|
||||||
|
private BigDecimal responseSpeedScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 沟通效果得分(1.0-5.0)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "沟通效果得分")
|
||||||
|
private BigDecimal communicationScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文字评价内容
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "文字评价内容")
|
||||||
|
private String evaluationContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 满意度等级:1-非常满意,2-满意,3-一般,4-不满意,5-非常不满意
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "满意度等级", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(dictType = "pm_satisfaction_level")
|
||||||
|
private String satisfactionLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否匿名评价(0-实名,1-匿名)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "是否匿名评价", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(dictType = "sys_yes_no")
|
||||||
|
private Integer isAnonymous;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否公开显示(0-不公开,1-公开)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "是否公开显示", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(dictType = "sys_yes_no")
|
||||||
|
private Integer isPublic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评价时间
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "评价时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date evaluationTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务开始时间
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "服务开始时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date serviceStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务结束时间
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "服务结束时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date serviceEndTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务时长(分钟)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "服务时长(分钟)")
|
||||||
|
private Integer serviceDuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 正面标签(逗号分隔)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "正面标签")
|
||||||
|
private String positiveTags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 负面标签(逗号分隔)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "负面标签")
|
||||||
|
private String negativeTags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 改进建议
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "改进建议")
|
||||||
|
private String improvementSuggestions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注信息
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "备注信息")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 租户ID
|
||||||
|
*/
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建部门
|
||||||
|
*/
|
||||||
|
private Long createDept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建者
|
||||||
|
*/
|
||||||
|
private Long createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "创建时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新者
|
||||||
|
*/
|
||||||
|
private Long updateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.dromara.hq.mapper;
|
||||||
|
|
||||||
|
import org.dromara.hq.domain.HqPmRepairAttachment;
|
||||||
|
import org.dromara.hq.domain.vo.HqPmRepairAttachmentVo;
|
||||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报修附件Mapper接口
|
||||||
|
*
|
||||||
|
* @author Cursor AI
|
||||||
|
* @date 2025-01-26
|
||||||
|
*/
|
||||||
|
public interface HqPmRepairAttachmentMapper extends BaseMapperPlus<HqPmRepairAttachment, HqPmRepairAttachmentVo> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.dromara.hq.mapper;
|
||||||
|
|
||||||
|
import org.dromara.hq.domain.HqPmRepairCategory;
|
||||||
|
import org.dromara.hq.domain.vo.HqPmRepairCategoryVo;
|
||||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 维修类型Mapper接口
|
||||||
|
*
|
||||||
|
* @author Cursor AI
|
||||||
|
* @date 2025-01-23
|
||||||
|
*/
|
||||||
|
public interface HqPmRepairCategoryMapper extends BaseMapperPlus<HqPmRepairCategory, HqPmRepairCategoryVo> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.dromara.hq.mapper;
|
package org.dromara.hq.mapper;
|
||||||
|
|
||||||
import org.dromara.hq.domain.PmRepairOrder;
|
import org.dromara.hq.domain.HqPmRepairOrder;
|
||||||
import org.dromara.hq.domain.vo.PmRepairOrderVo;
|
import org.dromara.hq.domain.vo.HqPmRepairOrderVo;
|
||||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -13,7 +13,7 @@ import java.util.Map;
|
|||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
public interface PmRepairOrderMapper extends BaseMapperPlus<PmRepairOrder, PmRepairOrderVo> {
|
public interface HqPmRepairOrderMapper extends BaseMapperPlus<HqPmRepairOrder, HqPmRepairOrderVo> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询拥有"维修人员"角色的用户列表
|
* 查询拥有"维修人员"角色的用户列表
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.dromara.hq.mapper;
|
package org.dromara.hq.mapper;
|
||||||
|
|
||||||
import org.dromara.hq.domain.PmRepairProgress;
|
import org.dromara.hq.domain.HqPmRepairProgress;
|
||||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,6 +9,6 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
|||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-26
|
* @date 2025-01-26
|
||||||
*/
|
*/
|
||||||
public interface PmRepairProgressMapper extends BaseMapperPlus<PmRepairProgress, PmRepairProgress> {
|
public interface HqPmRepairProgressMapper extends BaseMapperPlus<HqPmRepairProgress, HqPmRepairProgress> {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.dromara.hq.mapper;
|
package org.dromara.hq.mapper;
|
||||||
|
|
||||||
import org.dromara.hq.domain.PmServiceEvaluation;
|
import org.dromara.hq.domain.HqPmServiceEvaluation;
|
||||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,6 +9,6 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
|||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-26
|
* @date 2025-01-26
|
||||||
*/
|
*/
|
||||||
public interface PmServiceEvaluationMapper extends BaseMapperPlus<PmServiceEvaluation, PmServiceEvaluation> {
|
public interface HqPmServiceEvaluationMapper extends BaseMapperPlus<HqPmServiceEvaluation, HqPmServiceEvaluation> {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package org.dromara.hq.mapper;
|
|
||||||
|
|
||||||
import org.dromara.hq.domain.PmRepairAttachment;
|
|
||||||
import org.dromara.hq.domain.vo.PmRepairAttachmentVo;
|
|
||||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 报修附件Mapper接口
|
|
||||||
*
|
|
||||||
* @author Cursor AI
|
|
||||||
* @date 2025-01-26
|
|
||||||
*/
|
|
||||||
public interface PmRepairAttachmentMapper extends BaseMapperPlus<PmRepairAttachment, PmRepairAttachmentVo> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package org.dromara.hq.mapper;
|
|
||||||
|
|
||||||
import org.dromara.hq.domain.PmRepairCategory;
|
|
||||||
import org.dromara.hq.domain.vo.PmRepairCategoryVo;
|
|
||||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 维修类型Mapper接口
|
|
||||||
*
|
|
||||||
* @author Cursor AI
|
|
||||||
* @date 2025-01-23
|
|
||||||
*/
|
|
||||||
public interface PmRepairCategoryMapper extends BaseMapperPlus<PmRepairCategory, PmRepairCategoryVo> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,8 @@ package org.dromara.hq.service;
|
|||||||
import org.dromara.hq.domain.vo.HqHallReservationVo;
|
import org.dromara.hq.domain.vo.HqHallReservationVo;
|
||||||
import org.dromara.hq.domain.bo.HqHallReservationBo;
|
import org.dromara.hq.domain.bo.HqHallReservationBo;
|
||||||
import org.dromara.hq.domain.bo.HqHallReservationAuditBo;
|
import org.dromara.hq.domain.bo.HqHallReservationAuditBo;
|
||||||
|
import org.dromara.hq.domain.bo.HqHallTimeCheckBo;
|
||||||
|
import org.dromara.hq.domain.vo.HqHallTimeCheckVo;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
|
|
||||||
@@ -74,4 +76,12 @@ public interface IHqHallReservationService {
|
|||||||
* @return 是否审核成功
|
* @return 是否审核成功
|
||||||
*/
|
*/
|
||||||
Boolean auditByIds(HqHallReservationAuditBo auditBo);
|
Boolean auditByIds(HqHallReservationAuditBo auditBo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查报告厅时间冲突
|
||||||
|
*
|
||||||
|
* @param timeCheckBo 时间检查参数
|
||||||
|
* @return 时间冲突检查结果
|
||||||
|
*/
|
||||||
|
HqHallTimeCheckVo checkTimeConflict(HqHallTimeCheckBo timeCheckBo);
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.dromara.hq.service;
|
package org.dromara.hq.service;
|
||||||
|
|
||||||
import org.dromara.hq.domain.vo.PmRepairAttachmentVo;
|
import org.dromara.hq.domain.vo.HqPmRepairAttachmentVo;
|
||||||
import org.dromara.hq.domain.bo.PmRepairAttachmentBo;
|
import org.dromara.hq.domain.bo.HqPmRepairAttachmentBo;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -15,37 +15,37 @@ import java.util.List;
|
|||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-26
|
* @date 2025-01-26
|
||||||
*/
|
*/
|
||||||
public interface IPmRepairAttachmentService {
|
public interface IHqPmRepairAttachmentService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报修附件
|
* 查询报修附件
|
||||||
*/
|
*/
|
||||||
PmRepairAttachmentVo queryById(Long id);
|
HqPmRepairAttachmentVo queryById(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报修附件列表
|
* 查询报修附件列表
|
||||||
*/
|
*/
|
||||||
TableDataInfo<PmRepairAttachmentVo> queryPageList(PmRepairAttachmentBo bo, PageQuery pageQuery);
|
TableDataInfo<HqPmRepairAttachmentVo> queryPageList(HqPmRepairAttachmentBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报修附件列表
|
* 查询报修附件列表
|
||||||
*/
|
*/
|
||||||
List<PmRepairAttachmentVo> queryList(PmRepairAttachmentBo bo);
|
List<HqPmRepairAttachmentVo> queryList(HqPmRepairAttachmentBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据工单ID查询附件列表
|
* 根据工单ID查询附件列表
|
||||||
*/
|
*/
|
||||||
List<PmRepairAttachmentVo> queryByOrderId(Long orderId);
|
List<HqPmRepairAttachmentVo> queryByOrderId(Long orderId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增报修附件
|
* 新增报修附件
|
||||||
*/
|
*/
|
||||||
Boolean insertByBo(PmRepairAttachmentBo bo);
|
Boolean insertByBo(HqPmRepairAttachmentBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改报修附件
|
* 修改报修附件
|
||||||
*/
|
*/
|
||||||
Boolean updateByBo(PmRepairAttachmentBo bo);
|
Boolean updateByBo(HqPmRepairAttachmentBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验并批量删除报修附件信息
|
* 校验并批量删除报修附件信息
|
||||||
@@ -55,12 +55,12 @@ public interface IPmRepairAttachmentService {
|
|||||||
/**
|
/**
|
||||||
* 上传附件文件
|
* 上传附件文件
|
||||||
*/
|
*/
|
||||||
PmRepairAttachmentVo uploadFile(Long orderId, String uploadStage, MultipartFile file, String description);
|
HqPmRepairAttachmentVo uploadFile(Long orderId, String uploadStage, MultipartFile file, String description);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量上传附件文件
|
* 批量上传附件文件
|
||||||
*/
|
*/
|
||||||
List<PmRepairAttachmentVo> uploadFiles(Long orderId, String uploadStage, MultipartFile[] files,
|
List<HqPmRepairAttachmentVo> uploadFiles(Long orderId, String uploadStage, MultipartFile[] files,
|
||||||
List<String> descriptions);
|
List<String> descriptions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.dromara.hq.service;
|
package org.dromara.hq.service;
|
||||||
|
|
||||||
import org.dromara.hq.domain.vo.PmRepairCategoryVo;
|
import org.dromara.hq.domain.vo.HqPmRepairCategoryVo;
|
||||||
import org.dromara.hq.domain.bo.PmRepairCategoryBo;
|
import org.dromara.hq.domain.bo.HqPmRepairCategoryBo;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
public interface IPmRepairCategoryService {
|
public interface IHqPmRepairCategoryService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询维修类型
|
* 查询维修类型
|
||||||
@@ -22,7 +22,7 @@ public interface IPmRepairCategoryService {
|
|||||||
* @param id 主键
|
* @param id 主键
|
||||||
* @return 维修类型
|
* @return 维修类型
|
||||||
*/
|
*/
|
||||||
PmRepairCategoryVo queryById(Long id);
|
HqPmRepairCategoryVo queryById(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询维修类型列表
|
* 分页查询维修类型列表
|
||||||
@@ -31,7 +31,7 @@ public interface IPmRepairCategoryService {
|
|||||||
* @param pageQuery 分页参数
|
* @param pageQuery 分页参数
|
||||||
* @return 维修类型分页列表
|
* @return 维修类型分页列表
|
||||||
*/
|
*/
|
||||||
TableDataInfo<PmRepairCategoryVo> queryPageList(PmRepairCategoryBo bo, PageQuery pageQuery);
|
TableDataInfo<HqPmRepairCategoryVo> queryPageList(HqPmRepairCategoryBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询符合条件的维修类型列表
|
* 查询符合条件的维修类型列表
|
||||||
@@ -39,7 +39,7 @@ public interface IPmRepairCategoryService {
|
|||||||
* @param bo 查询条件
|
* @param bo 查询条件
|
||||||
* @return 维修类型列表
|
* @return 维修类型列表
|
||||||
*/
|
*/
|
||||||
List<PmRepairCategoryVo> queryList(PmRepairCategoryBo bo);
|
List<HqPmRepairCategoryVo> queryList(HqPmRepairCategoryBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增维修类型
|
* 新增维修类型
|
||||||
@@ -47,7 +47,7 @@ public interface IPmRepairCategoryService {
|
|||||||
* @param bo 维修类型
|
* @param bo 维修类型
|
||||||
* @return 是否新增成功
|
* @return 是否新增成功
|
||||||
*/
|
*/
|
||||||
Boolean insertByBo(PmRepairCategoryBo bo);
|
Boolean insertByBo(HqPmRepairCategoryBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改维修类型
|
* 修改维修类型
|
||||||
@@ -55,7 +55,7 @@ public interface IPmRepairCategoryService {
|
|||||||
* @param bo 维修类型
|
* @param bo 维修类型
|
||||||
* @return 是否修改成功
|
* @return 是否修改成功
|
||||||
*/
|
*/
|
||||||
Boolean updateByBo(PmRepairCategoryBo bo);
|
Boolean updateByBo(HqPmRepairCategoryBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验并批量删除维修类型信息
|
* 校验并批量删除维修类型信息
|
||||||
@@ -71,7 +71,7 @@ public interface IPmRepairCategoryService {
|
|||||||
*
|
*
|
||||||
* @return 维修类型树形列表
|
* @return 维修类型树形列表
|
||||||
*/
|
*/
|
||||||
List<PmRepairCategoryVo> queryTree();
|
List<HqPmRepairCategoryVo> queryTree();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新使用次数
|
* 更新使用次数
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.dromara.hq.service;
|
package org.dromara.hq.service;
|
||||||
|
|
||||||
import org.dromara.hq.domain.vo.PmRepairOrderVo;
|
import org.dromara.hq.domain.vo.HqPmRepairOrderVo;
|
||||||
import org.dromara.hq.domain.bo.PmRepairOrderBo;
|
import org.dromara.hq.domain.bo.HqPmRepairOrderBo;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
* @author Cursor AI
|
* @author Cursor AI
|
||||||
* @date 2025-01-23
|
* @date 2025-01-23
|
||||||
*/
|
*/
|
||||||
public interface IPmRepairOrderService {
|
public interface IHqPmRepairOrderService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报修工单
|
* 查询报修工单
|
||||||
@@ -22,7 +22,7 @@ public interface IPmRepairOrderService {
|
|||||||
* @param id 主键
|
* @param id 主键
|
||||||
* @return 报修工单
|
* @return 报修工单
|
||||||
*/
|
*/
|
||||||
PmRepairOrderVo queryById(Long id);
|
HqPmRepairOrderVo queryById(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询报修工单列表
|
* 分页查询报修工单列表
|
||||||
@@ -31,7 +31,7 @@ public interface IPmRepairOrderService {
|
|||||||
* @param pageQuery 分页参数
|
* @param pageQuery 分页参数
|
||||||
* @return 报修工单分页列表
|
* @return 报修工单分页列表
|
||||||
*/
|
*/
|
||||||
TableDataInfo<PmRepairOrderVo> queryPageList(PmRepairOrderBo bo, PageQuery pageQuery);
|
TableDataInfo<HqPmRepairOrderVo> queryPageList(HqPmRepairOrderBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询符合条件的报修工单列表
|
* 查询符合条件的报修工单列表
|
||||||
@@ -39,7 +39,7 @@ public interface IPmRepairOrderService {
|
|||||||
* @param bo 查询条件
|
* @param bo 查询条件
|
||||||
* @return 报修工单列表
|
* @return 报修工单列表
|
||||||
*/
|
*/
|
||||||
List<PmRepairOrderVo> queryList(PmRepairOrderBo bo);
|
List<HqPmRepairOrderVo> queryList(HqPmRepairOrderBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增报修工单
|
* 新增报修工单
|
||||||
@@ -47,7 +47,7 @@ public interface IPmRepairOrderService {
|
|||||||
* @param bo 报修工单
|
* @param bo 报修工单
|
||||||
* @return 是否新增成功
|
* @return 是否新增成功
|
||||||
*/
|
*/
|
||||||
Boolean insertByBo(PmRepairOrderBo bo);
|
Boolean insertByBo(HqPmRepairOrderBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改报修工单
|
* 修改报修工单
|
||||||
@@ -55,7 +55,7 @@ public interface IPmRepairOrderService {
|
|||||||
* @param bo 报修工单
|
* @param bo 报修工单
|
||||||
* @return 是否修改成功
|
* @return 是否修改成功
|
||||||
*/
|
*/
|
||||||
Boolean updateByBo(PmRepairOrderBo bo);
|
Boolean updateByBo(HqPmRepairOrderBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验并批量删除报修工单信息
|
* 校验并批量删除报修工单信息
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package org.dromara.hq.service;
|
||||||
|
|
||||||
|
import org.dromara.hq.domain.vo.HqPmRepairProgressVo;
|
||||||
|
import org.dromara.hq.domain.bo.HqPmRepairProgressBo;
|
||||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 维修进度记录Service接口
|
||||||
|
*
|
||||||
|
* @author Cursor AI
|
||||||
|
* @date 2025-01-23
|
||||||
|
*/
|
||||||
|
public interface IHqPmRepairProgressService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询维修进度记录
|
||||||
|
*/
|
||||||
|
HqPmRepairProgressVo queryById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询维修进度记录列表
|
||||||
|
*/
|
||||||
|
TableDataInfo<HqPmRepairProgressVo> queryPageList(HqPmRepairProgressBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询维修进度记录列表
|
||||||
|
*/
|
||||||
|
List<HqPmRepairProgressVo> queryList(HqPmRepairProgressBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据工单ID查询进度记录列表
|
||||||
|
*/
|
||||||
|
List<HqPmRepairProgressVo> queryListByOrderId(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增维修进度记录
|
||||||
|
*/
|
||||||
|
Boolean insertByBo(HqPmRepairProgressBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改维修进度记录
|
||||||
|
*/
|
||||||
|
Boolean updateByBo(HqPmRepairProgressBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验并批量删除维修进度记录信息
|
||||||
|
*/
|
||||||
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除维修进度记录信息
|
||||||
|
*/
|
||||||
|
Boolean deleteByIds(Collection<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除维修进度记录信息
|
||||||
|
*/
|
||||||
|
Boolean deleteById(Long id);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package org.dromara.hq.service;
|
||||||
|
|
||||||
|
import org.dromara.hq.domain.vo.HqPmServiceEvaluationVo;
|
||||||
|
import org.dromara.hq.domain.bo.HqPmServiceEvaluationBo;
|
||||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务评价Service接口
|
||||||
|
*
|
||||||
|
* @author Cursor AI
|
||||||
|
* @date 2025-01-23
|
||||||
|
*/
|
||||||
|
public interface IHqPmServiceEvaluationService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询服务评价
|
||||||
|
*/
|
||||||
|
HqPmServiceEvaluationVo queryById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询服务评价列表
|
||||||
|
*/
|
||||||
|
TableDataInfo<HqPmServiceEvaluationVo> queryPageList(HqPmServiceEvaluationBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询服务评价列表
|
||||||
|
*/
|
||||||
|
List<HqPmServiceEvaluationVo> queryList(HqPmServiceEvaluationBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据工单ID查询评价信息
|
||||||
|
*/
|
||||||
|
HqPmServiceEvaluationVo queryByOrderId(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据维修员ID查询评价列表
|
||||||
|
*/
|
||||||
|
List<HqPmServiceEvaluationVo> queryListByWorkerId(Long workerId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增服务评价
|
||||||
|
*/
|
||||||
|
Boolean insertByBo(HqPmServiceEvaluationBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改服务评价
|
||||||
|
*/
|
||||||
|
Boolean updateByBo(HqPmServiceEvaluationBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验并批量删除服务评价信息
|
||||||
|
*/
|
||||||
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除服务评价信息
|
||||||
|
*/
|
||||||
|
Boolean deleteByIds(Collection<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除服务评价信息
|
||||||
|
*/
|
||||||
|
Boolean deleteById(Long id);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,7 +12,9 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.dromara.hq.domain.bo.HqHallReservationBo;
|
import org.dromara.hq.domain.bo.HqHallReservationBo;
|
||||||
import org.dromara.hq.domain.bo.HqHallReservationAuditBo;
|
import org.dromara.hq.domain.bo.HqHallReservationAuditBo;
|
||||||
|
import org.dromara.hq.domain.bo.HqHallTimeCheckBo;
|
||||||
import org.dromara.hq.domain.vo.HqHallReservationVo;
|
import org.dromara.hq.domain.vo.HqHallReservationVo;
|
||||||
|
import org.dromara.hq.domain.vo.HqHallTimeCheckVo;
|
||||||
import org.dromara.hq.domain.HqHallReservation;
|
import org.dromara.hq.domain.HqHallReservation;
|
||||||
import org.dromara.hq.mapper.HqHallReservationMapper;
|
import org.dromara.hq.mapper.HqHallReservationMapper;
|
||||||
import org.dromara.hq.service.IHqHallReservationService;
|
import org.dromara.hq.service.IHqHallReservationService;
|
||||||
@@ -223,4 +225,49 @@ public class HqHallReservationServiceImpl implements IHqHallReservationService {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查报告厅时间冲突
|
||||||
|
*
|
||||||
|
* @param timeCheckBo 时间检查参数
|
||||||
|
* @return 时间冲突检查结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public HqHallTimeCheckVo checkTimeConflict(HqHallTimeCheckBo timeCheckBo) {
|
||||||
|
log.info("开始检查报告厅时间冲突,参数:{}", timeCheckBo);
|
||||||
|
|
||||||
|
// 构建查询条件:同一报告厅,时间有重叠,状态为已批准的预约
|
||||||
|
LambdaQueryWrapper<HqHallReservation> lqw = Wrappers.lambdaQuery();
|
||||||
|
|
||||||
|
// 1. 同一报告厅
|
||||||
|
lqw.eq(HqHallReservation::getHallId, timeCheckBo.getHallId());
|
||||||
|
|
||||||
|
// 2. 状态为已批准(状态为'1')
|
||||||
|
lqw.eq(HqHallReservation::getStatus, "1");
|
||||||
|
|
||||||
|
// 3. 如果有排除ID,则排除该记录(用于编辑时排除自己)
|
||||||
|
if (timeCheckBo.getExcludeId() != null) {
|
||||||
|
lqw.ne(HqHallReservation::getId, timeCheckBo.getExcludeId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 时间重叠判断:
|
||||||
|
// 两个时间段重叠的条件:新开始时间 < 已存在结束时间 AND 新结束时间 > 已存在开始时间
|
||||||
|
// 即:startTime < existingEndTime AND endTime > existingStartTime
|
||||||
|
lqw.and(wrapper -> wrapper
|
||||||
|
.lt(HqHallReservation::getStartTime, timeCheckBo.getEndTime())
|
||||||
|
.gt(HqHallReservation::getEndTime, timeCheckBo.getStartTime()));
|
||||||
|
|
||||||
|
// 查询冲突的预约记录
|
||||||
|
List<HqHallReservationVo> conflictList = baseMapper.selectVoList(lqw);
|
||||||
|
|
||||||
|
// 构建返回结果
|
||||||
|
if (conflictList.isEmpty()) {
|
||||||
|
log.info("未发现时间冲突");
|
||||||
|
return HqHallTimeCheckVo.noConflict();
|
||||||
|
} else {
|
||||||
|
String conflictMessage = String.format("发现 %d 个时间冲突的已批准预约", conflictList.size());
|
||||||
|
log.info("发现时间冲突,冲突记录数:{}", conflictList.size());
|
||||||
|
return HqHallTimeCheckVo.hasConflict(conflictList, conflictMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,12 +16,12 @@ import org.dromara.common.oss.core.OssClient;
|
|||||||
import org.dromara.common.oss.entity.UploadResult;
|
import org.dromara.common.oss.entity.UploadResult;
|
||||||
import org.dromara.common.oss.factory.OssFactory;
|
import org.dromara.common.oss.factory.OssFactory;
|
||||||
import org.dromara.common.satoken.utils.LoginHelper;
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.hq.domain.PmRepairAttachment;
|
import org.dromara.hq.domain.HqPmRepairAttachment;
|
||||||
import org.dromara.hq.domain.bo.PmRepairAttachmentBo;
|
import org.dromara.hq.domain.bo.HqPmRepairAttachmentBo;
|
||||||
import org.dromara.hq.domain.vo.PmRepairAttachmentVo;
|
import org.dromara.hq.domain.vo.HqPmRepairAttachmentVo;
|
||||||
import org.dromara.hq.mapper.PmRepairAttachmentMapper;
|
import org.dromara.hq.mapper.HqPmRepairAttachmentMapper;
|
||||||
import org.dromara.hq.mapper.PmRepairOrderMapper;
|
import org.dromara.hq.mapper.HqPmRepairOrderMapper;
|
||||||
import org.dromara.hq.service.IPmRepairAttachmentService;
|
import org.dromara.hq.service.IHqPmRepairAttachmentService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -40,16 +40,16 @@ import java.util.List;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Service
|
@Service
|
||||||
public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService {
|
public class HqPmRepairAttachmentServiceImpl implements IHqPmRepairAttachmentService {
|
||||||
|
|
||||||
private final PmRepairAttachmentMapper baseMapper;
|
private final HqPmRepairAttachmentMapper baseMapper;
|
||||||
private final PmRepairOrderMapper repairOrderMapper;
|
private final HqPmRepairOrderMapper repairOrderMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报修附件
|
* 查询报修附件
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PmRepairAttachmentVo queryById(Long id) {
|
public HqPmRepairAttachmentVo queryById(Long id) {
|
||||||
return baseMapper.selectVoById(id);
|
return baseMapper.selectVoById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,9 +57,9 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
* 查询报修附件列表
|
* 查询报修附件列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TableDataInfo<PmRepairAttachmentVo> queryPageList(PmRepairAttachmentBo bo, PageQuery pageQuery) {
|
public TableDataInfo<HqPmRepairAttachmentVo> queryPageList(HqPmRepairAttachmentBo bo, PageQuery pageQuery) {
|
||||||
LambdaQueryWrapper<PmRepairAttachment> lqw = buildQueryWrapper(bo);
|
LambdaQueryWrapper<HqPmRepairAttachment> lqw = buildQueryWrapper(bo);
|
||||||
Page<PmRepairAttachmentVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
Page<HqPmRepairAttachmentVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||||
return TableDataInfo.build(result);
|
return TableDataInfo.build(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,8 +67,8 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
* 查询报修附件列表
|
* 查询报修附件列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<PmRepairAttachmentVo> queryList(PmRepairAttachmentBo bo) {
|
public List<HqPmRepairAttachmentVo> queryList(HqPmRepairAttachmentBo bo) {
|
||||||
LambdaQueryWrapper<PmRepairAttachment> lqw = buildQueryWrapper(bo);
|
LambdaQueryWrapper<HqPmRepairAttachment> lqw = buildQueryWrapper(bo);
|
||||||
return baseMapper.selectVoList(lqw);
|
return baseMapper.selectVoList(lqw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,22 +76,22 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
* 根据工单ID查询附件列表
|
* 根据工单ID查询附件列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<PmRepairAttachmentVo> queryByOrderId(Long orderId) {
|
public List<HqPmRepairAttachmentVo> queryByOrderId(Long orderId) {
|
||||||
LambdaQueryWrapper<PmRepairAttachment> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairAttachment> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(PmRepairAttachment::getOrderId, orderId);
|
lqw.eq(HqPmRepairAttachment::getOrderId, orderId);
|
||||||
lqw.orderByAsc(PmRepairAttachment::getSortOrder)
|
lqw.orderByAsc(HqPmRepairAttachment::getSortOrder)
|
||||||
.orderByAsc(PmRepairAttachment::getCreateTime);
|
.orderByAsc(HqPmRepairAttachment::getCreateTime);
|
||||||
return baseMapper.selectVoList(lqw);
|
return baseMapper.selectVoList(lqw);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LambdaQueryWrapper<PmRepairAttachment> buildQueryWrapper(PmRepairAttachmentBo bo) {
|
private LambdaQueryWrapper<HqPmRepairAttachment> buildQueryWrapper(HqPmRepairAttachmentBo bo) {
|
||||||
LambdaQueryWrapper<PmRepairAttachment> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairAttachment> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(bo.getOrderId() != null, PmRepairAttachment::getOrderId, bo.getOrderId());
|
lqw.eq(bo.getOrderId() != null, HqPmRepairAttachment::getOrderId, bo.getOrderId());
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getFileName()), PmRepairAttachment::getFileName, bo.getFileName());
|
lqw.like(StringUtils.isNotBlank(bo.getFileName()), HqPmRepairAttachment::getFileName, bo.getFileName());
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getFileType()), PmRepairAttachment::getFileType, bo.getFileType());
|
lqw.eq(StringUtils.isNotBlank(bo.getFileType()), HqPmRepairAttachment::getFileType, bo.getFileType());
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getUploadStage()), PmRepairAttachment::getUploadStage, bo.getUploadStage());
|
lqw.eq(StringUtils.isNotBlank(bo.getUploadStage()), HqPmRepairAttachment::getUploadStage, bo.getUploadStage());
|
||||||
lqw.eq(bo.getUploaderId() != null, PmRepairAttachment::getUploaderId, bo.getUploaderId());
|
lqw.eq(bo.getUploaderId() != null, HqPmRepairAttachment::getUploaderId, bo.getUploaderId());
|
||||||
lqw.orderByAsc(PmRepairAttachment::getSortOrder).orderByDesc(PmRepairAttachment::getCreateTime);
|
lqw.orderByAsc(HqPmRepairAttachment::getSortOrder).orderByDesc(HqPmRepairAttachment::getCreateTime);
|
||||||
return lqw;
|
return lqw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,8 +99,8 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
* 新增报修附件
|
* 新增报修附件
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean insertByBo(PmRepairAttachmentBo bo) {
|
public Boolean insertByBo(HqPmRepairAttachmentBo bo) {
|
||||||
PmRepairAttachment add = MapstructUtils.convert(bo, PmRepairAttachment.class);
|
HqPmRepairAttachment add = MapstructUtils.convert(bo, HqPmRepairAttachment.class);
|
||||||
validEntityBeforeSave(add);
|
validEntityBeforeSave(add);
|
||||||
boolean flag = baseMapper.insert(add) > 0;
|
boolean flag = baseMapper.insert(add) > 0;
|
||||||
if (flag) {
|
if (flag) {
|
||||||
@@ -115,8 +115,8 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
* 修改报修附件
|
* 修改报修附件
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean updateByBo(PmRepairAttachmentBo bo) {
|
public Boolean updateByBo(HqPmRepairAttachmentBo bo) {
|
||||||
PmRepairAttachment update = MapstructUtils.convert(bo, PmRepairAttachment.class);
|
HqPmRepairAttachment update = MapstructUtils.convert(bo, HqPmRepairAttachment.class);
|
||||||
validEntityBeforeSave(update);
|
validEntityBeforeSave(update);
|
||||||
return baseMapper.updateById(update) > 0;
|
return baseMapper.updateById(update) > 0;
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
/**
|
/**
|
||||||
* 保存前的数据校验
|
* 保存前的数据校验
|
||||||
*/
|
*/
|
||||||
private void validEntityBeforeSave(PmRepairAttachment entity) {
|
private void validEntityBeforeSave(HqPmRepairAttachment entity) {
|
||||||
// 设置默认值
|
// 设置默认值
|
||||||
if (entity.getSortOrder() == null) {
|
if (entity.getSortOrder() == null) {
|
||||||
entity.setSortOrder(0);
|
entity.setSortOrder(0);
|
||||||
@@ -147,9 +147,9 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||||
// 先获取要删除的附件信息(在删除前)
|
// 先获取要删除的附件信息(在删除前)
|
||||||
List<PmRepairAttachmentVo> attachments = new ArrayList<>();
|
List<HqPmRepairAttachmentVo> attachments = new ArrayList<>();
|
||||||
for (Long id : ids) {
|
for (Long id : ids) {
|
||||||
PmRepairAttachmentVo attachment = baseMapper.selectVoById(id);
|
HqPmRepairAttachmentVo attachment = baseMapper.selectVoById(id);
|
||||||
if (attachment != null) {
|
if (attachment != null) {
|
||||||
attachments.add(attachment);
|
attachments.add(attachment);
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
// 删除OSS文件
|
// 删除OSS文件
|
||||||
for (PmRepairAttachmentVo attachment : attachments) {
|
for (HqPmRepairAttachmentVo attachment : attachments) {
|
||||||
try {
|
try {
|
||||||
if (StringUtils.isNotBlank(attachment.getFilePath())) {
|
if (StringUtils.isNotBlank(attachment.getFilePath())) {
|
||||||
OssFactory.instance().delete(attachment.getFilePath());
|
OssFactory.instance().delete(attachment.getFilePath());
|
||||||
@@ -176,7 +176,7 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
if (flag) {
|
if (flag) {
|
||||||
// 更新相关工单的附件数量
|
// 更新相关工单的附件数量
|
||||||
attachments.stream()
|
attachments.stream()
|
||||||
.map(PmRepairAttachmentVo::getOrderId)
|
.map(HqPmRepairAttachmentVo::getOrderId)
|
||||||
.distinct()
|
.distinct()
|
||||||
.forEach(this::updateOrderAttachmentCount);
|
.forEach(this::updateOrderAttachmentCount);
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public PmRepairAttachmentVo uploadFile(Long orderId, String uploadStage, MultipartFile file, String description) {
|
public HqPmRepairAttachmentVo uploadFile(Long orderId, String uploadStage, MultipartFile file, String description) {
|
||||||
try {
|
try {
|
||||||
// 文件基本信息
|
// 文件基本信息
|
||||||
String originalFilename = file.getOriginalFilename();
|
String originalFilename = file.getOriginalFilename();
|
||||||
@@ -200,7 +200,7 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
UploadResult uploadResult = OssFactory.instance().uploadSuffix(file.getBytes(), fileExtension, contentType);
|
UploadResult uploadResult = OssFactory.instance().uploadSuffix(file.getBytes(), fileExtension, contentType);
|
||||||
|
|
||||||
// 构建附件信息
|
// 构建附件信息
|
||||||
PmRepairAttachmentBo bo = new PmRepairAttachmentBo();
|
HqPmRepairAttachmentBo bo = new HqPmRepairAttachmentBo();
|
||||||
bo.setOrderId(orderId);
|
bo.setOrderId(orderId);
|
||||||
bo.setFileName(originalFilename);
|
bo.setFileName(originalFilename);
|
||||||
bo.setFilePath(uploadResult.getUrl());
|
bo.setFilePath(uploadResult.getUrl());
|
||||||
@@ -231,16 +231,16 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public List<PmRepairAttachmentVo> uploadFiles(Long orderId, String uploadStage, MultipartFile[] files,
|
public List<HqPmRepairAttachmentVo> uploadFiles(Long orderId, String uploadStage, MultipartFile[] files,
|
||||||
List<String> descriptions) {
|
List<String> descriptions) {
|
||||||
List<PmRepairAttachmentVo> results = new ArrayList<>();
|
List<HqPmRepairAttachmentVo> results = new ArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
for (int i = 0; i < files.length; i++) {
|
||||||
MultipartFile file = files[i];
|
MultipartFile file = files[i];
|
||||||
String description = (descriptions != null && i < descriptions.size()) ? descriptions.get(i) : null;
|
String description = (descriptions != null && i < descriptions.size()) ? descriptions.get(i) : null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PmRepairAttachmentVo result = uploadFile(orderId, uploadStage, file, description);
|
HqPmRepairAttachmentVo result = uploadFile(orderId, uploadStage, file, description);
|
||||||
results.add(result);
|
results.add(result);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("批量上传第{}个文件失败: {}", i + 1, e.getMessage());
|
log.error("批量上传第{}个文件失败: {}", i + 1, e.getMessage());
|
||||||
@@ -257,7 +257,7 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Boolean deleteAttachment(Long id) {
|
public Boolean deleteAttachment(Long id) {
|
||||||
PmRepairAttachmentVo attachment = queryById(id);
|
HqPmRepairAttachmentVo attachment = queryById(id);
|
||||||
if (attachment == null) {
|
if (attachment == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -292,14 +292,14 @@ public class PmRepairAttachmentServiceImpl implements IPmRepairAttachmentService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LambdaQueryWrapper<PmRepairAttachment> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairAttachment> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(PmRepairAttachment::getOrderId, orderId);
|
lqw.eq(HqPmRepairAttachment::getOrderId, orderId);
|
||||||
long count = baseMapper.selectCount(lqw);
|
long count = baseMapper.selectCount(lqw);
|
||||||
|
|
||||||
// 更新工单的附件数量
|
// 更新工单的附件数量
|
||||||
LambdaUpdateWrapper<org.dromara.hq.domain.PmRepairOrder> updateWrapper = Wrappers.lambdaUpdate();
|
LambdaUpdateWrapper<org.dromara.hq.domain.HqPmRepairOrder> updateWrapper = Wrappers.lambdaUpdate();
|
||||||
updateWrapper.eq(org.dromara.hq.domain.PmRepairOrder::getId, orderId)
|
updateWrapper.eq(org.dromara.hq.domain.HqPmRepairOrder::getId, orderId)
|
||||||
.set(org.dromara.hq.domain.PmRepairOrder::getAttachmentCount, (int) count);
|
.set(org.dromara.hq.domain.HqPmRepairOrder::getAttachmentCount, (int) count);
|
||||||
repairOrderMapper.update(null, updateWrapper);
|
repairOrderMapper.update(null, updateWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,11 +11,11 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.dromara.hq.domain.bo.PmRepairCategoryBo;
|
import org.dromara.hq.domain.bo.HqPmRepairCategoryBo;
|
||||||
import org.dromara.hq.domain.vo.PmRepairCategoryVo;
|
import org.dromara.hq.domain.vo.HqPmRepairCategoryVo;
|
||||||
import org.dromara.hq.domain.PmRepairCategory;
|
import org.dromara.hq.domain.HqPmRepairCategory;
|
||||||
import org.dromara.hq.mapper.PmRepairCategoryMapper;
|
import org.dromara.hq.mapper.HqPmRepairCategoryMapper;
|
||||||
import org.dromara.hq.service.IPmRepairCategoryService;
|
import org.dromara.hq.service.IHqPmRepairCategoryService;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -32,9 +32,9 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Service
|
@Service
|
||||||
public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
public class HqPmRepairCategoryServiceImpl implements IHqPmRepairCategoryService {
|
||||||
|
|
||||||
private final PmRepairCategoryMapper baseMapper;
|
private final HqPmRepairCategoryMapper baseMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询维修类型
|
* 查询维修类型
|
||||||
@@ -43,7 +43,7 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
* @return 维修类型
|
* @return 维修类型
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PmRepairCategoryVo queryById(Long id) {
|
public HqPmRepairCategoryVo queryById(Long id) {
|
||||||
return baseMapper.selectVoById(id);
|
return baseMapper.selectVoById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,9 +55,9 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
* @return 维修类型分页列表
|
* @return 维修类型分页列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TableDataInfo<PmRepairCategoryVo> queryPageList(PmRepairCategoryBo bo, PageQuery pageQuery) {
|
public TableDataInfo<HqPmRepairCategoryVo> queryPageList(HqPmRepairCategoryBo bo, PageQuery pageQuery) {
|
||||||
LambdaQueryWrapper<PmRepairCategory> lqw = buildQueryWrapper(bo);
|
LambdaQueryWrapper<HqPmRepairCategory> lqw = buildQueryWrapper(bo);
|
||||||
Page<PmRepairCategoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
Page<HqPmRepairCategoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||||
return TableDataInfo.build(result);
|
return TableDataInfo.build(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,26 +68,28 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
* @return 维修类型列表
|
* @return 维修类型列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<PmRepairCategoryVo> queryList(PmRepairCategoryBo bo) {
|
public List<HqPmRepairCategoryVo> queryList(HqPmRepairCategoryBo bo) {
|
||||||
LambdaQueryWrapper<PmRepairCategory> lqw = buildQueryWrapper(bo);
|
LambdaQueryWrapper<HqPmRepairCategory> lqw = buildQueryWrapper(bo);
|
||||||
return baseMapper.selectVoList(lqw);
|
return baseMapper.selectVoList(lqw);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LambdaQueryWrapper<PmRepairCategory> buildQueryWrapper(PmRepairCategoryBo bo) {
|
private LambdaQueryWrapper<HqPmRepairCategory> buildQueryWrapper(HqPmRepairCategoryBo bo) {
|
||||||
LambdaQueryWrapper<PmRepairCategory> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairCategory> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.orderByAsc(PmRepairCategory::getSortOrder).orderByAsc(PmRepairCategory::getId);
|
lqw.orderByAsc(HqPmRepairCategory::getSortOrder).orderByAsc(HqPmRepairCategory::getId);
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), PmRepairCategory::getCategoryName, bo.getCategoryName());
|
lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), HqPmRepairCategory::getCategoryName,
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getCategoryCode()), PmRepairCategory::getCategoryCode, bo.getCategoryCode());
|
bo.getCategoryName());
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getCategoryDescription()), PmRepairCategory::getCategoryDescription,
|
lqw.like(StringUtils.isNotBlank(bo.getCategoryCode()), HqPmRepairCategory::getCategoryCode,
|
||||||
|
bo.getCategoryCode());
|
||||||
|
lqw.like(StringUtils.isNotBlank(bo.getCategoryDescription()), HqPmRepairCategory::getCategoryDescription,
|
||||||
bo.getCategoryDescription());
|
bo.getCategoryDescription());
|
||||||
lqw.eq(bo.getParentId() != null, PmRepairCategory::getParentId, bo.getParentId());
|
lqw.eq(bo.getParentId() != null, HqPmRepairCategory::getParentId, bo.getParentId());
|
||||||
lqw.eq(bo.getLevelDepth() != null, PmRepairCategory::getLevelDepth, bo.getLevelDepth());
|
lqw.eq(bo.getLevelDepth() != null, HqPmRepairCategory::getLevelDepth, bo.getLevelDepth());
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getSkillLevel()), PmRepairCategory::getSkillLevel, bo.getSkillLevel());
|
lqw.eq(StringUtils.isNotBlank(bo.getSkillLevel()), HqPmRepairCategory::getSkillLevel, bo.getSkillLevel());
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), PmRepairCategory::getStatus, bo.getStatus());
|
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), HqPmRepairCategory::getStatus, bo.getStatus());
|
||||||
|
|
||||||
// IN查询条件
|
// IN查询条件
|
||||||
lqw.in(CollUtil.isNotEmpty(bo.getStatusIn()), PmRepairCategory::getStatus, bo.getStatusIn());
|
lqw.in(CollUtil.isNotEmpty(bo.getStatusIn()), HqPmRepairCategory::getStatus, bo.getStatusIn());
|
||||||
lqw.in(CollUtil.isNotEmpty(bo.getParentIdIn()), PmRepairCategory::getParentId, bo.getParentIdIn());
|
lqw.in(CollUtil.isNotEmpty(bo.getParentIdIn()), HqPmRepairCategory::getParentId, bo.getParentIdIn());
|
||||||
|
|
||||||
return lqw;
|
return lqw;
|
||||||
}
|
}
|
||||||
@@ -99,8 +101,8 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
* @return 是否新增成功
|
* @return 是否新增成功
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean insertByBo(PmRepairCategoryBo bo) {
|
public Boolean insertByBo(HqPmRepairCategoryBo bo) {
|
||||||
PmRepairCategory add = MapstructUtils.convert(bo, PmRepairCategory.class);
|
HqPmRepairCategory add = MapstructUtils.convert(bo, HqPmRepairCategory.class);
|
||||||
validEntityBeforeSave(add);
|
validEntityBeforeSave(add);
|
||||||
|
|
||||||
// 设置层级信息
|
// 设置层级信息
|
||||||
@@ -140,12 +142,12 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
* @return 是否修改成功
|
* @return 是否修改成功
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean updateByBo(PmRepairCategoryBo bo) {
|
public Boolean updateByBo(HqPmRepairCategoryBo bo) {
|
||||||
PmRepairCategory update = MapstructUtils.convert(bo, PmRepairCategory.class);
|
HqPmRepairCategory update = MapstructUtils.convert(bo, HqPmRepairCategory.class);
|
||||||
validEntityBeforeSave(update);
|
validEntityBeforeSave(update);
|
||||||
|
|
||||||
// 如果修改了父级,需要重新计算层级信息
|
// 如果修改了父级,需要重新计算层级信息
|
||||||
PmRepairCategory oldEntity = baseMapper.selectById(update.getId());
|
HqPmRepairCategory oldEntity = baseMapper.selectById(update.getId());
|
||||||
if (oldEntity != null && !oldEntity.getParentId().equals(update.getParentId())) {
|
if (oldEntity != null && !oldEntity.getParentId().equals(update.getParentId())) {
|
||||||
buildHierarchyInfo(update);
|
buildHierarchyInfo(update);
|
||||||
// 更新新旧父级的子类数量
|
// 更新新旧父级的子类数量
|
||||||
@@ -159,13 +161,13 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
/**
|
/**
|
||||||
* 保存前的数据校验
|
* 保存前的数据校验
|
||||||
*/
|
*/
|
||||||
private void validEntityBeforeSave(PmRepairCategory entity) {
|
private void validEntityBeforeSave(HqPmRepairCategory entity) {
|
||||||
// 校验类型编码唯一性
|
// 校验类型编码唯一性
|
||||||
if (StringUtils.isNotBlank(entity.getCategoryCode())) {
|
if (StringUtils.isNotBlank(entity.getCategoryCode())) {
|
||||||
LambdaQueryWrapper<PmRepairCategory> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairCategory> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(PmRepairCategory::getCategoryCode, entity.getCategoryCode());
|
lqw.eq(HqPmRepairCategory::getCategoryCode, entity.getCategoryCode());
|
||||||
if (entity.getId() != null) {
|
if (entity.getId() != null) {
|
||||||
lqw.ne(PmRepairCategory::getId, entity.getId());
|
lqw.ne(HqPmRepairCategory::getId, entity.getId());
|
||||||
}
|
}
|
||||||
boolean exists = baseMapper.exists(lqw);
|
boolean exists = baseMapper.exists(lqw);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
@@ -182,13 +184,13 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
/**
|
/**
|
||||||
* 构建层级信息
|
* 构建层级信息
|
||||||
*/
|
*/
|
||||||
private void buildHierarchyInfo(PmRepairCategory entity) {
|
private void buildHierarchyInfo(HqPmRepairCategory entity) {
|
||||||
if (entity.getParentId() == null || entity.getParentId() == 0L) {
|
if (entity.getParentId() == null || entity.getParentId() == 0L) {
|
||||||
entity.setParentId(0L);
|
entity.setParentId(0L);
|
||||||
entity.setLevelDepth(1);
|
entity.setLevelDepth(1);
|
||||||
entity.setAncestorIds("0");
|
entity.setAncestorIds("0");
|
||||||
} else {
|
} else {
|
||||||
PmRepairCategory parent = baseMapper.selectById(entity.getParentId());
|
HqPmRepairCategory parent = baseMapper.selectById(entity.getParentId());
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
entity.setLevelDepth(parent.getLevelDepth() + 1);
|
entity.setLevelDepth(parent.getLevelDepth() + 1);
|
||||||
entity.setAncestorIds(parent.getAncestorIds() + "," + parent.getId());
|
entity.setAncestorIds(parent.getAncestorIds() + "," + parent.getId());
|
||||||
@@ -204,11 +206,11 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LambdaQueryWrapper<PmRepairCategory> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairCategory> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(PmRepairCategory::getParentId, parentId);
|
lqw.eq(HqPmRepairCategory::getParentId, parentId);
|
||||||
long count = baseMapper.selectCount(lqw);
|
long count = baseMapper.selectCount(lqw);
|
||||||
|
|
||||||
PmRepairCategory parent = new PmRepairCategory();
|
HqPmRepairCategory parent = new HqPmRepairCategory();
|
||||||
parent.setId(parentId);
|
parent.setId(parentId);
|
||||||
parent.setChildrenCount((int) count);
|
parent.setChildrenCount((int) count);
|
||||||
baseMapper.updateById(parent);
|
baseMapper.updateById(parent);
|
||||||
@@ -226,7 +228,7 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
if (isValid) {
|
if (isValid) {
|
||||||
// 校验是否有子类
|
// 校验是否有子类
|
||||||
for (Long id : ids) {
|
for (Long id : ids) {
|
||||||
PmRepairCategory category = baseMapper.selectById(id);
|
HqPmRepairCategory category = baseMapper.selectById(id);
|
||||||
if (category != null && category.getChildrenCount() > 0) {
|
if (category != null && category.getChildrenCount() > 0) {
|
||||||
throw new ServiceException("存在子类型,不允许删除:" + category.getCategoryName());
|
throw new ServiceException("存在子类型,不允许删除:" + category.getCategoryName());
|
||||||
}
|
}
|
||||||
@@ -234,10 +236,10 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除后更新父级的子类数量
|
// 删除后更新父级的子类数量
|
||||||
List<PmRepairCategory> categories = baseMapper.selectBatchIds(ids);
|
List<HqPmRepairCategory> categories = baseMapper.selectBatchIds(ids);
|
||||||
boolean flag = baseMapper.deleteByIds(ids) > 0;
|
boolean flag = baseMapper.deleteByIds(ids) > 0;
|
||||||
if (flag) {
|
if (flag) {
|
||||||
for (PmRepairCategory category : categories) {
|
for (HqPmRepairCategory category : categories) {
|
||||||
updateParentChildrenCount(category.getParentId());
|
updateParentChildrenCount(category.getParentId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,11 +252,11 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
* @return 维修类型树形列表
|
* @return 维修类型树形列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<PmRepairCategoryVo> queryTree() {
|
public List<HqPmRepairCategoryVo> queryTree() {
|
||||||
LambdaQueryWrapper<PmRepairCategory> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairCategory> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(PmRepairCategory::getStatus, "1");
|
lqw.eq(HqPmRepairCategory::getStatus, "1");
|
||||||
lqw.orderByAsc(PmRepairCategory::getSortOrder).orderByAsc(PmRepairCategory::getId);
|
lqw.orderByAsc(HqPmRepairCategory::getSortOrder).orderByAsc(HqPmRepairCategory::getId);
|
||||||
List<PmRepairCategoryVo> allList = baseMapper.selectVoList(lqw);
|
List<HqPmRepairCategoryVo> allList = baseMapper.selectVoList(lqw);
|
||||||
|
|
||||||
return buildTree(allList, 0L);
|
return buildTree(allList, 0L);
|
||||||
}
|
}
|
||||||
@@ -262,11 +264,11 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
/**
|
/**
|
||||||
* 构建树形结构
|
* 构建树形结构
|
||||||
*/
|
*/
|
||||||
private List<PmRepairCategoryVo> buildTree(List<PmRepairCategoryVo> allList, Long parentId) {
|
private List<HqPmRepairCategoryVo> buildTree(List<HqPmRepairCategoryVo> allList, Long parentId) {
|
||||||
return allList.stream()
|
return allList.stream()
|
||||||
.filter(item -> parentId.equals(item.getParentId()))
|
.filter(item -> parentId.equals(item.getParentId()))
|
||||||
.map(item -> {
|
.map(item -> {
|
||||||
List<PmRepairCategoryVo> children = buildTree(allList, item.getId());
|
List<HqPmRepairCategoryVo> children = buildTree(allList, item.getId());
|
||||||
item.setChildren(children);
|
item.setChildren(children);
|
||||||
return item;
|
return item;
|
||||||
})
|
})
|
||||||
@@ -281,12 +283,12 @@ public class PmRepairCategoryServiceImpl implements IPmRepairCategoryService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean updateUsageCount(Long categoryId) {
|
public Boolean updateUsageCount(Long categoryId) {
|
||||||
PmRepairCategory category = baseMapper.selectById(categoryId);
|
HqPmRepairCategory category = baseMapper.selectById(categoryId);
|
||||||
if (category == null) {
|
if (category == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PmRepairCategory update = new PmRepairCategory();
|
HqPmRepairCategory update = new HqPmRepairCategory();
|
||||||
update.setId(categoryId);
|
update.setId(categoryId);
|
||||||
update.setUsageCount(category.getUsageCount() + 1);
|
update.setUsageCount(category.getUsageCount() + 1);
|
||||||
update.setLastUsedTime(new Date());
|
update.setLastUsedTime(new Date());
|
||||||
@@ -12,16 +12,16 @@ import cn.hutool.core.date.DateUtil;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.dromara.hq.domain.bo.PmRepairOrderBo;
|
import org.dromara.hq.domain.bo.HqPmRepairOrderBo;
|
||||||
import org.dromara.hq.domain.vo.PmRepairOrderVo;
|
import org.dromara.hq.domain.vo.HqPmRepairOrderVo;
|
||||||
import org.dromara.hq.domain.PmRepairOrder;
|
import org.dromara.hq.domain.HqPmRepairOrder;
|
||||||
import org.dromara.hq.domain.PmRepairProgress;
|
import org.dromara.hq.domain.HqPmRepairProgress;
|
||||||
import org.dromara.hq.domain.PmServiceEvaluation;
|
import org.dromara.hq.domain.HqPmServiceEvaluation;
|
||||||
import org.dromara.hq.mapper.PmRepairOrderMapper;
|
import org.dromara.hq.mapper.HqPmRepairOrderMapper;
|
||||||
import org.dromara.hq.mapper.PmRepairProgressMapper;
|
import org.dromara.hq.mapper.HqPmRepairProgressMapper;
|
||||||
import org.dromara.hq.mapper.PmServiceEvaluationMapper;
|
import org.dromara.hq.mapper.HqPmServiceEvaluationMapper;
|
||||||
import org.dromara.hq.service.IPmRepairOrderService;
|
import org.dromara.hq.service.IHqPmRepairOrderService;
|
||||||
import org.dromara.hq.service.IPmRepairCategoryService;
|
import org.dromara.hq.service.IHqPmRepairCategoryService;
|
||||||
import org.dromara.common.satoken.utils.LoginHelper;
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.service.UserService;
|
import org.dromara.common.core.service.UserService;
|
||||||
@@ -39,13 +39,13 @@ import java.util.Date;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Service
|
@Service
|
||||||
public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
public class HqPmRepairOrderServiceImpl implements IHqPmRepairOrderService {
|
||||||
|
|
||||||
private final PmRepairOrderMapper baseMapper;
|
private final HqPmRepairOrderMapper baseMapper;
|
||||||
private final PmRepairProgressMapper repairProgressMapper;
|
private final HqPmRepairProgressMapper repairProgressMapper;
|
||||||
private final IPmRepairCategoryService repairCategoryService;
|
private final IHqPmRepairCategoryService repairCategoryService;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final PmServiceEvaluationMapper serviceEvaluationMapper;
|
private final HqPmServiceEvaluationMapper serviceEvaluationMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报修工单
|
* 查询报修工单
|
||||||
@@ -54,8 +54,8 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
* @return 报修工单
|
* @return 报修工单
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PmRepairOrderVo queryById(Long id) {
|
public HqPmRepairOrderVo queryById(Long id) {
|
||||||
PmRepairOrderVo orderVo = baseMapper.selectVoById(id);
|
HqPmRepairOrderVo orderVo = baseMapper.selectVoById(id);
|
||||||
if (orderVo == null) {
|
if (orderVo == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
* @param orderVo 工单数据
|
* @param orderVo 工单数据
|
||||||
* @return 是否有权限
|
* @return 是否有权限
|
||||||
*/
|
*/
|
||||||
private boolean hasDataPermission(PmRepairOrderVo orderVo) {
|
private boolean hasDataPermission(HqPmRepairOrderVo orderVo) {
|
||||||
try {
|
try {
|
||||||
// 获取当前登录用户信息
|
// 获取当前登录用户信息
|
||||||
var loginUser = LoginHelper.getLoginUser();
|
var loginUser = LoginHelper.getLoginUser();
|
||||||
@@ -119,9 +119,9 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
* @return 报修工单分页列表
|
* @return 报修工单分页列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TableDataInfo<PmRepairOrderVo> queryPageList(PmRepairOrderBo bo, PageQuery pageQuery) {
|
public TableDataInfo<HqPmRepairOrderVo> queryPageList(HqPmRepairOrderBo bo, PageQuery pageQuery) {
|
||||||
LambdaQueryWrapper<PmRepairOrder> lqw = buildQueryWrapper(bo);
|
LambdaQueryWrapper<HqPmRepairOrder> lqw = buildQueryWrapper(bo);
|
||||||
Page<PmRepairOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
Page<HqPmRepairOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||||
return TableDataInfo.build(result);
|
return TableDataInfo.build(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,33 +132,34 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
* @return 报修工单列表
|
* @return 报修工单列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<PmRepairOrderVo> queryList(PmRepairOrderBo bo) {
|
public List<HqPmRepairOrderVo> queryList(HqPmRepairOrderBo bo) {
|
||||||
LambdaQueryWrapper<PmRepairOrder> lqw = buildQueryWrapper(bo);
|
LambdaQueryWrapper<HqPmRepairOrder> lqw = buildQueryWrapper(bo);
|
||||||
return baseMapper.selectVoList(lqw);
|
return baseMapper.selectVoList(lqw);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LambdaQueryWrapper<PmRepairOrder> buildQueryWrapper(PmRepairOrderBo bo) {
|
private LambdaQueryWrapper<HqPmRepairOrder> buildQueryWrapper(HqPmRepairOrderBo bo) {
|
||||||
LambdaQueryWrapper<PmRepairOrder> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairOrder> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.orderByDesc(PmRepairOrder::getCreateTime);
|
lqw.orderByDesc(HqPmRepairOrder::getCreateTime);
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), PmRepairOrder::getOrderNo, bo.getOrderNo());
|
lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), HqPmRepairOrder::getOrderNo, bo.getOrderNo());
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getTitle()), PmRepairOrder::getTitle, bo.getTitle());
|
lqw.like(StringUtils.isNotBlank(bo.getTitle()), HqPmRepairOrder::getTitle, bo.getTitle());
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getDescription()), PmRepairOrder::getDescription, bo.getDescription());
|
lqw.like(StringUtils.isNotBlank(bo.getDescription()), HqPmRepairOrder::getDescription, bo.getDescription());
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getRepairLocation()), PmRepairOrder::getRepairLocation,
|
lqw.like(StringUtils.isNotBlank(bo.getRepairLocation()), HqPmRepairOrder::getRepairLocation,
|
||||||
bo.getRepairLocation());
|
bo.getRepairLocation());
|
||||||
lqw.eq(bo.getCategoryId() != null, PmRepairOrder::getCategoryId, bo.getCategoryId());
|
lqw.eq(bo.getCategoryId() != null, HqPmRepairOrder::getCategoryId, bo.getCategoryId());
|
||||||
lqw.eq(bo.getPriorityLevel() != null, PmRepairOrder::getPriorityLevel, bo.getPriorityLevel());
|
lqw.eq(bo.getPriorityLevel() != null, HqPmRepairOrder::getPriorityLevel, bo.getPriorityLevel());
|
||||||
lqw.eq(bo.getReporterId() != null, PmRepairOrder::getReporterId, bo.getReporterId());
|
lqw.eq(bo.getReporterId() != null, HqPmRepairOrder::getReporterId, bo.getReporterId());
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getReporterName()), PmRepairOrder::getReporterName, bo.getReporterName());
|
lqw.like(StringUtils.isNotBlank(bo.getReporterName()), HqPmRepairOrder::getReporterName, bo.getReporterName());
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getReporterPhone()), PmRepairOrder::getReporterPhone, bo.getReporterPhone());
|
lqw.like(StringUtils.isNotBlank(bo.getReporterPhone()), HqPmRepairOrder::getReporterPhone,
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getOrderStatus()), PmRepairOrder::getOrderStatus, bo.getOrderStatus());
|
bo.getReporterPhone());
|
||||||
lqw.eq(bo.getAssigneeId() != null, PmRepairOrder::getAssigneeId, bo.getAssigneeId());
|
lqw.eq(StringUtils.isNotBlank(bo.getOrderStatus()), HqPmRepairOrder::getOrderStatus, bo.getOrderStatus());
|
||||||
lqw.like(StringUtils.isNotBlank(bo.getAssigneeName()), PmRepairOrder::getAssigneeName, bo.getAssigneeName());
|
lqw.eq(bo.getAssigneeId() != null, HqPmRepairOrder::getAssigneeId, bo.getAssigneeId());
|
||||||
|
lqw.like(StringUtils.isNotBlank(bo.getAssigneeName()), HqPmRepairOrder::getAssigneeName, bo.getAssigneeName());
|
||||||
|
|
||||||
// IN查询条件
|
// IN查询条件
|
||||||
lqw.in(CollUtil.isNotEmpty(bo.getOrderStatusIn()), PmRepairOrder::getOrderStatus, bo.getOrderStatusIn());
|
lqw.in(CollUtil.isNotEmpty(bo.getOrderStatusIn()), HqPmRepairOrder::getOrderStatus, bo.getOrderStatusIn());
|
||||||
lqw.in(CollUtil.isNotEmpty(bo.getCategoryIdIn()), PmRepairOrder::getCategoryId, bo.getCategoryIdIn());
|
lqw.in(CollUtil.isNotEmpty(bo.getCategoryIdIn()), HqPmRepairOrder::getCategoryId, bo.getCategoryIdIn());
|
||||||
lqw.in(CollUtil.isNotEmpty(bo.getReporterIdIn()), PmRepairOrder::getReporterId, bo.getReporterIdIn());
|
lqw.in(CollUtil.isNotEmpty(bo.getReporterIdIn()), HqPmRepairOrder::getReporterId, bo.getReporterIdIn());
|
||||||
lqw.in(CollUtil.isNotEmpty(bo.getAssigneeIdIn()), PmRepairOrder::getAssigneeId, bo.getAssigneeIdIn());
|
lqw.in(CollUtil.isNotEmpty(bo.getAssigneeIdIn()), HqPmRepairOrder::getAssigneeId, bo.getAssigneeIdIn());
|
||||||
|
|
||||||
// 添加数据权限控制
|
// 添加数据权限控制
|
||||||
addDataPermissionFilter(lqw);
|
addDataPermissionFilter(lqw);
|
||||||
@@ -171,14 +172,14 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
*
|
*
|
||||||
* @param lqw 查询条件构造器
|
* @param lqw 查询条件构造器
|
||||||
*/
|
*/
|
||||||
private void addDataPermissionFilter(LambdaQueryWrapper<PmRepairOrder> lqw) {
|
private void addDataPermissionFilter(LambdaQueryWrapper<HqPmRepairOrder> lqw) {
|
||||||
try {
|
try {
|
||||||
// 获取当前登录用户信息
|
// 获取当前登录用户信息
|
||||||
var loginUser = LoginHelper.getLoginUser();
|
var loginUser = LoginHelper.getLoginUser();
|
||||||
if (loginUser == null) {
|
if (loginUser == null) {
|
||||||
// 未登录用户不能查看任何数据
|
// 未登录用户不能查看任何数据
|
||||||
log.warn("未登录用户尝试访问报修订单数据");
|
log.warn("未登录用户尝试访问报修订单数据");
|
||||||
lqw.eq(PmRepairOrder::getId, 0L);
|
lqw.eq(HqPmRepairOrder::getId, 0L);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,16 +211,16 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
if (rolePermissions != null && rolePermissions.contains("maintenance_worker")) {
|
if (rolePermissions != null && rolePermissions.contains("maintenance_worker")) {
|
||||||
log.debug("当前用户[{}]为维修人员,只能查看自己创建或分配给自己的报修单", currentUserId);
|
log.debug("当前用户[{}]为维修人员,只能查看自己创建或分配给自己的报修单", currentUserId);
|
||||||
lqw.and(wrapper -> wrapper
|
lqw.and(wrapper -> wrapper
|
||||||
.eq(PmRepairOrder::getReporterId, currentUserId) // 自己创建的报修单
|
.eq(HqPmRepairOrder::getReporterId, currentUserId) // 自己创建的报修单
|
||||||
.or()
|
.or()
|
||||||
.eq(PmRepairOrder::getAssigneeId, currentUserId) // 分配给自己的报修单
|
.eq(HqPmRepairOrder::getAssigneeId, currentUserId) // 分配给自己的报修单
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其他用户:只能看见自己创建的报修单
|
// 其他用户:只能看见自己创建的报修单
|
||||||
log.debug("当前用户[{}]为普通用户,只能查看自己创建的报修单", currentUserId);
|
log.debug("当前用户[{}]为普通用户,只能查看自己创建的报修单", currentUserId);
|
||||||
lqw.eq(PmRepairOrder::getReporterId, currentUserId);
|
lqw.eq(HqPmRepairOrder::getReporterId, currentUserId);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("数据权限过滤异常: {}", e.getMessage(), e);
|
log.error("数据权限过滤异常: {}", e.getMessage(), e);
|
||||||
@@ -228,14 +229,14 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
Long currentUserId = LoginHelper.getUserId();
|
Long currentUserId = LoginHelper.getUserId();
|
||||||
if (currentUserId != null) {
|
if (currentUserId != null) {
|
||||||
log.warn("权限过滤异常,回退到只查看自己创建的报修单,用户ID: {}", currentUserId);
|
log.warn("权限过滤异常,回退到只查看自己创建的报修单,用户ID: {}", currentUserId);
|
||||||
lqw.eq(PmRepairOrder::getReporterId, currentUserId);
|
lqw.eq(HqPmRepairOrder::getReporterId, currentUserId);
|
||||||
} else {
|
} else {
|
||||||
log.error("无法获取当前用户ID,拒绝所有数据访问");
|
log.error("无法获取当前用户ID,拒绝所有数据访问");
|
||||||
lqw.eq(PmRepairOrder::getId, 0L);
|
lqw.eq(HqPmRepairOrder::getId, 0L);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("权限过滤回退逻辑也失败了: {}", ex.getMessage(), ex);
|
log.error("权限过滤回退逻辑也失败了: {}", ex.getMessage(), ex);
|
||||||
lqw.eq(PmRepairOrder::getId, 0L);
|
lqw.eq(HqPmRepairOrder::getId, 0L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,8 +248,8 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
* @return 是否新增成功
|
* @return 是否新增成功
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean insertByBo(PmRepairOrderBo bo) {
|
public Boolean insertByBo(HqPmRepairOrderBo bo) {
|
||||||
PmRepairOrder add = MapstructUtils.convert(bo, PmRepairOrder.class);
|
HqPmRepairOrder add = MapstructUtils.convert(bo, HqPmRepairOrder.class);
|
||||||
validEntityBeforeSave(add);
|
validEntityBeforeSave(add);
|
||||||
|
|
||||||
// 生成工单编号
|
// 生成工单编号
|
||||||
@@ -289,7 +290,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
*
|
*
|
||||||
* @param order 报修工单
|
* @param order 报修工单
|
||||||
*/
|
*/
|
||||||
private void fillReporterInfo(PmRepairOrder order) {
|
private void fillReporterInfo(HqPmRepairOrder order) {
|
||||||
try {
|
try {
|
||||||
// 获取当前登录用户信息
|
// 获取当前登录用户信息
|
||||||
Long userId = LoginHelper.getUserId();
|
Long userId = LoginHelper.getUserId();
|
||||||
@@ -335,8 +336,8 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
* @return 是否修改成功
|
* @return 是否修改成功
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean updateByBo(PmRepairOrderBo bo) {
|
public Boolean updateByBo(HqPmRepairOrderBo bo) {
|
||||||
PmRepairOrder update = MapstructUtils.convert(bo, PmRepairOrder.class);
|
HqPmRepairOrder update = MapstructUtils.convert(bo, HqPmRepairOrder.class);
|
||||||
validEntityBeforeSave(update);
|
validEntityBeforeSave(update);
|
||||||
return baseMapper.updateById(update) > 0;
|
return baseMapper.updateById(update) > 0;
|
||||||
}
|
}
|
||||||
@@ -344,13 +345,13 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
/**
|
/**
|
||||||
* 保存前的数据校验
|
* 保存前的数据校验
|
||||||
*/
|
*/
|
||||||
private void validEntityBeforeSave(PmRepairOrder entity) {
|
private void validEntityBeforeSave(HqPmRepairOrder entity) {
|
||||||
// 校验工单编号唯一性
|
// 校验工单编号唯一性
|
||||||
if (StringUtils.isNotBlank(entity.getOrderNo())) {
|
if (StringUtils.isNotBlank(entity.getOrderNo())) {
|
||||||
LambdaQueryWrapper<PmRepairOrder> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairOrder> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(PmRepairOrder::getOrderNo, entity.getOrderNo());
|
lqw.eq(HqPmRepairOrder::getOrderNo, entity.getOrderNo());
|
||||||
if (entity.getId() != null) {
|
if (entity.getId() != null) {
|
||||||
lqw.ne(PmRepairOrder::getId, entity.getId());
|
lqw.ne(HqPmRepairOrder::getId, entity.getId());
|
||||||
}
|
}
|
||||||
boolean exists = baseMapper.exists(lqw);
|
boolean exists = baseMapper.exists(lqw);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
@@ -371,7 +372,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
if (isValid) {
|
if (isValid) {
|
||||||
// 校验是否可以删除
|
// 校验是否可以删除
|
||||||
for (Long id : ids) {
|
for (Long id : ids) {
|
||||||
PmRepairOrder order = baseMapper.selectById(id);
|
HqPmRepairOrder order = baseMapper.selectById(id);
|
||||||
if (order != null && !"1".equals(order.getOrderStatus()) && !"9".equals(order.getOrderStatus())) {
|
if (order != null && !"1".equals(order.getOrderStatus()) && !"9".equals(order.getOrderStatus())) {
|
||||||
throw new ServiceException("只能删除待分派或已取消状态的工单");
|
throw new ServiceException("只能删除待分派或已取消状态的工单");
|
||||||
}
|
}
|
||||||
@@ -390,13 +391,13 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean assignOrder(Long orderId, Long assigneeId, String assignRemark) {
|
public Boolean assignOrder(Long orderId, Long assigneeId, String assignRemark) {
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据权限验证
|
// 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限操作该工单");
|
throw new ServiceException("无权限操作该工单");
|
||||||
}
|
}
|
||||||
@@ -427,7 +428,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新工单信息
|
// 更新工单信息
|
||||||
PmRepairOrder update = new PmRepairOrder();
|
HqPmRepairOrder update = new HqPmRepairOrder();
|
||||||
update.setId(orderId);
|
update.setId(orderId);
|
||||||
update.setAssigneeId(assigneeId);
|
update.setAssigneeId(assigneeId);
|
||||||
update.setAssigneeName(assigneeName); // 设置维修员姓名
|
update.setAssigneeName(assigneeName); // 设置维修员姓名
|
||||||
@@ -453,13 +454,13 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean startRepair(Long orderId) {
|
public Boolean startRepair(Long orderId) {
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据权限验证
|
// 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限操作该工单");
|
throw new ServiceException("无权限操作该工单");
|
||||||
}
|
}
|
||||||
@@ -468,7 +469,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
throw new ServiceException("只能开始已分派状态的工单");
|
throw new ServiceException("只能开始已分派状态的工单");
|
||||||
}
|
}
|
||||||
|
|
||||||
PmRepairOrder update = new PmRepairOrder();
|
HqPmRepairOrder update = new HqPmRepairOrder();
|
||||||
update.setId(orderId);
|
update.setId(orderId);
|
||||||
update.setStartTime(new Date());
|
update.setStartTime(new Date());
|
||||||
update.setOrderStatus("3"); // 进行中
|
update.setOrderStatus("3"); // 进行中
|
||||||
@@ -486,13 +487,13 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean finishRepair(Long orderId, String repairResult, String usedMaterials) {
|
public Boolean finishRepair(Long orderId, String repairResult, String usedMaterials) {
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据权限验证
|
// 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限操作该工单");
|
throw new ServiceException("无权限操作该工单");
|
||||||
}
|
}
|
||||||
@@ -510,7 +511,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
totalDuration = (int) (diff / 60000); // 转换为分钟
|
totalDuration = (int) (diff / 60000); // 转换为分钟
|
||||||
}
|
}
|
||||||
|
|
||||||
PmRepairOrder update = new PmRepairOrder();
|
HqPmRepairOrder update = new HqPmRepairOrder();
|
||||||
update.setId(orderId);
|
update.setId(orderId);
|
||||||
update.setFinishTime(finishTime);
|
update.setFinishTime(finishTime);
|
||||||
update.setTotalDuration(totalDuration);
|
update.setTotalDuration(totalDuration);
|
||||||
@@ -530,13 +531,13 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean cancelOrder(Long orderId, String cancelReason) {
|
public Boolean cancelOrder(Long orderId, String cancelReason) {
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据权限验证
|
// 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限操作该工单");
|
throw new ServiceException("无权限操作该工单");
|
||||||
}
|
}
|
||||||
@@ -546,7 +547,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
throw new ServiceException("已完成、已评价或已归档的工单不能取消");
|
throw new ServiceException("已完成、已评价或已归档的工单不能取消");
|
||||||
}
|
}
|
||||||
|
|
||||||
PmRepairOrder update = new PmRepairOrder();
|
HqPmRepairOrder update = new HqPmRepairOrder();
|
||||||
update.setId(orderId);
|
update.setId(orderId);
|
||||||
update.setCancelReason(cancelReason);
|
update.setCancelReason(cancelReason);
|
||||||
update.setOrderStatus("9"); // 已取消
|
update.setOrderStatus("9"); // 已取消
|
||||||
@@ -565,12 +566,12 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
String prefix = "RO" + dateStr;
|
String prefix = "RO" + dateStr;
|
||||||
|
|
||||||
// 查询当天最大序号
|
// 查询当天最大序号
|
||||||
LambdaQueryWrapper<PmRepairOrder> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairOrder> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.likeRight(PmRepairOrder::getOrderNo, prefix);
|
lqw.likeRight(HqPmRepairOrder::getOrderNo, prefix);
|
||||||
lqw.orderByDesc(PmRepairOrder::getOrderNo);
|
lqw.orderByDesc(HqPmRepairOrder::getOrderNo);
|
||||||
lqw.last("LIMIT 1");
|
lqw.last("LIMIT 1");
|
||||||
|
|
||||||
PmRepairOrder lastOrder = baseMapper.selectOne(lqw);
|
HqPmRepairOrder lastOrder = baseMapper.selectOne(lqw);
|
||||||
int sequence = 1;
|
int sequence = 1;
|
||||||
|
|
||||||
if (lastOrder != null && StringUtils.isNotBlank(lastOrder.getOrderNo())) {
|
if (lastOrder != null && StringUtils.isNotBlank(lastOrder.getOrderNo())) {
|
||||||
@@ -611,13 +612,13 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
@Override
|
@Override
|
||||||
public Boolean updateProgress(Long orderId, java.util.Map<String, Object> progressData) {
|
public Boolean updateProgress(Long orderId, java.util.Map<String, Object> progressData) {
|
||||||
// 1. 验证工单是否存在
|
// 1. 验证工单是否存在
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 数据权限验证
|
// 2. 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限操作该工单");
|
throw new ServiceException("无权限操作该工单");
|
||||||
}
|
}
|
||||||
@@ -635,7 +636,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
String currentUserName = loginUser.getUsername();
|
String currentUserName = loginUser.getUsername();
|
||||||
|
|
||||||
// 5. 创建进度记录
|
// 5. 创建进度记录
|
||||||
PmRepairProgress progress = new PmRepairProgress();
|
HqPmRepairProgress progress = new HqPmRepairProgress();
|
||||||
progress.setOrderId(orderId);
|
progress.setOrderId(orderId);
|
||||||
progress.setProgressType(String.valueOf(progressData.get("progressType")));
|
progress.setProgressType(String.valueOf(progressData.get("progressType")));
|
||||||
progress.setProgressStatus(String.valueOf(progressData.get("progressStatus")));
|
progress.setProgressStatus(String.valueOf(progressData.get("progressStatus")));
|
||||||
@@ -675,7 +676,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
boolean statusUpdated = false;
|
boolean statusUpdated = false;
|
||||||
if ("2".equals(order.getOrderStatus())) {
|
if ("2".equals(order.getOrderStatus())) {
|
||||||
// 如果是首次更新进度(从已分派状态),自动将状态改为进行中
|
// 如果是首次更新进度(从已分派状态),自动将状态改为进行中
|
||||||
PmRepairOrder statusUpdate = new PmRepairOrder();
|
HqPmRepairOrder statusUpdate = new HqPmRepairOrder();
|
||||||
statusUpdate.setId(orderId);
|
statusUpdate.setId(orderId);
|
||||||
statusUpdate.setStartTime(new Date());
|
statusUpdate.setStartTime(new Date());
|
||||||
statusUpdate.setOrderStatus("3"); // 进行中
|
statusUpdate.setOrderStatus("3"); // 进行中
|
||||||
@@ -707,27 +708,27 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
@Override
|
@Override
|
||||||
public List<java.util.Map<String, Object>> getRepairProgress(Long orderId) {
|
public List<java.util.Map<String, Object>> getRepairProgress(Long orderId) {
|
||||||
// 1. 验证工单是否存在
|
// 1. 验证工单是否存在
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 数据权限验证
|
// 2. 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限查看该工单进度");
|
throw new ServiceException("无权限查看该工单进度");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 查询进度记录
|
// 3. 查询进度记录
|
||||||
LambdaQueryWrapper<PmRepairProgress> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairProgress> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(PmRepairProgress::getOrderId, orderId);
|
lqw.eq(HqPmRepairProgress::getOrderId, orderId);
|
||||||
lqw.orderByAsc(PmRepairProgress::getOperationTime); // 按时间正序排列
|
lqw.orderByAsc(HqPmRepairProgress::getOperationTime); // 按时间正序排列
|
||||||
|
|
||||||
List<PmRepairProgress> progressList = repairProgressMapper.selectList(lqw);
|
List<HqPmRepairProgress> progressList = repairProgressMapper.selectList(lqw);
|
||||||
|
|
||||||
// 4. 转换为Map格式返回
|
// 4. 转换为Map格式返回
|
||||||
List<java.util.Map<String, Object>> result = new java.util.ArrayList<>();
|
List<java.util.Map<String, Object>> result = new java.util.ArrayList<>();
|
||||||
for (PmRepairProgress progress : progressList) {
|
for (HqPmRepairProgress progress : progressList) {
|
||||||
java.util.Map<String, Object> map = new java.util.HashMap<>();
|
java.util.Map<String, Object> map = new java.util.HashMap<>();
|
||||||
map.put("id", progress.getId());
|
map.put("id", progress.getId());
|
||||||
map.put("orderId", progress.getOrderId());
|
map.put("orderId", progress.getOrderId());
|
||||||
@@ -758,12 +759,12 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
private void updateProgressCount(Long orderId) {
|
private void updateProgressCount(Long orderId) {
|
||||||
try {
|
try {
|
||||||
// 查询该工单的进度记录总数
|
// 查询该工单的进度记录总数
|
||||||
LambdaQueryWrapper<PmRepairProgress> countLqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmRepairProgress> countLqw = Wrappers.lambdaQuery();
|
||||||
countLqw.eq(PmRepairProgress::getOrderId, orderId);
|
countLqw.eq(HqPmRepairProgress::getOrderId, orderId);
|
||||||
long progressCount = repairProgressMapper.selectCount(countLqw);
|
long progressCount = repairProgressMapper.selectCount(countLqw);
|
||||||
|
|
||||||
// 更新工单的进度计数
|
// 更新工单的进度计数
|
||||||
PmRepairOrder update = new PmRepairOrder();
|
HqPmRepairOrder update = new HqPmRepairOrder();
|
||||||
update.setId(orderId);
|
update.setId(orderId);
|
||||||
update.setProgressCount((int) progressCount);
|
update.setProgressCount((int) progressCount);
|
||||||
baseMapper.updateById(update);
|
baseMapper.updateById(update);
|
||||||
@@ -815,13 +816,13 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
@Override
|
@Override
|
||||||
public Boolean completeOrder(Long orderId, String repairResult, String usedMaterials, String followSuggestions) {
|
public Boolean completeOrder(Long orderId, String repairResult, String usedMaterials, String followSuggestions) {
|
||||||
// 1. 验证工单是否存在
|
// 1. 验证工单是否存在
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 数据权限验证
|
// 2. 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限操作该工单");
|
throw new ServiceException("无权限操作该工单");
|
||||||
}
|
}
|
||||||
@@ -841,7 +842,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 5. 更新工单状态和完成信息
|
// 5. 更新工单状态和完成信息
|
||||||
PmRepairOrder update = new PmRepairOrder();
|
HqPmRepairOrder update = new HqPmRepairOrder();
|
||||||
update.setId(orderId);
|
update.setId(orderId);
|
||||||
update.setFinishTime(finishTime);
|
update.setFinishTime(finishTime);
|
||||||
update.setTotalDuration(totalDuration);
|
update.setTotalDuration(totalDuration);
|
||||||
@@ -858,7 +859,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
// 6. 添加完成进度记录
|
// 6. 添加完成进度记录
|
||||||
try {
|
try {
|
||||||
var loginUser = LoginHelper.getLoginUser();
|
var loginUser = LoginHelper.getLoginUser();
|
||||||
PmRepairProgress completionProgress = new PmRepairProgress();
|
HqPmRepairProgress completionProgress = new HqPmRepairProgress();
|
||||||
completionProgress.setOrderId(orderId);
|
completionProgress.setOrderId(orderId);
|
||||||
completionProgress.setProgressType("6"); // 完成维修
|
completionProgress.setProgressType("6"); // 完成维修
|
||||||
completionProgress.setProgressStatus("维修已完成");
|
completionProgress.setProgressStatus("维修已完成");
|
||||||
@@ -902,13 +903,13 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
Long orderId = Long.valueOf(evaluationData.get("orderId").toString());
|
Long orderId = Long.valueOf(evaluationData.get("orderId").toString());
|
||||||
|
|
||||||
// 2. 验证工单是否存在
|
// 2. 验证工单是否存在
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 数据权限验证
|
// 3. 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限评价该工单");
|
throw new ServiceException("无权限评价该工单");
|
||||||
}
|
}
|
||||||
@@ -919,8 +920,8 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 5. 验证是否已经评价过
|
// 5. 验证是否已经评价过
|
||||||
LambdaQueryWrapper<PmServiceEvaluation> checkLqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmServiceEvaluation> checkLqw = Wrappers.lambdaQuery();
|
||||||
checkLqw.eq(PmServiceEvaluation::getOrderId, orderId);
|
checkLqw.eq(HqPmServiceEvaluation::getOrderId, orderId);
|
||||||
boolean hasEvaluated = serviceEvaluationMapper.exists(checkLqw);
|
boolean hasEvaluated = serviceEvaluationMapper.exists(checkLqw);
|
||||||
if (hasEvaluated) {
|
if (hasEvaluated) {
|
||||||
throw new ServiceException("该工单已经评价过,不能重复评价");
|
throw new ServiceException("该工单已经评价过,不能重复评价");
|
||||||
@@ -933,7 +934,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
|
|
||||||
// 7. 创建服务评价记录
|
// 7. 创建服务评价记录
|
||||||
Date evaluationTime = new Date();
|
Date evaluationTime = new Date();
|
||||||
PmServiceEvaluation evaluation = new PmServiceEvaluation();
|
HqPmServiceEvaluation evaluation = new HqPmServiceEvaluation();
|
||||||
evaluation.setOrderId(orderId);
|
evaluation.setOrderId(orderId);
|
||||||
evaluation.setEvaluatorId(currentUserId);
|
evaluation.setEvaluatorId(currentUserId);
|
||||||
evaluation.setEvaluatorName(currentUserName);
|
evaluation.setEvaluatorName(currentUserName);
|
||||||
@@ -989,7 +990,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 9. 更新工单状态为"已评价",并设置评价得分和评价时间
|
// 9. 更新工单状态为"已评价",并设置评价得分和评价时间
|
||||||
PmRepairOrder updateOrder = new PmRepairOrder();
|
HqPmRepairOrder updateOrder = new HqPmRepairOrder();
|
||||||
updateOrder.setId(orderId);
|
updateOrder.setId(orderId);
|
||||||
updateOrder.setOrderStatus("5"); // 已评价
|
updateOrder.setOrderStatus("5"); // 已评价
|
||||||
updateOrder.setEvaluationScore(evaluation.getOverallScore());
|
updateOrder.setEvaluationScore(evaluation.getOverallScore());
|
||||||
@@ -1002,7 +1003,7 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
|
|
||||||
// 10. 添加评价进度记录
|
// 10. 添加评价进度记录
|
||||||
try {
|
try {
|
||||||
PmRepairProgress evaluationProgress = new PmRepairProgress();
|
HqPmRepairProgress evaluationProgress = new HqPmRepairProgress();
|
||||||
evaluationProgress.setOrderId(orderId);
|
evaluationProgress.setOrderId(orderId);
|
||||||
evaluationProgress.setProgressType("7"); // 用户评价
|
evaluationProgress.setProgressType("7"); // 用户评价
|
||||||
evaluationProgress.setProgressStatus("用户已评价");
|
evaluationProgress.setProgressStatus("用户已评价");
|
||||||
@@ -1043,24 +1044,24 @@ public class PmRepairOrderServiceImpl implements IPmRepairOrderService {
|
|||||||
public java.util.Map<String, Object> getServiceEvaluation(Long orderId) {
|
public java.util.Map<String, Object> getServiceEvaluation(Long orderId) {
|
||||||
try {
|
try {
|
||||||
// 1. 验证工单是否存在
|
// 1. 验证工单是否存在
|
||||||
PmRepairOrder order = baseMapper.selectById(orderId);
|
HqPmRepairOrder order = baseMapper.selectById(orderId);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new ServiceException("工单不存在");
|
throw new ServiceException("工单不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 数据权限验证
|
// 2. 数据权限验证
|
||||||
PmRepairOrderVo orderVo = MapstructUtils.convert(order, PmRepairOrderVo.class);
|
HqPmRepairOrderVo orderVo = MapstructUtils.convert(order, HqPmRepairOrderVo.class);
|
||||||
if (!hasDataPermission(orderVo)) {
|
if (!hasDataPermission(orderVo)) {
|
||||||
throw new ServiceException("无权限查看该工单的评价");
|
throw new ServiceException("无权限查看该工单的评价");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 查询评价记录
|
// 3. 查询评价记录
|
||||||
LambdaQueryWrapper<PmServiceEvaluation> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<HqPmServiceEvaluation> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.eq(PmServiceEvaluation::getOrderId, orderId);
|
lqw.eq(HqPmServiceEvaluation::getOrderId, orderId);
|
||||||
lqw.orderByDesc(PmServiceEvaluation::getCreateTime);
|
lqw.orderByDesc(HqPmServiceEvaluation::getCreateTime);
|
||||||
lqw.last("LIMIT 1");
|
lqw.last("LIMIT 1");
|
||||||
|
|
||||||
PmServiceEvaluation evaluation = serviceEvaluationMapper.selectOne(lqw);
|
HqPmServiceEvaluation evaluation = serviceEvaluationMapper.selectOne(lqw);
|
||||||
if (evaluation == null) {
|
if (evaluation == null) {
|
||||||
throw new ServiceException("该工单还没有评价记录");
|
throw new ServiceException("该工单还没有评价记录");
|
||||||
}
|
}
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
<!DOCTYPE mapper
|
<!DOCTYPE mapper
|
||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="org.dromara.hq.mapper.PmRepairAttachmentMapper">
|
<mapper namespace="org.dromara.hq.mapper.HqPmRepairAttachmentMapper">
|
||||||
|
|
||||||
<resultMap type="org.dromara.hq.domain.PmRepairAttachment" id="PmRepairAttachmentResult">
|
<resultMap type="org.dromara.hq.domain.HqPmRepairAttachment" id="HqPmRepairAttachmentResult">
|
||||||
<result property="id" column="id" />
|
<result property="id" column="id" />
|
||||||
<result property="orderId" column="order_id" />
|
<result property="orderId" column="order_id" />
|
||||||
<result property="fileName" column="file_name" />
|
<result property="fileName" column="file_name" />
|
||||||
@@ -30,8 +30,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="deleted" column="deleted" />
|
<result property="deleted" column="deleted" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectPmRepairAttachmentVo">
|
<sql id="selectHqPmRepairAttachmentVo">
|
||||||
select id, order_id, file_name, file_path, file_size, file_type, file_extension, file_mime_type, upload_stage, uploader_id, uploader_name, thumbnail_path, duration, resolution, description, sort_order, tenant_id, create_dept, create_by, create_time, update_by, update_time, deleted from pm_repair_attachment
|
select id, order_id, file_name, file_path, file_size, file_type, file_extension, file_mime_type, upload_stage, uploader_id, uploader_name, thumbnail_path, duration, resolution, description, sort_order, tenant_id, create_dept, create_by, create_time, update_by, update_time, deleted from hq_pm_repair_attachment
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
<!DOCTYPE mapper
|
<!DOCTYPE mapper
|
||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="org.dromara.hq.mapper.PmRepairCategoryMapper">
|
<mapper namespace="org.dromara.hq.mapper.HqPmRepairCategoryMapper">
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<!DOCTYPE mapper
|
<!DOCTYPE mapper
|
||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="org.dromara.hq.mapper.PmRepairOrderMapper">
|
<mapper namespace="org.dromara.hq.mapper.HqPmRepairOrderMapper">
|
||||||
|
|
||||||
<!-- 查询拥有"维修人员"角色的用户列表 -->
|
<!-- 查询拥有"维修人员"角色的用户列表 -->
|
||||||
<select id="selectMaintenanceWorkers" resultType="java.util.Map">
|
<select id="selectMaintenanceWorkers" resultType="java.util.Map">
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
<!DOCTYPE mapper
|
<!DOCTYPE mapper
|
||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="org.dromara.hq.mapper.PmRepairProgressMapper">
|
<mapper namespace="org.dromara.hq.mapper.HqPmRepairProgressMapper">
|
||||||
|
|
||||||
<resultMap type="org.dromara.hq.domain.PmRepairProgress" id="PmRepairProgressResult">
|
<resultMap type="org.dromara.hq.domain.HqPmRepairProgress" id="HqPmRepairProgressResult">
|
||||||
<result property="id" column="id" />
|
<result property="id" column="id" />
|
||||||
<result property="orderId" column="order_id" />
|
<result property="orderId" column="order_id" />
|
||||||
<result property="progressType" column="progress_type" />
|
<result property="progressType" column="progress_type" />
|
||||||
@@ -32,8 +32,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="deleted" column="deleted" />
|
<result property="deleted" column="deleted" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectPmRepairProgressVo">
|
<sql id="selectHqPmRepairProgressVo">
|
||||||
select id, order_id, progress_type, progress_status, progress_detail, operator_id, operator_name, operator_role, location_info, gps_latitude, gps_longitude, operation_time, estimated_duration, attachment_ids, next_step, issues_encountered, materials_needed, remark, tenant_id, create_dept, create_by, create_time, update_by, update_time, deleted from pm_repair_progress
|
select id, order_id, progress_type, progress_status, progress_detail, operator_id, operator_name, operator_role, location_info, gps_latitude, gps_longitude, operation_time, estimated_duration, attachment_ids, next_step, issues_encountered, materials_needed, remark, tenant_id, create_dept, create_by, create_time, update_by, update_time, deleted from hq_pm_repair_progress
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.dromara.hq.mapper.HqPmServiceEvaluationMapper">
|
||||||
|
|
||||||
|
<resultMap type="org.dromara.hq.domain.HqPmServiceEvaluation" id="HqPmServiceEvaluationResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="orderId" column="order_id" />
|
||||||
|
<result property="evaluatorId" column="evaluator_id" />
|
||||||
|
<result property="evaluatorName" column="evaluator_name" />
|
||||||
|
<result property="evaluatedWorkerId" column="evaluated_worker_id" />
|
||||||
|
<result property="evaluatedWorkerName" column="evaluated_worker_name" />
|
||||||
|
<result property="overallScore" column="overall_score" />
|
||||||
|
<result property="qualityScore" column="quality_score" />
|
||||||
|
<result property="attitudeScore" column="attitude_score" />
|
||||||
|
<result property="responseSpeedScore" column="response_speed_score" />
|
||||||
|
<result property="communicationScore" column="communication_score" />
|
||||||
|
<result property="evaluationContent" column="evaluation_content" />
|
||||||
|
<result property="satisfactionLevel" column="satisfaction_level" />
|
||||||
|
<result property="isAnonymous" column="is_anonymous" />
|
||||||
|
<result property="isPublic" column="is_public" />
|
||||||
|
<result property="evaluationTime" column="evaluation_time" />
|
||||||
|
<result property="serviceStartTime" column="service_start_time" />
|
||||||
|
<result property="serviceEndTime" column="service_end_time" />
|
||||||
|
<result property="serviceDuration" column="service_duration" />
|
||||||
|
<result property="positiveTags" column="positive_tags" />
|
||||||
|
<result property="negativeTags" column="negative_tags" />
|
||||||
|
<result property="improvementSuggestions" column="improvement_suggestions" />
|
||||||
|
<result property="remark" column="remark" />
|
||||||
|
<result property="tenantId" column="tenant_id" />
|
||||||
|
<result property="createDept" column="create_dept" />
|
||||||
|
<result property="createBy" column="create_by" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateBy" column="update_by" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
<result property="deleted" column="deleted" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectHqPmServiceEvaluationVo">
|
||||||
|
select id, order_id, evaluator_id, evaluator_name, evaluated_worker_id, evaluated_worker_name, overall_score, quality_score, attitude_score, response_speed_score, communication_score, evaluation_content, satisfaction_level, is_anonymous, is_public, evaluation_time, service_start_time, service_end_time, service_duration, positive_tags, negative_tags, improvement_suggestions, remark, tenant_id, create_dept, create_by, create_time, update_by, update_time, deleted from hq_pm_service_evaluation
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -273,7 +273,7 @@ sequenceDiagram
|
|||||||
|
|
||||||
### 核心实体
|
### 核心实体
|
||||||
|
|
||||||
#### 报修单表 (pm_repair_order)
|
#### 报修单表 (hq_pm_repair_order)
|
||||||
|
|
||||||
| 字段名 | 类型 | 长度 | 非空 | 默认值 | 说明 |
|
| 字段名 | 类型 | 长度 | 非空 | 默认值 | 说明 |
|
||||||
| ------------------ | ------------ | ---- | ---- | ------- | ------------- |
|
| ------------------ | ------------ | ---- | ---- | ------- | ------------- |
|
||||||
@@ -303,7 +303,7 @@ sequenceDiagram
|
|||||||
| update_time | DATETIME | - | Y | - | 更新时间 |
|
| update_time | DATETIME | - | Y | - | 更新时间 |
|
||||||
| deleted | TINYINT | - | Y | 0 | 删除标记 |
|
| deleted | TINYINT | - | Y | 0 | 删除标记 |
|
||||||
|
|
||||||
#### 报修附件表 (pm_repair_attachment)
|
#### 报修附件表 (hq_pm_repair_attachment)
|
||||||
|
|
||||||
| 字段名 | 类型 | 长度 | 非空 | 默认值 | 说明 |
|
| 字段名 | 类型 | 长度 | 非空 | 默认值 | 说明 |
|
||||||
| --------------- | -------- | ---- | ---- | ------ | --------- |
|
| --------------- | -------- | ---- | ---- | ------ | --------- |
|
||||||
@@ -321,7 +321,7 @@ sequenceDiagram
|
|||||||
| update_time | DATETIME | - | Y | - | 更新时间 |
|
| update_time | DATETIME | - | Y | - | 更新时间 |
|
||||||
| deleted | TINYINT | - | Y | 0 | 删除标记 |
|
| deleted | TINYINT | - | Y | 0 | 删除标记 |
|
||||||
|
|
||||||
#### 维修进度记录表 (pm_repair_progress)
|
#### 维修进度记录表 (hq_pm_repair_progress)
|
||||||
|
|
||||||
| 字段名 | 类型 | 长度 | 非空 | 默认值 | 说明 |
|
| 字段名 | 类型 | 长度 | 非空 | 默认值 | 说明 |
|
||||||
| --------------- | -------- | ---- | ---- | ------ | ------------ |
|
| --------------- | -------- | ---- | ---- | ------ | ------------ |
|
||||||
@@ -341,12 +341,12 @@ sequenceDiagram
|
|||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
erDiagram
|
erDiagram
|
||||||
PM_REPAIR_ORDER ||--o{ PM_REPAIR_ATTACHMENT : "一对多"
|
HQ_PM_REPAIR_ORDER ||--o{ HQ_PM_REPAIR_ATTACHMENT : "一对多"
|
||||||
PM_REPAIR_ORDER ||--o{ PM_REPAIR_PROGRESS : "一对多"
|
HQ_PM_REPAIR_ORDER ||--o{ HQ_PM_REPAIR_PROGRESS : "一对多"
|
||||||
PM_REPAIR_ORDER }o--|| SYS_USER : "报修人"
|
HQ_PM_REPAIR_ORDER }o--|| SYS_USER : "报修人"
|
||||||
PM_REPAIR_ORDER }o--|| SYS_USER : "维修员"
|
HQ_PM_REPAIR_ORDER }o--|| SYS_USER : "维修员"
|
||||||
|
|
||||||
PM_REPAIR_ORDER {
|
HQ_PM_REPAIR_ORDER {
|
||||||
bigint id PK
|
bigint id PK
|
||||||
varchar order_no UK
|
varchar order_no UK
|
||||||
varchar title
|
varchar title
|
||||||
@@ -357,7 +357,7 @@ erDiagram
|
|||||||
datetime create_time
|
datetime create_time
|
||||||
}
|
}
|
||||||
|
|
||||||
PM_REPAIR_ATTACHMENT {
|
HQ_PM_REPAIR_ATTACHMENT {
|
||||||
bigint id PK
|
bigint id PK
|
||||||
bigint repair_order_id FK
|
bigint repair_order_id FK
|
||||||
varchar file_name
|
varchar file_name
|
||||||
@@ -365,7 +365,7 @@ erDiagram
|
|||||||
varchar file_type
|
varchar file_type
|
||||||
}
|
}
|
||||||
|
|
||||||
PM_REPAIR_PROGRESS {
|
HQ_PM_REPAIR_PROGRESS {
|
||||||
bigint id PK
|
bigint id PK
|
||||||
bigint repair_order_id FK
|
bigint repair_order_id FK
|
||||||
varchar status
|
varchar status
|
||||||
@@ -610,7 +610,7 @@ src/views/maintenance/
|
|||||||
|
|
||||||
#### 数据库命名规范
|
#### 数据库命名规范
|
||||||
|
|
||||||
- **表名**:pm_repair_order、pm_repair_attachment、pm_repair_progress
|
- **表名**:hq_pm_repair_order、hq_pm_repair_attachment、hq_pm_repair_progress
|
||||||
- **字段名**:repair_order_id、contact_name、urgency_level
|
- **字段名**:repair_order_id、contact_name、urgency_level
|
||||||
- **索引名**:idx_repair_order_status、idx_repair_order_assignee
|
- **索引名**:idx_repair_order_status、idx_repair_order_assignee
|
||||||
|
|
||||||
|
|||||||
@@ -31,40 +31,40 @@
|
|||||||
### 🗂️ 表结构清单
|
### 🗂️ 表结构清单
|
||||||
|
|
||||||
| 表名 | 中文名称 | 用途 | 关联关系 |
|
| 表名 | 中文名称 | 用途 | 关联关系 |
|
||||||
| ----------------------- | ---------- | ---------------------- | ------------ |
|
| --------------------------- | ---------- | ---------------------- | ------------ |
|
||||||
| `pm_repair_order` | 报修工单表 | 存储报修申请的核心信息 | 核心表 |
|
| `hq_pm_repair_order` | 报修工单表 | 存储报修申请的核心信息 | 核心表 |
|
||||||
| `pm_repair_attachment` | 报修附件表 | 存储报修相关附件文件 | 关联报修工单 |
|
| `hq_pm_repair_attachment` | 报修附件表 | 存储报修相关附件文件 | 关联报修工单 |
|
||||||
| `pm_repair_progress` | 维修进度表 | 记录维修过程状态变更 | 关联报修工单 |
|
| `hq_pm_repair_progress` | 维修进度表 | 记录维修过程状态变更 | 关联报修工单 |
|
||||||
| `pm_service_evaluation` | 服务评价表 | 存储用户服务质量评价 | 关联报修工单 |
|
| `hq_pm_service_evaluation` | 服务评价表 | 存储用户服务质量评价 | 关联报修工单 |
|
||||||
| `pm_repair_category` | 维修类型表 | 报修类型分类配置 | 字典表 |
|
| `hq_pm_repair_category` | 维修类型表 | 报修类型分类配置 | 字典表 |
|
||||||
| `pm_system_config` | 系统配置表 | 模块系统参数配置 | 配置表 |
|
| `hq_pm_system_config` | 系统配置表 | 模块系统参数配置 | 配置表 |
|
||||||
|
|
||||||
### 📈 数据流转关系
|
### 📈 数据流转关系
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph TD
|
graph TD
|
||||||
A[用户提交报修] --> B[pm_repair_order 报修工单]
|
A[用户提交报修] --> B[hq_pm_repair_order 报修工单]
|
||||||
B --> C[pm_repair_attachment 附件]
|
B --> C[hq_pm_repair_attachment 附件]
|
||||||
B --> D[pm_repair_progress 进度]
|
B --> D[hq_pm_repair_progress 进度]
|
||||||
B --> E[pm_service_evaluation 评价]
|
B --> E[hq_pm_service_evaluation 评价]
|
||||||
F[pm_repair_category 类型] --> B
|
F[hq_pm_repair_category 类型] --> B
|
||||||
G[pm_system_config 配置] --> B
|
G[hq_pm_system_config 配置] --> B
|
||||||
H[sys_user 系统用户] --> B
|
H[sys_user 系统用户] --> B
|
||||||
H --> D
|
H --> D
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🏗️ 详细表结构设计
|
## 🏗️ 详细表结构设计
|
||||||
|
|
||||||
### 1. 报修工单表 (pm_repair_order)
|
### 1. 报修工单表 (hq_pm_repair_order)
|
||||||
|
|
||||||
> **核心业务表**:存储报修申请的所有核心信息,是整个模块的数据中心
|
> **核心业务表**:存储报修申请的所有核心信息,是整个模块的数据中心
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_repair_order
|
-- Table structure for hq_pm_repair_order
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_repair_order`;
|
DROP TABLE IF EXISTS `hq_pm_repair_order`;
|
||||||
CREATE TABLE `pm_repair_order` (
|
CREATE TABLE `hq_pm_repair_order` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -82,7 +82,7 @@ CREATE TABLE `pm_repair_order` (
|
|||||||
`repair_location` varchar(200) NOT NULL COMMENT '报修地点',
|
`repair_location` varchar(200) NOT NULL COMMENT '报修地点',
|
||||||
|
|
||||||
-- 分类和紧急程度
|
-- 分类和紧急程度
|
||||||
`category_id` bigint(20) NOT NULL COMMENT '维修类型ID,关联pm_repair_category.id',
|
`category_id` bigint(20) NOT NULL COMMENT '维修类型ID,关联hq_pm_repair_category.id',
|
||||||
`priority_level` tinyint(1) NOT NULL DEFAULT 3 COMMENT '紧急程度:1-非常紧急,2-紧急,3-一般,4-不紧急,5-可延后',
|
`priority_level` tinyint(1) NOT NULL DEFAULT 3 COMMENT '紧急程度:1-非常紧急,2-紧急,3-一般,4-不紧急,5-可延后',
|
||||||
`expected_finish_time` datetime DEFAULT NULL COMMENT '期望完成时间',
|
`expected_finish_time` datetime DEFAULT NULL COMMENT '期望完成时间',
|
||||||
|
|
||||||
@@ -138,16 +138,16 @@ CREATE TABLE `pm_repair_order` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修工单表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修工单表';
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 报修附件表 (pm_repair_attachment)
|
### 2. 报修附件表 (hq_pm_repair_attachment)
|
||||||
|
|
||||||
> **附件管理表**:存储报修过程中上传的图片、视频等多媒体文件信息
|
> **附件管理表**:存储报修过程中上传的图片、视频等多媒体文件信息
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_repair_attachment
|
-- Table structure for hq_pm_repair_attachment
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_repair_attachment`;
|
DROP TABLE IF EXISTS `hq_pm_repair_attachment`;
|
||||||
CREATE TABLE `pm_repair_attachment` (
|
CREATE TABLE `hq_pm_repair_attachment` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -159,7 +159,7 @@ CREATE TABLE `pm_repair_attachment` (
|
|||||||
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
||||||
|
|
||||||
-- 关联信息
|
-- 关联信息
|
||||||
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联pm_repair_order.id',
|
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联hq_pm_repair_order.id',
|
||||||
|
|
||||||
-- 文件信息
|
-- 文件信息
|
||||||
`file_name` varchar(200) NOT NULL COMMENT '文件原始名称',
|
`file_name` varchar(200) NOT NULL COMMENT '文件原始名称',
|
||||||
@@ -196,16 +196,16 @@ CREATE TABLE `pm_repair_attachment` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修附件表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修附件表';
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 维修进度表 (pm_repair_progress)
|
### 3. 维修进度表 (hq_pm_repair_progress)
|
||||||
|
|
||||||
> **进度跟踪表**:记录维修过程中的每一个状态变更和进度更新
|
> **进度跟踪表**:记录维修过程中的每一个状态变更和进度更新
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_repair_progress
|
-- Table structure for hq_pm_repair_progress
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_repair_progress`;
|
DROP TABLE IF EXISTS `hq_pm_repair_progress`;
|
||||||
CREATE TABLE `pm_repair_progress` (
|
CREATE TABLE `hq_pm_repair_progress` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -217,7 +217,7 @@ CREATE TABLE `pm_repair_progress` (
|
|||||||
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
||||||
|
|
||||||
-- 关联信息
|
-- 关联信息
|
||||||
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联pm_repair_order.id',
|
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联hq_pm_repair_order.id',
|
||||||
|
|
||||||
-- 进度信息
|
-- 进度信息
|
||||||
`progress_type` char(1) NOT NULL COMMENT '进度类型:1-工单分派,2-接收确认,3-到达现场,4-开始维修,5-进度更新,6-完成维修,7-用户评价,8-工单归档,9-其他',
|
`progress_type` char(1) NOT NULL COMMENT '进度类型:1-工单分派,2-接收确认,3-到达现场,4-开始维修,5-进度更新,6-完成维修,7-用户评价,8-工单归档,9-其他',
|
||||||
@@ -260,16 +260,16 @@ CREATE TABLE `pm_repair_progress` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修进度表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修进度表';
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 服务评价表 (pm_service_evaluation)
|
### 4. 服务评价表 (hq_pm_service_evaluation)
|
||||||
|
|
||||||
> **评价反馈表**:存储用户对维修服务的多维度评价和反馈信息
|
> **评价反馈表**:存储用户对维修服务的多维度评价和反馈信息
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_service_evaluation
|
-- Table structure for hq_pm_service_evaluation
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_service_evaluation`;
|
DROP TABLE IF EXISTS `hq_pm_service_evaluation`;
|
||||||
CREATE TABLE `pm_service_evaluation` (
|
CREATE TABLE `hq_pm_service_evaluation` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -281,7 +281,7 @@ CREATE TABLE `pm_service_evaluation` (
|
|||||||
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
||||||
|
|
||||||
-- 关联信息
|
-- 关联信息
|
||||||
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联pm_repair_order.id',
|
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联hq_pm_repair_order.id',
|
||||||
`evaluator_id` bigint(20) NOT NULL COMMENT '评价人ID,关联sys_user.id',
|
`evaluator_id` bigint(20) NOT NULL COMMENT '评价人ID,关联sys_user.id',
|
||||||
`evaluator_name` varchar(50) NOT NULL COMMENT '评价人姓名',
|
`evaluator_name` varchar(50) NOT NULL COMMENT '评价人姓名',
|
||||||
`evaluated_worker_id` bigint(20) NOT NULL COMMENT '被评价维修员ID,关联sys_user.id',
|
`evaluated_worker_id` bigint(20) NOT NULL COMMENT '被评价维修员ID,关联sys_user.id',
|
||||||
@@ -330,16 +330,16 @@ CREATE TABLE `pm_service_evaluation` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='服务评价表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='服务评价表';
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. 维修类型表 (pm_repair_category)
|
### 5. 维修类型表 (hq_pm_repair_category)
|
||||||
|
|
||||||
> **分类字典表**:存储维修类型的分类信息,支持层级结构
|
> **分类字典表**:存储维修类型的分类信息,支持层级结构
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_repair_category
|
-- Table structure for hq_pm_repair_category
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_repair_category`;
|
DROP TABLE IF EXISTS `hq_pm_repair_category`;
|
||||||
CREATE TABLE `pm_repair_category` (
|
CREATE TABLE `hq_pm_repair_category` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -395,16 +395,16 @@ CREATE TABLE `pm_repair_category` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修类型表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修类型表';
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6. 系统配置表 (pm_system_config)
|
### 6. 系统配置表 (hq_pm_system_config)
|
||||||
|
|
||||||
> **配置管理表**:存储物业报修模块的系统参数和配置信息
|
> **配置管理表**:存储物业报修模块的系统参数和配置信息
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_system_config
|
-- Table structure for hq_pm_system_config
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_system_config`;
|
DROP TABLE IF EXISTS `hq_pm_system_config`;
|
||||||
CREATE TABLE `pm_system_config` (
|
CREATE TABLE `hq_pm_system_config` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -510,16 +510,16 @@ CREATE TABLE `pm_system_config` (
|
|||||||
```sql
|
```sql
|
||||||
-- 报修工单表的核心查询索引
|
-- 报修工单表的核心查询索引
|
||||||
-- 1. 按状态和时间查询(管理员常用)
|
-- 1. 按状态和时间查询(管理员常用)
|
||||||
CREATE INDEX idx_status_time ON pm_repair_order (order_status, create_time);
|
CREATE INDEX idx_status_time ON hq_pm_repair_order (order_status, create_time);
|
||||||
|
|
||||||
-- 2. 按维修员查询其工单(维修员常用)
|
-- 2. 按维修员查询其工单(维修员常用)
|
||||||
CREATE INDEX idx_assignee_status ON pm_repair_order (assignee_id, order_status);
|
CREATE INDEX idx_assignee_status ON hq_pm_repair_order (assignee_id, order_status);
|
||||||
|
|
||||||
-- 3. 按报修人查询(用户查看自己的工单)
|
-- 3. 按报修人查询(用户查看自己的工单)
|
||||||
CREATE INDEX idx_reporter_time ON pm_repair_order (reporter_id, create_time);
|
CREATE INDEX idx_reporter_time ON hq_pm_repair_order (reporter_id, create_time);
|
||||||
|
|
||||||
-- 4. 按紧急程度和分派时间查询(工单分派)
|
-- 4. 按紧急程度和分派时间查询(工单分派)
|
||||||
CREATE INDEX idx_priority_assign ON pm_repair_order (priority_level, assign_time);
|
CREATE INDEX idx_priority_assign ON hq_pm_repair_order (priority_level, assign_time);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 附件查询索引
|
### 2. 附件查询索引
|
||||||
@@ -527,10 +527,10 @@ CREATE INDEX idx_priority_assign ON pm_repair_order (priority_level, assign_time
|
|||||||
```sql
|
```sql
|
||||||
-- 附件表的查询索引
|
-- 附件表的查询索引
|
||||||
-- 1. 按工单查询附件(最常用)
|
-- 1. 按工单查询附件(最常用)
|
||||||
CREATE INDEX idx_order_stage ON pm_repair_attachment (order_id, upload_stage);
|
CREATE INDEX idx_order_stage ON hq_pm_repair_attachment (order_id, upload_stage);
|
||||||
|
|
||||||
-- 2. 按上传者查询附件
|
-- 2. 按上传者查询附件
|
||||||
CREATE INDEX idx_uploader_time ON pm_repair_attachment (uploader_id, create_time);
|
CREATE INDEX idx_uploader_time ON hq_pm_repair_attachment (uploader_id, create_time);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 进度查询索引
|
### 3. 进度查询索引
|
||||||
@@ -538,10 +538,10 @@ CREATE INDEX idx_uploader_time ON pm_repair_attachment (uploader_id, create_time
|
|||||||
```sql
|
```sql
|
||||||
-- 进度表的查询索引
|
-- 进度表的查询索引
|
||||||
-- 1. 按工单查询进度(时间线显示)
|
-- 1. 按工单查询进度(时间线显示)
|
||||||
CREATE INDEX idx_order_operation_time ON pm_repair_progress (order_id, operation_time);
|
CREATE INDEX idx_order_operation_time ON hq_pm_repair_progress (order_id, operation_time);
|
||||||
|
|
||||||
-- 2. 按操作人查询进度
|
-- 2. 按操作人查询进度
|
||||||
CREATE INDEX idx_operator_time ON pm_repair_progress (operator_id, operation_time);
|
CREATE INDEX idx_operator_time ON hq_pm_repair_progress (operator_id, operation_time);
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📊 数据存储预估
|
## 📊 数据存储预估
|
||||||
@@ -549,13 +549,13 @@ CREATE INDEX idx_operator_time ON pm_repair_progress (operator_id, operation_tim
|
|||||||
### 表数据量预估
|
### 表数据量预估
|
||||||
|
|
||||||
| 表名 | 日增长量 | 年数据量 | 存储空间预估 |
|
| 表名 | 日增长量 | 年数据量 | 存储空间预估 |
|
||||||
| --------------------- | ---------- | ------------ | ------------ |
|
| --------------------------- | ---------- | ------------ | ------------ |
|
||||||
| pm_repair_order | 50-100 条 | 2-4 万条 | 50-100MB |
|
| hq_pm_repair_order | 50-100 条 | 2-4 万条 | 50-100MB |
|
||||||
| pm_repair_attachment | 200-400 条 | 8-16 万条 | 100-200MB |
|
| hq_pm_repair_attachment | 200-400 条 | 8-16 万条 | 100-200MB |
|
||||||
| pm_repair_progress | 300-600 条 | 12-24 万条 | 150-300MB |
|
| hq_pm_repair_progress | 300-600 条 | 12-24 万条 | 150-300MB |
|
||||||
| pm_service_evaluation | 40-80 条 | 1.6-3.2 万条 | 20-40MB |
|
| hq_pm_service_evaluation | 40-80 条 | 1.6-3.2 万条 | 20-40MB |
|
||||||
| pm_repair_category | 0-5 条 | 100-200 条 | <1MB |
|
| hq_pm_repair_category | 0-5 条 | 100-200 条 | <1MB |
|
||||||
| pm_system_config | 0-2 条 | 50-100 条 | <1MB |
|
| hq_pm_system_config | 0-2 条 | 50-100 条 | <1MB |
|
||||||
|
|
||||||
### 存储优化建议
|
### 存储优化建议
|
||||||
|
|
||||||
@@ -570,7 +570,7 @@ CREATE INDEX idx_operator_time ON pm_repair_progress (operator_id, operation_tim
|
|||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- 插入基础维修类型分类
|
-- 插入基础维修类型分类
|
||||||
INSERT INTO `pm_repair_category` (
|
INSERT INTO `hq_pm_repair_category` (
|
||||||
`id`, `tenant_id`, `category_name`, `category_code`, `category_description`,
|
`id`, `tenant_id`, `category_name`, `category_code`, `category_description`,
|
||||||
`parent_id`, `level_depth`, `required_skills`, `skill_level`,
|
`parent_id`, `level_depth`, `required_skills`, `skill_level`,
|
||||||
`estimated_duration`, `icon_url`, `color_code`, `sort_order`, `status`,
|
`estimated_duration`, `icon_url`, `color_code`, `sort_order`, `status`,
|
||||||
@@ -588,7 +588,7 @@ INSERT INTO `pm_repair_category` (
|
|||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- 插入系统配置参数
|
-- 插入系统配置参数
|
||||||
INSERT INTO `pm_system_config` (
|
INSERT INTO `hq_pm_system_config` (
|
||||||
`id`, `tenant_id`, `config_key`, `config_value`, `config_type`, `config_group`,
|
`id`, `tenant_id`, `config_key`, `config_value`, `config_type`, `config_group`,
|
||||||
`config_name`, `config_description`, `default_value`, `is_system`, `is_editable`,
|
`config_name`, `config_description`, `default_value`, `is_system`, `is_editable`,
|
||||||
`sort_order`, `status`, `create_time`, `create_by`
|
`sort_order`, `status`, `create_time`, `create_by`
|
||||||
|
|||||||
@@ -285,6 +285,7 @@ private Date updateTime;
|
|||||||
**文档版本**: v1.0
|
**文档版本**: v1.0
|
||||||
**下次评审**: 根据实际使用情况优化
|
**下次评审**: 根据实际使用情况优化
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
---
|
---
|
||||||
|
|
||||||
# 代码调整记录 - 2025-01-09 - wuzilong
|
# 代码调整记录 - 2025-01-09 - wuzilong
|
||||||
@@ -619,3 +620,450 @@ private Date updateTime;
|
|||||||
|
|
||||||
**📝 维护人员**: wuzilong
|
**📝 维护人员**: wuzilong
|
||||||
**📅 更新时间**: 2025-01-09 23:50:00
|
**📅 更新时间**: 2025-01-09 23:50:00
|
||||||
|
=======
|
||||||
|
## 报告厅预约时间冲突检查功能优化
|
||||||
|
|
||||||
|
### 变更时间
|
||||||
|
2025-01-09 14:30:00
|
||||||
|
|
||||||
|
### 变更内容
|
||||||
|
1. 新增后端时间冲突检查接口
|
||||||
|
- 添加 `/hq/hallReservation/checkTimeConflict` 接口
|
||||||
|
- 实现精确的时间冲突检查逻辑
|
||||||
|
- 支持排除当前预约记录的冲突检查
|
||||||
|
|
||||||
|
2. 前端代码优化
|
||||||
|
- 将时间冲突检查逻辑从前端移至后端
|
||||||
|
- 添加相关API调用和类型定义
|
||||||
|
- 优化界面显示效果
|
||||||
|
|
||||||
|
3. API文档更新
|
||||||
|
- 在场地预约管理API文档中添加时间冲突检查接口说明
|
||||||
|
- 完善接口参数和响应说明
|
||||||
|
- 添加使用示例
|
||||||
|
|
||||||
|
### 涉及文件
|
||||||
|
1. 后端文件:
|
||||||
|
- `HallReservationController.java`
|
||||||
|
- `IHallReservationService.java`
|
||||||
|
- `HallReservationServiceImpl.java`
|
||||||
|
- `HallReservationTimeCheckDTO.java`
|
||||||
|
|
||||||
|
2. 前端文件:
|
||||||
|
- `web/src/api/hq/hallAudit/index.ts`
|
||||||
|
- `web/src/api/hq/hallAudit/types.ts`
|
||||||
|
- `web/src/views/hq/hallAudit/index.vue`
|
||||||
|
|
||||||
|
3. 文档文件:
|
||||||
|
- `docs/开发文档/API/场地预约管理API.md`
|
||||||
|
|
||||||
|
### 变更原因
|
||||||
|
1. 提高时间冲突检查的准确性
|
||||||
|
2. 优化代码结构,将业务逻辑移至后端
|
||||||
|
3. 提升系统性能和可维护性
|
||||||
|
|
||||||
|
### 测试验证
|
||||||
|
1. 接口测试
|
||||||
|
- [x] 正常时间段检查
|
||||||
|
- [x] 边界时间检查
|
||||||
|
- [x] 排除当前记录的检查
|
||||||
|
- [x] 错误参数处理
|
||||||
|
|
||||||
|
2. 前端功能测试
|
||||||
|
- [x] 审核建议显示
|
||||||
|
- [x] 时间冲突提示
|
||||||
|
- [x] 界面交互体验
|
||||||
|
|
||||||
|
### 注意事项
|
||||||
|
1. 时间格式统一使用:yyyy-MM-dd HH:mm:ss
|
||||||
|
2. 注意处理时区问题
|
||||||
|
3. 确保前端传参格式正确
|
||||||
|
|
||||||
|
### 后续计划
|
||||||
|
1. 添加批量时间冲突检查功能
|
||||||
|
2. 优化冲突提示的展示方式
|
||||||
|
3. 考虑添加预约时间段可视化展示
|
||||||
|
|
||||||
|
### 相关文档
|
||||||
|
- [场地预约管理API文档](../开发文档/API/场地预约管理API.md)
|
||||||
|
- [报告厅预约系统设计说明](../需求文档/后勤报告厅预约需求/简化版报告厅预约系统设计说明.md)
|
||||||
|
|
||||||
|
# 代码调整记录 2025-01-09
|
||||||
|
|
||||||
|
## 报告厅预约时间冲突检查功能迁移
|
||||||
|
|
||||||
|
### 变更时间
|
||||||
|
2025-01-09 15:30:00
|
||||||
|
|
||||||
|
### 变更内容
|
||||||
|
1. 代码迁移
|
||||||
|
- 将代码从 `com.ruoyi.hq` 迁移到 `org.dromara.hq`
|
||||||
|
- 按照新的项目规范重构代码结构
|
||||||
|
- 完善实体类和VO类的定义
|
||||||
|
|
||||||
|
2. 功能优化
|
||||||
|
- 优化时间冲突检查逻辑
|
||||||
|
- 完善参数校验
|
||||||
|
- 规范化异常处理
|
||||||
|
- 添加详细的注释说明
|
||||||
|
|
||||||
|
3. 规范遵循
|
||||||
|
- 遵循新的包结构规范
|
||||||
|
- 实现标准的实体类继承关系
|
||||||
|
- 完善API文档
|
||||||
|
|
||||||
|
### 涉及文件
|
||||||
|
1. 后端文件:
|
||||||
|
- `org.dromara.hq.domain.HallReservation`
|
||||||
|
- `org.dromara.hq.domain.vo.HallReservationVO`
|
||||||
|
- `org.dromara.hq.domain.dto.HallReservationTimeCheckDTO`
|
||||||
|
- `org.dromara.hq.mapper.HallReservationMapper`
|
||||||
|
- `org.dromara.hq.service.IHallReservationService`
|
||||||
|
- `org.dromara.hq.service.impl.HallReservationServiceImpl`
|
||||||
|
- `org.dromara.hq.controller.HallReservationController`
|
||||||
|
|
||||||
|
2. 文档文件:
|
||||||
|
- `docs/开发文档/API/场地预约管理API.md`
|
||||||
|
- `docs/变更管理/code-adjust-record-2025-01-09-wuzilong.md`
|
||||||
|
|
||||||
|
### 变更原因
|
||||||
|
1. 遵循新的项目规范要求
|
||||||
|
2. 优化代码结构和可维护性
|
||||||
|
3. 统一项目包命名规范
|
||||||
|
|
||||||
|
### 测试验证
|
||||||
|
1. 功能测试
|
||||||
|
- [x] 时间冲突检查
|
||||||
|
- [x] 参数校验
|
||||||
|
- [x] 异常处理
|
||||||
|
|
||||||
|
2. 规范检查
|
||||||
|
- [x] 包结构符合规范
|
||||||
|
- [x] 类名和方法名符合规范
|
||||||
|
- [x] 注释完整规范
|
||||||
|
|
||||||
|
### 遗留问题
|
||||||
|
1. Excel导出相关的注解依赖需要确认
|
||||||
|
2. 部分Mapper方法可能需要优化
|
||||||
|
|
||||||
|
### 后续计划
|
||||||
|
1. 完善Excel导出功能
|
||||||
|
2. 优化查询性能
|
||||||
|
3. 添加缓存支持
|
||||||
|
|
||||||
|
### 备注
|
||||||
|
代码迁移后进行了全面的功能测试,确保所有功能正常运行。如有问题及时反馈。
|
||||||
|
|
||||||
|
# 代码调整记录 2025-01-09
|
||||||
|
|
||||||
|
## 报告厅预约模块代码规范优化
|
||||||
|
|
||||||
|
### 1. 类名规范调整
|
||||||
|
- 添加模块前缀 `Hq`
|
||||||
|
- 将 `DTO` 改为 `Bo`
|
||||||
|
- 涉及文件:
|
||||||
|
- `HallReservationTimeCheckDTO.java` → `HqHallReservationTimeCheckBo.java`
|
||||||
|
- 相关的Service、Controller等引用
|
||||||
|
|
||||||
|
### 2. 代码结构优化
|
||||||
|
- 创建标准的VO类:`HallReservationTimeCheckVO`
|
||||||
|
- 优化Mapper接口和XML映射文件
|
||||||
|
- 完善了时间冲突检查的业务逻辑
|
||||||
|
|
||||||
|
### 3. 前端代码同步更新
|
||||||
|
- 更新API接口定义
|
||||||
|
- 添加TypeScript类型声明
|
||||||
|
- 优化接口返回值处理
|
||||||
|
|
||||||
|
### 4. 文档更新
|
||||||
|
- 更新API文档
|
||||||
|
- 添加变更记录
|
||||||
|
|
||||||
|
## 遗留问题
|
||||||
|
- [ ] 需要进行完整的功能测试
|
||||||
|
- [ ] 可能需要补充单元测试用例
|
||||||
|
|
||||||
|
## 后续计划
|
||||||
|
- [ ] 继续优化其他模块的代码规范
|
||||||
|
- [ ] 完善测试覆盖率
|
||||||
|
|
||||||
|
## 变更人
|
||||||
|
- 作者:wuzilong
|
||||||
|
- 日期:2025-01-09
|
||||||
|
- 时间:15:30:00
|
||||||
|
|
||||||
|
# 代码调整记录 - 2025-01-09 - wuzilong
|
||||||
|
|
||||||
|
## 📋 本日工作总览
|
||||||
|
|
||||||
|
**工作重点**: 为报告厅审核建议功能添加后端接口支持
|
||||||
|
|
||||||
|
**工作时间**: 2025-01-09 14:00:00 - 17:00:00
|
||||||
|
|
||||||
|
**参与人员**: wuzilong
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 主要变更内容
|
||||||
|
|
||||||
|
### 1. 📝 VO类基础字段规范修复
|
||||||
|
|
||||||
|
**时间**: 2025-01-09 16:00:00
|
||||||
|
**文件**: `backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/domain/vo/HqHallReservationVo.java`
|
||||||
|
|
||||||
|
**变更内容**:
|
||||||
|
- ✅ 添加缺失的基础字段(符合强制性规范)
|
||||||
|
- ✅ 包含createBy、createTime、updateBy、updateTime四个字段
|
||||||
|
- ✅ 时间字段使用`@JsonFormat`注解格式化
|
||||||
|
- ✅ 创建时间字段支持Excel导出
|
||||||
|
|
||||||
|
**技术细节**:
|
||||||
|
```java
|
||||||
|
// 添加的基础字段
|
||||||
|
private Long createBy; // 创建者
|
||||||
|
private Date createTime; // 创建时间
|
||||||
|
private Long updateBy; // 更新者
|
||||||
|
private Date updateTime; // 更新时间
|
||||||
|
```
|
||||||
|
|
||||||
|
**符合规范**: `.cursor/cursorrules-backend.md` → "VO类基础字段规范(强制性)"
|
||||||
|
|
||||||
|
### 2. 🆕 新增业务对象类
|
||||||
|
|
||||||
|
**时间**: 2025-01-09 16:15:00
|
||||||
|
|
||||||
|
#### A. 时间冲突检查BO类
|
||||||
|
**文件**: `backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/domain/bo/HqHallTimeCheckBo.java`
|
||||||
|
|
||||||
|
**功能**: 接收前端时间冲突检查请求参数
|
||||||
|
- ✅ 报告厅ID(必填)
|
||||||
|
- ✅ 开始时间/结束时间(必填,JSON格式化)
|
||||||
|
- ✅ 排除预约ID(可选,用于编辑时排除自身)
|
||||||
|
- ✅ 完整的参数验证注解
|
||||||
|
|
||||||
|
#### B. 时间冲突检查结果VO类
|
||||||
|
**文件**: `backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/domain/vo/HqHallTimeCheckVo.java`
|
||||||
|
|
||||||
|
**功能**: 返回时间冲突检查结果
|
||||||
|
- ✅ 是否存在冲突(Boolean)
|
||||||
|
- ✅ 冲突预约列表(List<HqHallReservationVo>)
|
||||||
|
- ✅ 冲突描述信息(String)
|
||||||
|
- ✅ 静态工厂方法:noConflict()、hasConflict()
|
||||||
|
|
||||||
|
### 3. 🔧 服务层接口扩展
|
||||||
|
|
||||||
|
**时间**: 2025-01-09 16:25:00
|
||||||
|
|
||||||
|
#### A. Service接口
|
||||||
|
**文件**: `backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/IHqHallReservationService.java`
|
||||||
|
|
||||||
|
**新增方法**:
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 检查报告厅时间冲突
|
||||||
|
* @param timeCheckBo 时间检查参数
|
||||||
|
* @return 时间冲突检查结果
|
||||||
|
*/
|
||||||
|
HqHallTimeCheckVo checkTimeConflict(HqHallTimeCheckBo timeCheckBo);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### B. Service实现类
|
||||||
|
**文件**: `backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqHallReservationServiceImpl.java`
|
||||||
|
|
||||||
|
**核心业务逻辑**:
|
||||||
|
- ✅ 智能时间重叠检测算法
|
||||||
|
- ✅ 只检查已批准状态(status='1')的预约
|
||||||
|
- ✅ 支持排除指定预约ID(编辑场景)
|
||||||
|
- ✅ 详细的日志记录
|
||||||
|
- ✅ 构建标准化返回结果
|
||||||
|
|
||||||
|
**时间冲突判定规则**:
|
||||||
|
```sql
|
||||||
|
-- 时间重叠条件:
|
||||||
|
-- startTime < existingEndTime AND endTime > existingStartTime
|
||||||
|
lqw.and(wrapper -> wrapper
|
||||||
|
.lt(HqHallReservation::getStartTime, timeCheckBo.getEndTime())
|
||||||
|
.gt(HqHallReservation::getEndTime, timeCheckBo.getStartTime())
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 🌐 Controller层API接口
|
||||||
|
|
||||||
|
**时间**: 2025-01-09 16:35:00
|
||||||
|
**文件**: `backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/controller/HqHallReservationController.java`
|
||||||
|
|
||||||
|
**新增接口**:
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 检查报告厅时间冲突
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("hq:hallReservation:query")
|
||||||
|
@PostMapping("/checkTimeConflict")
|
||||||
|
public R<HqHallTimeCheckVo> checkTimeConflict(@Validated @RequestBody HqHallTimeCheckBo timeCheckBo)
|
||||||
|
```
|
||||||
|
|
||||||
|
**接口特点**:
|
||||||
|
- ✅ 使用现有查询权限(hq:hallReservation:query)
|
||||||
|
- ✅ POST方式,支持复杂参数传递
|
||||||
|
- ✅ 完整的参数验证(@Validated)
|
||||||
|
- ✅ 标准R类型响应格式
|
||||||
|
|
||||||
|
### 5. 🔐 权限配置管理
|
||||||
|
|
||||||
|
**时间**: 2025-01-09 16:40:00
|
||||||
|
**文件**: `docs/设计文档/database/hall-audit-permission.sql`
|
||||||
|
|
||||||
|
**权限配置内容**:
|
||||||
|
- ✅ 添加报告厅审核权限(hq:hallReservation:audit)
|
||||||
|
- ✅ 为admin角色分配审核权限
|
||||||
|
- ✅ 使用UPSERT逻辑,支持重复执行
|
||||||
|
- ✅ 包含验证和查询SQL
|
||||||
|
|
||||||
|
**权限ID**: 12216 - 报告厅预约审核权限
|
||||||
|
|
||||||
|
### 6. 📚 API文档完善
|
||||||
|
|
||||||
|
**时间**: 2025-01-09 16:50:00
|
||||||
|
|
||||||
|
#### A. 新建专门API文档
|
||||||
|
**文件**: `docs/开发文档/API/报告厅预约审核API.md`
|
||||||
|
|
||||||
|
**文档特点**:
|
||||||
|
- ✅ 完整的接口说明(400+行)
|
||||||
|
- ✅ 详细的请求/响应示例
|
||||||
|
- ✅ 时间冲突检查算法说明
|
||||||
|
- ✅ 权限配置说明
|
||||||
|
- ✅ 开发建议和常见问题
|
||||||
|
- ✅ 完整的版本记录
|
||||||
|
|
||||||
|
**核心章节**:
|
||||||
|
- 🔍 时间冲突检查API
|
||||||
|
- ✅ 报告厅预约审核API
|
||||||
|
- 📊 数据字典和权限配置
|
||||||
|
- 💡 开发建议和问题排查
|
||||||
|
|
||||||
|
#### B. 更新API文档总览
|
||||||
|
**文件**: `docs/开发文档/API/API文档总览.md`
|
||||||
|
|
||||||
|
**更新内容**:
|
||||||
|
- ✅ 添加报告厅预约审核API到分模块文档表
|
||||||
|
- ✅ 快速导航增加报告厅审核相关链接
|
||||||
|
- ✅ 完善API文档架构说明
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 技术实现亮点
|
||||||
|
|
||||||
|
### 1. 🧠 智能时间冲突检测
|
||||||
|
- **精确算法**: 使用数学逻辑准确判定时间段重叠
|
||||||
|
- **状态过滤**: 只检查已批准的预约,避免误判
|
||||||
|
- **灵活排除**: 支持编辑场景下排除自身记录
|
||||||
|
- **性能优化**: 数据库层面进行时间比较,减少数据传输
|
||||||
|
|
||||||
|
### 2. 📋 标准化VO类设计
|
||||||
|
- **规范遵循**: 严格按照cursorrules-backend.md强制性规范
|
||||||
|
- **字段完整**: 包含所有必需的基础字段
|
||||||
|
- **JSON格式化**: 时间字段统一格式化
|
||||||
|
- **兼容性保证**: 支持MyBatis-Plus自动查询和自定义SQL
|
||||||
|
|
||||||
|
### 3. 🔒 完整权限控制
|
||||||
|
- **接口级权限**: 每个API都有对应权限验证
|
||||||
|
- **权限复用**: checkTimeConflict复用查询权限
|
||||||
|
- **SQL配置**: 提供完整的权限配置脚本
|
||||||
|
- **角色分配**: 自动为admin角色分配权限
|
||||||
|
|
||||||
|
### 4. 📖 文档质量保证
|
||||||
|
- **技术详细**: 包含算法说明和实现细节
|
||||||
|
- **示例完整**: 提供真实的请求/响应示例
|
||||||
|
- **问题预防**: 包含常见问题和解决方案
|
||||||
|
- **版本管理**: 完整的版本记录和变更说明
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 文件变更统计
|
||||||
|
|
||||||
|
### 新增文件(4个)
|
||||||
|
1. `HqHallTimeCheckBo.java` - 时间冲突检查业务对象
|
||||||
|
2. `HqHallTimeCheckVo.java` - 时间冲突检查结果视图对象
|
||||||
|
3. `hall-audit-permission.sql` - 权限配置SQL脚本
|
||||||
|
4. `报告厅预约审核API.md` - API接口文档
|
||||||
|
|
||||||
|
### 修改文件(5个)
|
||||||
|
1. `HqHallReservationVo.java` - 添加基础字段
|
||||||
|
2. `IHqHallReservationService.java` - 新增服务方法
|
||||||
|
3. `HqHallReservationServiceImpl.java` - 实现时间冲突检查
|
||||||
|
4. `HqHallReservationController.java` - 新增API接口
|
||||||
|
5. `API文档总览.md` - 更新文档导航
|
||||||
|
|
||||||
|
### 总代码行数
|
||||||
|
- **Java代码**: 约150行
|
||||||
|
- **SQL脚本**: 约35行
|
||||||
|
- **API文档**: 约400行
|
||||||
|
- **总计**: 约585行
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 测试验证要求
|
||||||
|
|
||||||
|
### 1. 🔧 后端接口测试
|
||||||
|
- [ ] 时间冲突检查接口功能测试
|
||||||
|
- [ ] 不同时间段的冲突检测验证
|
||||||
|
- [ ] 排除ID参数的正确性验证
|
||||||
|
- [ ] 权限验证测试
|
||||||
|
|
||||||
|
### 2. 🌐 前端集成测试
|
||||||
|
- [ ] 前端API调用测试
|
||||||
|
- [ ] 审核建议UI显示测试
|
||||||
|
- [ ] 错误处理和用户提示测试
|
||||||
|
|
||||||
|
### 3. 🔐 权限配置验证
|
||||||
|
- [ ] 执行权限配置SQL脚本
|
||||||
|
- [ ] 验证admin角色权限分配
|
||||||
|
- [ ] 测试接口权限控制
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 后续工作计划
|
||||||
|
|
||||||
|
### 1. 📱 前端功能优化
|
||||||
|
- 优化审核建议UI展示
|
||||||
|
- 添加实时冲突检查
|
||||||
|
- 完善错误提示机制
|
||||||
|
|
||||||
|
### 2. 🧪 测试覆盖
|
||||||
|
- 编写单元测试
|
||||||
|
- 完善集成测试
|
||||||
|
- 添加性能测试
|
||||||
|
|
||||||
|
### 3. 📊 监控和日志
|
||||||
|
- 添加接口调用监控
|
||||||
|
- 完善错误日志记录
|
||||||
|
- 性能指标收集
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 开发体验总结
|
||||||
|
|
||||||
|
### 1. ✅ 成功经验
|
||||||
|
- **规范遵循**: 严格按照项目规范开发,保证代码质量
|
||||||
|
- **文档同步**: 代码完成后立即更新文档,保持一致性
|
||||||
|
- **模块化设计**: 清晰的分层架构,便于维护和扩展
|
||||||
|
- **权限控制**: 完整的权限体系,保证系统安全
|
||||||
|
|
||||||
|
### 2. 💡 改进建议
|
||||||
|
- **代码生成**: 可以考虑为BO/VO类创建代码生成模板
|
||||||
|
- **单元测试**: 应该在开发过程中同步编写单元测试
|
||||||
|
- **性能测试**: 大数据量下的时间冲突检查性能需要验证
|
||||||
|
|
||||||
|
### 3. 🎯 质量保证
|
||||||
|
- **代码审查**: 建议进行代码审查,确保质量
|
||||||
|
- **文档校验**: API文档示例需要与实际接口保持一致
|
||||||
|
- **权限测试**: 权限配置需要在实际环境中验证
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**📝 记录人**: wuzilong
|
||||||
|
**🕐 记录时间**: 2025-01-09 17:00:00
|
||||||
|
**🎯 工作质量**: 高质量完成,符合项目规范
|
||||||
|
**📋 下次重点**: 前端集成测试和功能优化
|
||||||
|
>>>>>>> 3f9838e8f119e5bd49ded7fde2a6229e312d9a14
|
||||||
@@ -1,321 +1,244 @@
|
|||||||
# 代码调整记录 - 2025-01-23 - wuzilong
|
# 代码调整记录 - 2025-01-23
|
||||||
|
|
||||||
## 📋 本次变更概述
|
## 📋 变更概述
|
||||||
|
|
||||||
**变更类型**: 🏗️ 架构重构 - 后端模块工程统一管理
|
**变更日期**: 2025-01-23
|
||||||
**变更时间**: 2025-01-23 15:00:00
|
**操作人员**: wuzilong
|
||||||
**影响范围**: 后端模块架构、开发规范、工程结构
|
**变更类型**: 数据库表名规范化调整
|
||||||
|
**影响模块**: 物业报修管理模块
|
||||||
|
**优先级**: 高
|
||||||
|
|
||||||
## 🎯 变更背景
|
## 🎯 变更目标
|
||||||
|
|
||||||
基于ruoyi-hq工程的成功实践,为了规范化管理后端业务模块,建立统一的工程管理标准,便于后续各业务模块的开发和维护。
|
将物业报修管理模块的数据库表名从 `pm_*` 格式调整为 `hq_pm_*` 格式,符合项目数据库表名规范要求(后勤管理模块使用 `hq_` 前缀)。
|
||||||
|
|
||||||
## 🔧 变更详情
|
## 📊 变更详情
|
||||||
|
|
||||||
### 1. 📋 后端开发规范更新
|
### 1. SQL文件调整
|
||||||
|
|
||||||
**文件**: `.cursor/cursorrules-backend.md`
|
**文件**: `docs/设计文档/database/07-property-maintenance-module.sql`
|
||||||
|
|
||||||
**新增内容**:
|
|
||||||
- ✅ **模块工程管理规范(强制性)**
|
|
||||||
- ✅ **模块命名和位置规范**
|
|
||||||
- ✅ **Maven配置标准模板**
|
|
||||||
- ✅ **包结构规范标准**
|
|
||||||
- ✅ **代码规范要求**
|
|
||||||
- ✅ **权限命名规范**
|
|
||||||
- ✅ **模块开发最佳实践**
|
|
||||||
- ✅ **模块创建检查清单**
|
|
||||||
|
|
||||||
**已规划模块列表**:
|
|
||||||
- ✅ `ruoyi-hq` - 后勤管理模块 (已完成)
|
|
||||||
- 🚧 `ruoyi-rs` - 人事管理模块
|
|
||||||
- 🚧 `ruoyi-cw` - 财务管理模块
|
|
||||||
- 🚧 `ruoyi-aqbw` - 安全保卫管理模块
|
|
||||||
- 🚧 `ruoyi-zsjy` - 招生就业管理模块
|
|
||||||
- 🚧 `ruoyi-xg` - 学工管理模块
|
|
||||||
|
|
||||||
### 2. 🏗️ 新增业务模块工程
|
|
||||||
|
|
||||||
**创建的5个标准业务模块**:
|
|
||||||
|
|
||||||
#### 📁 ruoyi-rs (人事管理模块)
|
|
||||||
```
|
|
||||||
backend/ruoyi-modules/ruoyi-rs/
|
|
||||||
├── pom.xml # Maven配置
|
|
||||||
└── src/main/
|
|
||||||
├── java/org/dromara/rs/
|
|
||||||
│ ├── controller/ # 控制器层
|
|
||||||
│ ├── service/ # 服务接口层
|
|
||||||
│ │ └── impl/ # 服务实现层
|
|
||||||
│ ├── mapper/ # 数据访问层
|
|
||||||
│ └── domain/ # 数据对象层
|
|
||||||
│ ├── bo/ # 业务对象
|
|
||||||
│ └── vo/ # 视图对象
|
|
||||||
└── resources/
|
|
||||||
└── mapper/ # MyBatis映射文件
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 📁 ruoyi-cw (财务管理模块)
|
|
||||||
```
|
|
||||||
backend/ruoyi-modules/ruoyi-cw/
|
|
||||||
├── pom.xml # Maven配置
|
|
||||||
└── src/main/
|
|
||||||
├── java/org/dromara/cw/
|
|
||||||
│ ├── controller/ # 控制器层
|
|
||||||
│ ├── service/ # 服务接口层
|
|
||||||
│ │ └── impl/ # 服务实现层
|
|
||||||
│ ├── mapper/ # 数据访问层
|
|
||||||
│ └── domain/ # 数据对象层
|
|
||||||
│ ├── bo/ # 业务对象
|
|
||||||
│ └── vo/ # 视图对象
|
|
||||||
└── resources/
|
|
||||||
└── mapper/ # MyBatis映射文件
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 📁 ruoyi-aqbw (安全保卫管理模块)
|
|
||||||
```
|
|
||||||
backend/ruoyi-modules/ruoyi-aqbw/
|
|
||||||
├── pom.xml # Maven配置
|
|
||||||
└── src/main/
|
|
||||||
├── java/org/dromara/aqbw/
|
|
||||||
│ ├── controller/ # 控制器层
|
|
||||||
│ ├── service/ # 服务接口层
|
|
||||||
│ │ └── impl/ # 服务实现层
|
|
||||||
│ ├── mapper/ # 数据访问层
|
|
||||||
│ └── domain/ # 数据对象层
|
|
||||||
│ ├── bo/ # 业务对象
|
|
||||||
│ └── vo/ # 视图对象
|
|
||||||
└── resources/
|
|
||||||
└── mapper/ # MyBatis映射文件
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 📁 ruoyi-zsjy (招生就业管理模块)
|
|
||||||
```
|
|
||||||
backend/ruoyi-modules/ruoyi-zsjy/
|
|
||||||
├── pom.xml # Maven配置
|
|
||||||
└── src/main/
|
|
||||||
├── java/org/dromara/zsjy/
|
|
||||||
│ ├── controller/ # 控制器层
|
|
||||||
│ ├── service/ # 服务接口层
|
|
||||||
│ │ └── impl/ # 服务实现层
|
|
||||||
│ ├── mapper/ # 数据访问层
|
|
||||||
│ └── domain/ # 数据对象层
|
|
||||||
│ ├── bo/ # 业务对象
|
|
||||||
│ └── vo/ # 视图对象
|
|
||||||
└── resources/
|
|
||||||
└── mapper/ # MyBatis映射文件
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 📁 ruoyi-xg (学工管理模块)
|
|
||||||
```
|
|
||||||
backend/ruoyi-modules/ruoyi-xg/
|
|
||||||
├── pom.xml # Maven配置
|
|
||||||
└── src/main/
|
|
||||||
├── java/org/dromara/xg/
|
|
||||||
│ ├── controller/ # 控制器层
|
|
||||||
│ ├── service/ # 服务接口层
|
|
||||||
│ │ └── impl/ # 服务实现层
|
|
||||||
│ ├── mapper/ # 数据访问层
|
|
||||||
│ └── domain/ # 数据对象层
|
|
||||||
│ ├── bo/ # 业务对象
|
|
||||||
│ └── vo/ # 视图对象
|
|
||||||
└── resources/
|
|
||||||
└── mapper/ # MyBatis映射文件
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. ⚙️ Maven配置更新
|
|
||||||
|
|
||||||
**文件**: `backend/ruoyi-modules/pom.xml`
|
|
||||||
|
|
||||||
**变更内容**:
|
**变更内容**:
|
||||||
```xml
|
- 将所有表名从 `pm_*` 调整为 `hq_pm_*`
|
||||||
<modules>
|
- 更新相关注释和关联引用
|
||||||
<module>ruoyi-demo</module>
|
- 版本号更新至 V1.0.2
|
||||||
<module>ruoyi-generator</module>
|
|
||||||
<module>ruoyi-job</module>
|
**具体表名变更**:
|
||||||
<module>ruoyi-system</module>
|
| 原表名 | 新表名 |
|
||||||
<module>ruoyi-workflow</module>
|
|--------|--------|
|
||||||
<module>ruoyi-hq</module>
|
| `pm_repair_order` | `hq_pm_repair_order` |
|
||||||
+ <module>ruoyi-rs</module>
|
| `pm_repair_attachment` | `hq_pm_repair_attachment` |
|
||||||
+ <module>ruoyi-cw</module>
|
| `pm_repair_progress` | `hq_pm_repair_progress` |
|
||||||
+ <module>ruoyi-aqbw</module>
|
| `pm_service_evaluation` | `hq_pm_service_evaluation` |
|
||||||
+ <module>ruoyi-zsjy</module>
|
| `pm_repair_category` | `hq_pm_repair_category` |
|
||||||
+ <module>ruoyi-xg</module>
|
| `pm_system_config` | `hq_pm_system_config` |
|
||||||
</modules>
|
|
||||||
|
### 2. 数据库重命名脚本
|
||||||
|
|
||||||
|
**新增文件**: `docs/设计文档/database/08-property-maintenance-table-rename.sql`
|
||||||
|
|
||||||
|
**功能**:
|
||||||
|
- 智能检测现有表是否存在
|
||||||
|
- 批量重命名所有物业报修相关表
|
||||||
|
- 提供验证结果显示
|
||||||
|
- 支持幂等操作
|
||||||
|
|
||||||
|
### 3. 规范文档更新
|
||||||
|
|
||||||
|
**更新文件**:
|
||||||
|
- `docs/业务模块/property-maintenance/技术设计/数据库设计.md`
|
||||||
|
- `docs/业务模块/property-maintenance/README.md`
|
||||||
|
|
||||||
|
**变更内容**:
|
||||||
|
- 更新所有表名引用
|
||||||
|
- 修正实体关系图
|
||||||
|
- 更新数据流转图
|
||||||
|
|
||||||
|
### 4. 后端代码调整
|
||||||
|
|
||||||
|
**Entity实体类更新**:
|
||||||
|
- `PmRepairOrder.java` - @TableName("hq_pm_repair_order")
|
||||||
|
- `PmRepairAttachment.java` - @TableName("hq_pm_repair_attachment")
|
||||||
|
- `PmRepairProgress.java` - @TableName("hq_pm_repair_progress")
|
||||||
|
- `PmServiceEvaluation.java` - @TableName("hq_pm_service_evaluation")
|
||||||
|
- `PmRepairCategory.java` - @TableName("hq_pm_repair_category")
|
||||||
|
|
||||||
|
**Mapper XML文件更新**:
|
||||||
|
- `PmRepairAttachmentMapper.xml` - selectVo中的表名更新
|
||||||
|
- `PmRepairProgressMapper.xml` - selectVo中的表名更新
|
||||||
|
- `PmServiceEvaluationMapper.xml` - 新创建完整的Mapper XML
|
||||||
|
|
||||||
|
**VO类和BO类完善**:
|
||||||
|
- 新增:`PmRepairProgressVo.java`、`PmServiceEvaluationVo.java`
|
||||||
|
- 新增:`PmRepairProgressBo.java`、`PmServiceEvaluationBo.java`
|
||||||
|
- 更新:所有VO/BO类中的注释表名引用
|
||||||
|
|
||||||
|
**Service接口完善**:
|
||||||
|
- 新增:`IPmRepairProgressService.java`
|
||||||
|
- 新增:`IPmServiceEvaluationService.java`
|
||||||
|
|
||||||
|
**涉及文件**:
|
||||||
|
```
|
||||||
|
backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/
|
||||||
|
├── domain/
|
||||||
|
│ ├── PmRepairOrder.java ✅
|
||||||
|
│ ├── PmRepairAttachment.java ✅
|
||||||
|
│ ├── PmRepairProgress.java ✅
|
||||||
|
│ ├── PmServiceEvaluation.java ✅
|
||||||
|
│ ├── PmRepairCategory.java ✅
|
||||||
|
│ ├── vo/
|
||||||
|
│ │ ├── PmRepairProgressVo.java ✅ (新增)
|
||||||
|
│ │ ├── PmServiceEvaluationVo.java ✅ (新增)
|
||||||
|
│ │ ├── PmRepairOrderVo.java ✅ (注释更新)
|
||||||
|
│ │ ├── PmRepairAttachmentVo.java ✅ (注释更新)
|
||||||
|
│ │ └── PmRepairCategoryVo.java ✅ (注释更新)
|
||||||
|
│ └── bo/
|
||||||
|
│ ├── PmRepairProgressBo.java ✅ (新增)
|
||||||
|
│ ├── PmServiceEvaluationBo.java ✅ (新增)
|
||||||
|
│ ├── PmRepairOrderBo.java ✅ (注释更新)
|
||||||
|
│ ├── PmRepairAttachmentBo.java ✅ (注释更新)
|
||||||
|
│ └── PmRepairCategoryBo.java ✅ (注释更新)
|
||||||
|
├── service/
|
||||||
|
│ ├── IPmRepairProgressService.java ✅ (新增)
|
||||||
|
│ └── IPmServiceEvaluationService.java ✅ (新增)
|
||||||
|
└── resources/mapper/
|
||||||
|
├── PmRepairAttachmentMapper.xml ✅ (表名更新)
|
||||||
|
├── PmRepairProgressMapper.xml ✅ (表名更新)
|
||||||
|
└── PmServiceEvaluationMapper.xml ✅ (新增)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 📂 目录结构说明文件
|
## 🛠️ 执行步骤
|
||||||
|
|
||||||
**为每个模块的各层级目录添加了.gitkeep文件**,包含详细的目录用途说明:
|
### 步骤1: SQL文件调整 ✅
|
||||||
- controller/ - REST API控制器层
|
- [x] 更新表结构定义
|
||||||
- service/ - 业务服务接口层
|
- [x] 更新关联引用
|
||||||
- service/impl/ - 业务服务实现层
|
- [x] 更新索引定义
|
||||||
- mapper/ - 数据访问层
|
- [x] 更新初始化数据
|
||||||
- domain/ - 实体类
|
|
||||||
- domain/bo/ - 业务对象
|
|
||||||
- domain/vo/ - 视图对象
|
|
||||||
- resources/mapper/ - MyBatis映射文件
|
|
||||||
|
|
||||||
## 🎯 模块工程标准化规范
|
### 步骤2: 数据库表重命名 🔄
|
||||||
|
- [x] 创建重命名脚本
|
||||||
|
- [ ] 执行数据库重命名(需手动执行)
|
||||||
|
|
||||||
### 📋 统一的Maven依赖配置
|
### 步骤3: 文档更新 ✅
|
||||||
所有新模块都采用统一的依赖配置,包括:
|
- [x] 数据库设计文档
|
||||||
- **通用工具**: core、doc、mybatis、log、security、web、excel、idempotent、tenant、social、ratelimiter、mail
|
- [x] 模块总览文档
|
||||||
- **系统模块**: system、job
|
- [x] 实体关系图
|
||||||
- **扩展模块**: generator、demo、workflow
|
|
||||||
|
|
||||||
### 🏛️ 统一的包结构规范
|
### 步骤4: 代码调整 ✅
|
||||||
- **包名格式**: `org.dromara.{模块简称}`
|
- [x] Entity类@TableName注解
|
||||||
- **分层架构**: controller → service → mapper → domain
|
- [x] 注释中的表名引用
|
||||||
- **对象分离**: Entity(实体) + BO(业务对象) + VO(视图对象)
|
- [x] Mapper XML文件表名更新
|
||||||
|
- [x] 创建缺失的VO和BO类
|
||||||
|
- [x] 创建缺失的Service接口
|
||||||
|
- [x] 创建缺失的Mapper XML文件
|
||||||
|
|
||||||
### 🔐 统一的权限命名规范
|
## 📋 验证清单
|
||||||
- **权限编码格式**: `{模块简称}:{功能}:{操作}`
|
|
||||||
- **示例**:
|
|
||||||
- `rs:employee:list` - 人事模块员工列表查询权限
|
|
||||||
- `cw:budget:add` - 财务模块预算新增权限
|
|
||||||
|
|
||||||
## ✅ 验证和测试
|
### 数据库层面
|
||||||
|
- [ ] 确认旧表名不存在
|
||||||
|
- [ ] 确认新表名存在且结构正确
|
||||||
|
- [ ] 确认索引重建成功
|
||||||
|
- [ ] 确认数据完整性
|
||||||
|
|
||||||
### 🔧 编译验证
|
### 代码层面
|
||||||
- ✅ 所有新模块Maven配置正确
|
- [x] Entity类编译通过
|
||||||
- ✅ 父模块pom.xml更新成功
|
- [x] Mapper XML语法正确
|
||||||
- ✅ 目录结构符合标准规范
|
- [x] VO/BO类创建完成
|
||||||
|
- [x] Service接口定义完成
|
||||||
|
- [ ] Service实现类创建(待完成)
|
||||||
|
- [ ] Controller类创建(待完成)
|
||||||
|
- [ ] 单元测试执行成功
|
||||||
|
- [ ] API接口调用正常
|
||||||
|
- [ ] 前端页面显示正常
|
||||||
|
|
||||||
### 📁 文件结构验证
|
### 文档层面
|
||||||
- ✅ 5个新模块目录结构完整
|
- [x] 所有文档表名更新完成
|
||||||
- ✅ 每个目录都有说明文件
|
- [x] 图表和示例代码正确
|
||||||
- ✅ 包结构符合ruoyi-hq标准
|
- [x] 变更记录完整
|
||||||
|
|
||||||
## 🎯 后续计划
|
## ⚠️ 注意事项
|
||||||
|
|
||||||
### 🚧 短期计划 (1-2周)
|
### 数据库操作
|
||||||
1. **业务需求梳理**: 为每个模块梳理详细的业务需求
|
1. **备份重要性**: 执行表重命名前务必备份数据库
|
||||||
2. **数据库设计**: 设计各模块的数据表结构
|
2. **停机时间**: 重命名操作需要停止相关服务
|
||||||
3. **API设计**: 制定标准的API接口规范
|
3. **权限验证**: 确保有足够的数据库操作权限
|
||||||
|
|
||||||
### 📋 中期计划 (1个月)
|
### 代码部署
|
||||||
1. **核心功能开发**: 优先开发人事管理(rs)和财务管理(cw)模块的核心功能
|
1. **同步部署**: 数据库重命名与代码部署需同步进行
|
||||||
2. **权限配置**: 完善各模块的菜单和权限配置
|
2. **回滚预案**: 准备回滚脚本以防意外情况
|
||||||
3. **测试用例**: 编写完整的测试用例
|
3. **测试验证**: 部署后需全面测试业务功能
|
||||||
|
|
||||||
### 🎯 长期计划 (3个月)
|
### 数据一致性
|
||||||
1. **功能完善**: 完成所有5个模块的核心功能开发
|
1. **外键约束**: 确认没有外键约束冲突
|
||||||
2. **系统集成**: 各模块之间的数据交互和业务流程打通
|
2. **应用层关联**: 验证应用层关联逻辑正确
|
||||||
3. **性能优化**: 系统性能优化和并发处理能力提升
|
3. **缓存刷新**: 清理相关缓存数据
|
||||||
|
|
||||||
## 📝 注意事项
|
## 🔧 执行命令
|
||||||
|
|
||||||
### ⚠️ 开发规范
|
### 数据库重命名
|
||||||
1. **严格遵循**: 必须按照`.cursor/cursorrules-backend.md`中的模块工程管理规范进行开发
|
```bash
|
||||||
2. **代码质量**: 所有代码必须符合Alibaba Java开发手册规范
|
# 连接到MySQL数据库
|
||||||
3. **文档同步**: 每次代码变更必须同步更新相关文档
|
mysql -h 47.99.164.66 -P 3306 -u root -p hzdyjs_xg
|
||||||
|
|
||||||
### 🔐 权限管理
|
# 执行重命名脚本
|
||||||
1. **权限前缀**: 每个模块的权限前缀不能冲突
|
source docs/设计文档/database/08-property-maintenance-table-rename.sql;
|
||||||
2. **菜单配置**: 需要在数据库中配置对应的菜单和权限
|
```
|
||||||
3. **接口权限**: 每个API接口必须添加@SaCheckPermission注解
|
|
||||||
|
|
||||||
### 📊 数据库规范
|
### 代码重新编译
|
||||||
1. **基础字段**: 必须包含统一的基础字段(id、tenant_id、create_by等)
|
```bash
|
||||||
2. **逻辑删除**: 统一使用逻辑删除,禁止物理删除
|
# 后端重新编译
|
||||||
3. **多租户**: 所有业务表必须支持多租户
|
cd backend
|
||||||
|
mvn clean compile
|
||||||
|
```
|
||||||
|
|
||||||
## 🏆 变更价值
|
## 📈 影响评估
|
||||||
|
|
||||||
### 📈 技术价值
|
### 正面影响
|
||||||
1. **架构统一**: 建立了标准的模块工程架构,便于后续开发和维护
|
1. **规范统一**: 符合项目数据库命名规范
|
||||||
2. **开发效率**: 标准化的结构可以大幅提升新模块的开发效率
|
2. **维护性提升**: 表名更清晰易理解
|
||||||
3. **代码质量**: 统一的规范保证了代码质量和一致性
|
3. **模块区分**: 清晰区分后勤管理模块表
|
||||||
|
|
||||||
### 🎯 业务价值
|
### 风险评估
|
||||||
1. **功能扩展**: 为后续各业务模块的开发提供了坚实的基础
|
1. **低风险**: 仅表名变更,表结构不变
|
||||||
2. **系统完整性**: 逐步完善校园管理系统的各个业务模块
|
2. **影响范围**: 仅限物业报修模块
|
||||||
3. **运维便利**: 统一的架构降低了系统运维的复杂度
|
3. **恢复时间**: 如有问题可快速回滚
|
||||||
|
|
||||||
### 👥 团队价值
|
## ✅ 验证结果
|
||||||
1. **开发规范**: 为团队建立了统一的开发标准和最佳实践
|
|
||||||
2. **知识沉淀**: 将ruoyi-hq的成功经验规范化并推广到其他模块
|
|
||||||
3. **协作效率**: 标准化的结构提升了团队协作效率
|
|
||||||
|
|
||||||
## 🔄 相关文件变更
|
### 文件变更统计
|
||||||
|
- SQL文件: 2个(1个更新,1个新增)
|
||||||
|
- 文档文件: 2个更新
|
||||||
|
- Entity类: 5个更新(@TableName注解和注释)
|
||||||
|
- Mapper XML: 3个(2个更新,1个新增)
|
||||||
|
- VO类: 7个(2个新增,5个注释更新)
|
||||||
|
- BO类: 7个(2个新增,5个注释更新)
|
||||||
|
- Service接口: 2个新增
|
||||||
|
- 总变更行数: 约800行
|
||||||
|
|
||||||
### 📝 新增文件
|
### 测试状态
|
||||||
1. `.cursor/cursorrules-backend.md` - 新增模块工程管理规范
|
- [ ] 本地环境测试
|
||||||
2. `backend/ruoyi-modules/ruoyi-rs/` - 人事管理模块完整工程
|
- [ ] 开发环境验证
|
||||||
3. `backend/ruoyi-modules/ruoyi-cw/` - 财务管理模块完整工程
|
- [ ] 功能回归测试
|
||||||
4. `backend/ruoyi-modules/ruoyi-aqbw/` - 安全保卫管理模块完整工程
|
|
||||||
5. `backend/ruoyi-modules/ruoyi-zsjy/` - 招生就业管理模块完整工程
|
|
||||||
6. `backend/ruoyi-modules/ruoyi-xg/` - 学工管理模块完整工程
|
|
||||||
|
|
||||||
### ✏️ 修改文件
|
## 📝 后续任务
|
||||||
1. `backend/ruoyi-modules/pom.xml` - 添加5个新模块到模块列表
|
|
||||||
|
|
||||||
### 📋 新增前端文件(2025-01-23 15:30:00更新)
|
1. **数据库执行**: 在测试环境执行表重命名脚本
|
||||||
|
2. **完善代码层**:
|
||||||
|
- 创建 `PmRepairProgressServiceImpl.java` 和 `PmServiceEvaluationServiceImpl.java`
|
||||||
|
- 创建 `PmRepairProgressController.java` 和 `PmServiceEvaluationController.java`
|
||||||
|
- 完善Mapper接口方法
|
||||||
|
3. **代码测试**: 验证所有API接口正常工作
|
||||||
|
4. **前端联调**: 确认前端页面数据显示正常
|
||||||
|
5. **文档同步**: 更新相关API文档和使用说明
|
||||||
|
|
||||||
**前端界面文件夹** (web/src/views/):
|
## 🔗 相关文档
|
||||||
- ✅ `web/src/views/rs/` - 人事管理界面文件夹 + README.md
|
|
||||||
- ✅ `web/src/views/cw/` - 财务管理界面文件夹 + README.md
|
|
||||||
- ✅ `web/src/views/xg/` - 学工管理界面文件夹 + README.md
|
|
||||||
- ✅ `web/src/views/zsjy/` - 招生就业管理界面文件夹 + README.md
|
|
||||||
- ✅ `web/src/views/aqbw/` - 安全保卫管理界面文件夹 + README.md
|
|
||||||
|
|
||||||
**前端API文件夹** (web/src/api/):
|
- [项目数据库命名规范](docs/设计文档/database/mysql-database-standard.md)
|
||||||
- ✅ `web/src/api/rs/` - 人事管理API文件夹 + index.ts + README.md
|
- [物业报修模块文档](docs/业务模块/property-maintenance/README.md)
|
||||||
- ✅ `web/src/api/cw/` - 财务管理API文件夹 + index.ts + README.md
|
- [数据库设计文档](docs/业务模块/property-maintenance/技术设计/数据库设计.md)
|
||||||
- ✅ `web/src/api/xg/` - 学工管理API文件夹 + index.ts + README.md
|
|
||||||
- ✅ `web/src/api/zsjy/` - 招生就业管理API文件夹 + index.ts + README.md
|
|
||||||
- ✅ `web/src/api/aqbw/` - 安全保卫管理API文件夹 + index.ts + README.md
|
|
||||||
|
|
||||||
### 📋 影响评估
|
|
||||||
- **编译构建**: ✅ 正常,新模块已正确集成到Maven构建流程
|
|
||||||
- **运行时**: ✅ 正常,新模块目前为空工程,不影响现有功能
|
|
||||||
- **依赖关系**: ✅ 正常,所有依赖配置正确
|
|
||||||
- **前端构建**: ✅ 正常,新增的TypeScript文件不会影响编译
|
|
||||||
|
|
||||||
## 🔄 数据库表命名规范补充更新 (2025-01-23 16:30:00)
|
|
||||||
|
|
||||||
### 📋 变更背景
|
|
||||||
为了配合新创建的5个业务模块,需要建立统一的数据库表命名规范,确保不同模块的数据库表有清晰的命名区分,便于后续开发和维护。
|
|
||||||
|
|
||||||
### 🔴 新增表命名规范(强制性)
|
|
||||||
|
|
||||||
**文件**: `.cursor/cursorrules-backend.md`
|
|
||||||
|
|
||||||
**新增内容**: 在数据库规范章节添加了完整的表命名规范
|
|
||||||
|
|
||||||
**模块表名前缀规范**:
|
|
||||||
- **后勤管理**:`hq_` 开头 (如:`hq_repair`, `hq_maintenance`)
|
|
||||||
- **人事管理**:`rs_` 开头 (如:`rs_employee`, `rs_department`)
|
|
||||||
- **财务管理**:`cw_` 开头 (如:`cw_budget`, `cw_expense`)
|
|
||||||
- **学工管理**:`xg_` 开头 (如:`xg_student`, `xg_dormitory`)
|
|
||||||
- **招生就业**:`zsjy_` 开头 (如:`zsjy_application`, `zsjy_job`)
|
|
||||||
- **安全保卫**:`aqbw_` 开头 (如:`aqbw_security`, `aqbw_patrol`)
|
|
||||||
- **系统公共**:`common_` 开头 (如:`common_dict`, `common_config`)
|
|
||||||
|
|
||||||
### ✅ 规范内容要点
|
|
||||||
|
|
||||||
1. **命名示例**: 提供了7个模块的完整CREATE TABLE示例
|
|
||||||
2. **强制性要求**: 明确了6个强制性命名要求和4个禁止事项
|
|
||||||
3. **实体类映射**: 提供了表名到Java实体类的命名对应规则
|
|
||||||
4. **规范位置**: 放置在数据库规范的强制性核心规范之后,基础字段模板之前
|
|
||||||
|
|
||||||
### 🔄 后勤管理模块补充更新 (2025-01-23 16:35:00)
|
|
||||||
|
|
||||||
**补充内容**: 添加后勤管理模块的表命名规范
|
|
||||||
- ✅ **后勤管理**: `hq_` 开头 (如:`hq_repair`, `hq_maintenance`)
|
|
||||||
- ✅ **命名示例**: 添加了后勤管理模块的CREATE TABLE示例
|
|
||||||
- ✅ **实体类映射**: 添加了 `hq_repair` → `HqRepair` 的命名对应示例
|
|
||||||
|
|
||||||
**更新说明**: 现在表命名规范涵盖完整的7个业务模块,包括已开发的后勤管理模块和5个新规划模块。
|
|
||||||
|
|
||||||
### 🎯 规范价值
|
|
||||||
|
|
||||||
1. **模块区分**: 清晰区分不同业务模块的数据表
|
|
||||||
2. **开发效率**: 标准化命名减少开发时的困惑
|
|
||||||
3. **维护便利**: 便于后续数据库维护和权限管理
|
|
||||||
4. **团队协作**: 为团队提供统一的数据库命名标准
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**总结**: 本次变更成功建立了前后端模块工程的统一管理规范,创建了5个后端业务模块和对应的前端文件夹结构,并补充完善了包含7个业务模块的完整数据库表命名规范(后勤、人事、财务、学工、招生就业、安全保卫、系统公共),为后续各业务模块的全栈开发奠定了坚实的架构基础。所有变更都经过仔细验证,确保系统稳定性不受影响。
|
**变更完成时间**: 2025-01-23 18:45:00
|
||||||
|
**最后更新**: 2025-01-23 18:45:00 - 完成所有表名调整和基础代码结构
|
||||||
|
**下次更新计划**: 待Service实现类和Controller创建完成后更新验证结果
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# 代码调整记录 2025-07-01
|
||||||
|
|
||||||
|
## 报告厅预约界面样式优化
|
||||||
|
|
||||||
|
### 调整内容
|
||||||
|
- 优化了报告厅预约界面中暂无图片占位符的样式
|
||||||
|
- 使暂无图片占位符宽度与预约用途输入框保持一致(450px)
|
||||||
|
- 增加了响应式布局支持,在小屏幕上自动适应容器宽度
|
||||||
|
|
||||||
|
### 具体修改
|
||||||
|
- 文件: `web/src/views/hq/hallReservation/index.vue`
|
||||||
|
- 修改了 `no-images-placeholder` 样式类:
|
||||||
|
- 将固定宽度改为响应式宽度 `width: 100%`
|
||||||
|
- 添加最大宽度限制 `max-width: 450px`
|
||||||
|
- 保持与预约用途输入框视觉统一
|
||||||
|
|
||||||
|
### 优化效果
|
||||||
|
- 提升了界面视觉统一性
|
||||||
|
- 改善了响应式布局表现
|
||||||
|
- 优化了用户体验
|
||||||
|
|
||||||
|
### 相关文件
|
||||||
|
- [x] web/src/views/hq/hallReservation/index.vue
|
||||||
|
|
||||||
|
提交人: wuzilong
|
||||||
|
完成时间: 2025-07-01 10:30:00
|
||||||
@@ -346,3 +346,196 @@
|
|||||||
- 次要按钮: 使用轮廓式设计
|
- 次要按钮: 使用轮廓式设计
|
||||||
- 危险按钮: 使用错误色
|
- 危险按钮: 使用错误色
|
||||||
- 禁用状态: 降低透明度
|
- 禁用状态: 降低透明度
|
||||||
|
|
||||||
|
# API接口基础规范(2025-07-01更新)
|
||||||
|
|
||||||
|
## 一、系统基础模块规范
|
||||||
|
|
||||||
|
### 1. 系统模块代码位置
|
||||||
|
|
||||||
|
所有涉及以下功能的API接口代码必须统一写在 `ruoyi-system` 工程中:
|
||||||
|
- 用户管理相关(SysUser)
|
||||||
|
- 组织机构相关(SysDept)
|
||||||
|
- 角色权限相关(SysRole)
|
||||||
|
- 菜单权限相关(SysMenu)
|
||||||
|
- 字典管理相关(SysDict)
|
||||||
|
- 系统配置相关(SysConfig)
|
||||||
|
- 租户管理相关(SysTenant)
|
||||||
|
|
||||||
|
#### 代码组织结构
|
||||||
|
```
|
||||||
|
ruoyi-system/
|
||||||
|
├── src/main/java/org/dromara/system/
|
||||||
|
│ ├── controller/system/ # 控制器(注意是system子包)
|
||||||
|
│ ├── service/ # 服务接口
|
||||||
|
│ ├── service/impl/ # 服务实现
|
||||||
|
│ ├── mapper/ # 数据访问层
|
||||||
|
│ └── domain/ # 实体类和VO对象
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 租户过滤规范
|
||||||
|
|
||||||
|
#### 2.1 Controller层
|
||||||
|
```java
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/xxx")
|
||||||
|
public class XxxController {
|
||||||
|
|
||||||
|
@GetMapping("/list")
|
||||||
|
public R<List<XxxVO>> list(@RequestParam(value = "tenantId", required = false) String tenantId) {
|
||||||
|
// 如果tenantId为空,会自动使用当前用户的租户ID
|
||||||
|
return R.ok(xxxService.selectXxxList(tenantId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 Service层
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class XxxServiceImpl implements IXxxService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<XxxVO> selectXxxList(String tenantId) {
|
||||||
|
if (StringUtils.isEmpty(tenantId)) {
|
||||||
|
tenantId = SecurityUtils.getTenantId();
|
||||||
|
}
|
||||||
|
return baseMapper.selectXxxList(tenantId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.3 Mapper层
|
||||||
|
```java
|
||||||
|
@Mapper
|
||||||
|
public interface XxxMapper {
|
||||||
|
|
||||||
|
@Select("""
|
||||||
|
SELECT
|
||||||
|
x.*
|
||||||
|
FROM xxx x
|
||||||
|
WHERE x.tenant_id = #{tenantId}
|
||||||
|
AND x.del_flag = '0'
|
||||||
|
ORDER BY x.create_time DESC
|
||||||
|
""")
|
||||||
|
List<Xxx> selectXxxList(@Param("tenantId") String tenantId);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 统一返回值规范
|
||||||
|
|
||||||
|
#### 3.1 后端返回格式
|
||||||
|
```java
|
||||||
|
// 统一返回格式
|
||||||
|
public class R<T> {
|
||||||
|
private int code; // 状态码
|
||||||
|
private String msg; // 消息
|
||||||
|
private T data; // 数据对象
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页返回格式
|
||||||
|
public class TableDataInfo<T> {
|
||||||
|
private int code; // 状态码
|
||||||
|
private String msg; // 消息
|
||||||
|
private List<T> data; // 数据对象
|
||||||
|
private long total; // 总记录数
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 前端获取数据规范
|
||||||
|
```typescript
|
||||||
|
// 标准数据获取
|
||||||
|
const getList = async () => {
|
||||||
|
try {
|
||||||
|
const res = await listApi();
|
||||||
|
// 正确:从data字段获取数据
|
||||||
|
dataList.value = res.data || [];
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取数据失败:', error);
|
||||||
|
dataList.value = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 分页数据获取
|
||||||
|
const getPageList = async (query: PageQuery) => {
|
||||||
|
try {
|
||||||
|
const res = await pageApi(query);
|
||||||
|
// 正确:从data字段获取列表数据
|
||||||
|
dataList.value = res.data || [];
|
||||||
|
// 获取总数
|
||||||
|
total.value = res.total || 0;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取分页数据失败:', error);
|
||||||
|
dataList.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 二、代码生成规范
|
||||||
|
|
||||||
|
### 1. 代码生成器配置
|
||||||
|
|
||||||
|
#### 1.1 系统模块配置
|
||||||
|
- 当生成的代码涉及用户、组织、角色等基础功能时:
|
||||||
|
- 包名:`org.dromara.system`
|
||||||
|
- 模块名:`ruoyi-system`
|
||||||
|
- 表前缀:`sys_`
|
||||||
|
|
||||||
|
#### 1.2 租户字段配置
|
||||||
|
- 必须包含租户字段:`tenant_id`
|
||||||
|
- 字段类型:`varchar(20)`
|
||||||
|
- 默认值:`'000000'`
|
||||||
|
- 注释:`租户编号`
|
||||||
|
|
||||||
|
### 2. 模板调整建议
|
||||||
|
|
||||||
|
#### 2.1 Controller模板
|
||||||
|
```java
|
||||||
|
@ApiOperation("查询${functionName}列表")
|
||||||
|
@SaCheckPermission("${permissionPrefix}:list")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public R<List<${ClassName}VO>> list(${ClassName}BO bo) {
|
||||||
|
// 确保设置租户ID
|
||||||
|
if (StringUtils.isEmpty(bo.getTenantId())) {
|
||||||
|
bo.setTenantId(SecurityUtils.getTenantId());
|
||||||
|
}
|
||||||
|
return R.ok(${className}Service.queryList(bo));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 Service模板
|
||||||
|
```java
|
||||||
|
@Override
|
||||||
|
public List<${ClassName}VO> queryList(${ClassName}BO bo) {
|
||||||
|
// 租户过滤
|
||||||
|
LambdaQueryWrapper<${ClassName}> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(${ClassName}::getTenantId, bo.getTenantId());
|
||||||
|
// ... 其他查询条件
|
||||||
|
return baseMapper.selectVoList(lqw);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三、注意事项
|
||||||
|
|
||||||
|
### 1. 租户ID处理
|
||||||
|
- 前端可以选择性传入租户ID
|
||||||
|
- 如果未传入,后端使用当前用户的租户ID
|
||||||
|
- 禁止跨租户查询(除非特殊说明)
|
||||||
|
|
||||||
|
### 2. 返回值处理
|
||||||
|
- 前端统一从data字段获取数据
|
||||||
|
- 禁止使用rows或其他字段名
|
||||||
|
- 空值处理使用空数组或空对象
|
||||||
|
|
||||||
|
### 3. 系统模块开发
|
||||||
|
- 涉及基础功能必须在ruoyi-system中开发
|
||||||
|
- 保持代码结构统一
|
||||||
|
- 遵循权限命名规范
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**📝 维护说明**:
|
||||||
|
- 更新时间:2025-07-01
|
||||||
|
- 更新人:wuzilong
|
||||||
|
- 基于实际项目开发经验总结
|
||||||
|
- 持续补充和优化
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
| **🛠️ 物业报修管理 API** | [物业报修管理 API.md](./物业报修管理API.md) | 维修分类、报修工单、进度跟踪、服务评价 | 物业报修功能开发 |
|
| **🛠️ 物业报修管理 API** | [物业报修管理 API.md](./物业报修管理API.md) | 维修分类、报修工单、进度跟踪、服务评价 | 物业报修功能开发 |
|
||||||
| **📊 后勤满意度调查 API** | [后勤满意度调查 API.md](./后勤满意度调查API.md) | 问卷管理、答题、题目管理、答题记录 | 满意度调查功能开发 |
|
| **📊 后勤满意度调查 API** | [后勤满意度调查 API.md](./后勤满意度调查API.md) | 问卷管理、答题、题目管理、答题记录 | 满意度调查功能开发 |
|
||||||
| **🏢 场地预约管理 API** | [场地预约管理 API.md](./场地预约管理API.md) | 场地信息管理、预约申请、审批流程、冲突检查 | 场地预约功能开发 |
|
| **🏢 场地预约管理 API** | [场地预约管理 API.md](./场地预约管理API.md) | 场地信息管理、预约申请、审批流程、冲突检查 | 场地预约功能开发 |
|
||||||
|
| **🎭 报告厅预约审核 API** | [报告厅预约审核 API.md](./报告厅预约审核API.md) | 审核建议生成、时间冲突检查、批量审核处理 | 报告厅审核功能开发 |
|
||||||
|
|
||||||
### 📝 阅读建议
|
### 📝 阅读建议
|
||||||
|
|
||||||
@@ -62,6 +63,13 @@
|
|||||||
- [预约审批](./场地预约管理API.md#审批场地预约) - 审批流程管理
|
- [预约审批](./场地预约管理API.md#审批场地预约) - 审批流程管理
|
||||||
- [时间冲突检查](./场地预约管理API.md#检查时间冲突) - 预约冲突检测
|
- [时间冲突检查](./场地预约管理API.md#检查时间冲突) - 预约冲突检测
|
||||||
|
|
||||||
|
#### 🎭 报告厅审核相关
|
||||||
|
|
||||||
|
- [报告厅预约查询](./报告厅预约审核API.md#报告厅预约查询-api) - 预约列表和详情查询
|
||||||
|
- [时间冲突检查](./报告厅预约审核API.md#时间冲突检查-api) - 智能冲突检测
|
||||||
|
- [批量审核处理](./报告厅预约审核API.md#报告厅预约审核-api) - 批准/拒绝预约申请
|
||||||
|
- [审核建议生成](./报告厅预约审核API.md#时间冲突检查-api) - 基于冲突检查的智能建议
|
||||||
|
|
||||||
### 🔍 按开发阶段查找
|
### 🔍 按开发阶段查找
|
||||||
|
|
||||||
#### 🚀 项目初期
|
#### 🚀 项目初期
|
||||||
|
|||||||
@@ -393,6 +393,101 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 预约时间冲突检查接口
|
||||||
|
|
||||||
|
### 1. 检查报告厅预约时间冲突
|
||||||
|
|
||||||
|
#### 接口说明
|
||||||
|
- 接口名称:检查报告厅预约时间是否存在冲突
|
||||||
|
- 接口地址:`/hq/hallReservation/checkTimeConflict`
|
||||||
|
- 请求方式:POST
|
||||||
|
- 接口说明:根据报告厅ID和预约时间段,检查是否与已批准的预约存在时间冲突
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hallId": "1", // 报告厅ID
|
||||||
|
"startTime": "2025-01-15 09:00:00", // 预约开始时间
|
||||||
|
"endTime": "2025-01-15 12:00:00", // 预约结束时间
|
||||||
|
"excludeId": "100" // 排除的预约ID(可选,用于编辑时排除自身)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应参数
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"hasConflict": true, // 是否存在冲突
|
||||||
|
"conflictList": [ // 冲突的预约列表
|
||||||
|
{
|
||||||
|
"id": "101",
|
||||||
|
"hallId": "1",
|
||||||
|
"hallName": "第一报告厅",
|
||||||
|
"startTime": "2025-01-15 10:00:00",
|
||||||
|
"endTime": "2025-01-15 13:00:00",
|
||||||
|
"applicantName": "张三",
|
||||||
|
"status": "1", // 预约状态:0-审核中,1-已批准,2-已拒绝
|
||||||
|
"auditTime": "2025-01-14 15:30:00"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 错误码说明
|
||||||
|
| 错误码 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 200 | 成功 |
|
||||||
|
| 500 | 系统错误 |
|
||||||
|
| 400 | 参数错误 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
```http
|
||||||
|
POST /hq/hallReservation/checkTimeConflict
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"hallId": "1",
|
||||||
|
"startTime": "2025-01-15 09:00:00",
|
||||||
|
"endTime": "2025-01-15 12:00:00"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"hasConflict": true,
|
||||||
|
"conflictList": [
|
||||||
|
{
|
||||||
|
"id": "101",
|
||||||
|
"hallId": "1",
|
||||||
|
"hallName": "第一报告厅",
|
||||||
|
"startTime": "2025-01-15 10:00:00",
|
||||||
|
"endTime": "2025-01-15 13:00:00",
|
||||||
|
"applicantName": "张三",
|
||||||
|
"status": "1",
|
||||||
|
"auditTime": "2025-01-14 15:30:00"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 注意事项
|
||||||
|
1. 时间格式必须为:yyyy-MM-dd HH:mm:ss
|
||||||
|
2. 只检查与已批准(status=1)的预约是否冲突
|
||||||
|
3. 时间冲突的判定规则:
|
||||||
|
- 新预约的开始时间在已有预约时间段内
|
||||||
|
- 新预约的结束时间在已有预约时间段内
|
||||||
|
- 新预约时间段完全包含已有预约时间段
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 数据字典
|
## 数据字典
|
||||||
|
|
||||||
### 场地类型 (hq_venue_type)
|
### 场地类型 (hq_venue_type)
|
||||||
|
|||||||
@@ -0,0 +1,429 @@
|
|||||||
|
# 报告厅预约审核 API 文档
|
||||||
|
|
||||||
|
## 文档信息
|
||||||
|
|
||||||
|
- **文档名称**: 报告厅预约审核 API 文档
|
||||||
|
- **创建时间**: 2025-01-09
|
||||||
|
- **维护负责人**: 开发团队
|
||||||
|
- **最后更新**: 2025-01-09 16:30:00
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
报告厅预约审核模块提供专门的报告厅预约审核功能 API 接口,包括审核建议生成、时间冲突检查、批量审核等核心功能。该模块主要面向管理员用户,用于对用户提交的报告厅预约申请进行审核处理。
|
||||||
|
|
||||||
|
### 核心功能
|
||||||
|
|
||||||
|
- 📋 **预约列表查询**:查询待审核和已审核的报告厅预约申请
|
||||||
|
- 🔍 **时间冲突检查**:智能检测预约时间是否与已批准的预约冲突
|
||||||
|
- 💡 **审核建议生成**:基于时间冲突检查结果自动生成审核建议
|
||||||
|
- ✅ **批量审核处理**:支持批准/拒绝单个或多个预约申请
|
||||||
|
- 📊 **审核记录管理**:记录审核人、审核时间、审核备注等详细信息
|
||||||
|
|
||||||
|
### 技术特点
|
||||||
|
|
||||||
|
- **智能冲突检测**:精确的时间重叠算法,避免预约冲突
|
||||||
|
- **批量操作支持**:高效处理多个预约的审核操作
|
||||||
|
- **权限控制严格**:完整的权限验证机制
|
||||||
|
- **日志记录完整**:详细的操作日志和审核轨迹
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 基础规范
|
||||||
|
|
||||||
|
### 请求头规范
|
||||||
|
|
||||||
|
所有需要认证的接口都必须在请求头中携带:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Authorization": "Bearer {access_token}",
|
||||||
|
"clientid": "e5cd7e4891bf95d1d19206ce24a7b32e",
|
||||||
|
"Content-Type": "application/json;charset=utf-8",
|
||||||
|
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
||||||
|
"referer": "http://localhost/login?redirect=%252Findex"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 响应格式规范
|
||||||
|
|
||||||
|
- **分页列表**: TableDataInfo 格式 (total, rows, code, msg)
|
||||||
|
- **非分页接口**: R 类型格式 (code, msg, data)
|
||||||
|
- **错误响应**: 统一错误格式
|
||||||
|
|
||||||
|
详细规范请参考:[API文档基础规范](./API文档基础规范.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 报告厅预约查询 API
|
||||||
|
|
||||||
|
### 1. 查询报告厅预约列表
|
||||||
|
|
||||||
|
**接口描述**: 查询报告厅预约申请列表,支持多种条件筛选
|
||||||
|
**请求方式**: `GET`
|
||||||
|
**请求路径**: `/hq/hallReservation/list`
|
||||||
|
**权限要求**: `hq:hallReservation:list`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 | 示例值 |
|
||||||
|
| ------------- | ------- | ---- | ---------------------------------- | ---------------- |
|
||||||
|
| hallName | String | 否 | 报告厅名称(模糊查询) | 第一报告厅 |
|
||||||
|
| startTime | String | 否 | 预约开始时间(查询该时间之后的) | 2025-01-10 |
|
||||||
|
| endTime | String | 否 | 预约结束时间(查询该时间之前的) | 2025-01-15 |
|
||||||
|
| applicantName | String | 否 | 申请人姓名(模糊查询) | 张三 |
|
||||||
|
| status | String | 否 | 预约状态(0-审核中 1-已批准 2-已拒绝) | 0 |
|
||||||
|
| pageNum | Integer | 否 | 页码,默认1 | 1 |
|
||||||
|
| pageSize | Integer | 否 | 每页数量,默认10 | 10 |
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"total": 5,
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"id": 1234567890123456789,
|
||||||
|
"hallId": 1,
|
||||||
|
"hallName": "第一报告厅",
|
||||||
|
"applicantId": 987654321,
|
||||||
|
"applicantName": "张三",
|
||||||
|
"applicantPhone": "13800138000",
|
||||||
|
"startTime": "2025-01-15 09:00:00",
|
||||||
|
"endTime": "2025-01-15 12:00:00",
|
||||||
|
"reservationPurpose": "学术讲座 - 人工智能发展趋势",
|
||||||
|
"status": "0",
|
||||||
|
"auditBy": null,
|
||||||
|
"auditName": null,
|
||||||
|
"auditTime": null,
|
||||||
|
"auditRemark": null,
|
||||||
|
"createTime": "2025-01-09 14:30:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"code": 200,
|
||||||
|
"msg": "查询成功"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 获取报告厅预约详情
|
||||||
|
|
||||||
|
**接口描述**: 获取指定预约申请的详细信息
|
||||||
|
**请求方式**: `GET`
|
||||||
|
**请求路径**: `/hq/hallReservation/{id}`
|
||||||
|
**权限要求**: `hq:hallReservation:query`
|
||||||
|
|
||||||
|
#### 路径参数
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 | 示例值 |
|
||||||
|
| ------ | ---- | ---- | ------- | ----------------- |
|
||||||
|
| id | Long | 是 | 预约 ID | 1234567890123456789 |
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"id": 1234567890123456789,
|
||||||
|
"hallId": 1,
|
||||||
|
"hallName": "第一报告厅",
|
||||||
|
"applicantId": 987654321,
|
||||||
|
"applicantName": "张三",
|
||||||
|
"applicantPhone": "13800138000",
|
||||||
|
"startTime": "2025-01-15 09:00:00",
|
||||||
|
"endTime": "2025-01-15 12:00:00",
|
||||||
|
"reservationPurpose": "学术讲座 - 人工智能发展趋势",
|
||||||
|
"status": "0",
|
||||||
|
"auditBy": null,
|
||||||
|
"auditName": null,
|
||||||
|
"auditTime": null,
|
||||||
|
"auditRemark": null,
|
||||||
|
"createTime": "2025-01-09 14:30:00"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 时间冲突检查 API
|
||||||
|
|
||||||
|
### 检查报告厅预约时间冲突
|
||||||
|
|
||||||
|
**接口描述**: 检查指定报告厅在指定时间段内是否存在已批准的预约冲突
|
||||||
|
**请求方式**: `POST`
|
||||||
|
**请求路径**: `/hq/hallReservation/checkTimeConflict`
|
||||||
|
**权限要求**: `hq:hallReservation:query`
|
||||||
|
|
||||||
|
#### 请求体
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hallId": 1,
|
||||||
|
"startTime": "2025-01-15 09:00:00",
|
||||||
|
"endTime": "2025-01-15 12:00:00",
|
||||||
|
"excludeId": 1234567890123456789
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 请求参数说明
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 | 示例值 |
|
||||||
|
| --------- | ---- | ---- | --------------------------------------- | --------------------- |
|
||||||
|
| hallId | Long | 是 | 报告厅ID | 1 |
|
||||||
|
| startTime | Date | 是 | 预约开始时间(格式:yyyy-MM-dd HH:mm:ss) | 2025-01-15 09:00:00 |
|
||||||
|
| endTime | Date | 是 | 预约结束时间(格式:yyyy-MM-dd HH:mm:ss) | 2025-01-15 12:00:00 |
|
||||||
|
| excludeId | Long | 否 | 排除的预约ID(编辑时排除自己) | 1234567890123456789 |
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
**无冲突时:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"hasConflict": false,
|
||||||
|
"conflictList": [],
|
||||||
|
"conflictMessage": "无时间冲突"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**有冲突时:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"hasConflict": true,
|
||||||
|
"conflictList": [
|
||||||
|
{
|
||||||
|
"id": 1234567890123456790,
|
||||||
|
"hallId": 1,
|
||||||
|
"hallName": "第一报告厅",
|
||||||
|
"applicantName": "李四",
|
||||||
|
"applicantPhone": "13900139000",
|
||||||
|
"startTime": "2025-01-15 10:00:00",
|
||||||
|
"endTime": "2025-01-15 13:00:00",
|
||||||
|
"reservationPurpose": "企业宣讲会",
|
||||||
|
"status": "1",
|
||||||
|
"auditName": "管理员",
|
||||||
|
"auditTime": "2025-01-14 15:30:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conflictMessage": "发现 1 个时间冲突的已批准预约"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 时间冲突判定规则
|
||||||
|
|
||||||
|
两个时间段存在冲突的条件:
|
||||||
|
1. 新预约开始时间 < 已存在预约结束时间
|
||||||
|
2. 新预约结束时间 > 已存在预约开始时间
|
||||||
|
|
||||||
|
即:`startTime < existingEndTime AND endTime > existingStartTime`
|
||||||
|
|
||||||
|
#### 冲突检查逻辑
|
||||||
|
|
||||||
|
1. **同一报告厅**:只检查相同报告厅ID的预约
|
||||||
|
2. **已批准状态**:只检查状态为"1"(已批准)的预约
|
||||||
|
3. **排除自身**:修改预约时可以通过excludeId排除自身
|
||||||
|
4. **精确匹配**:使用数据库时间比较,确保检查准确性
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 报告厅预约审核 API
|
||||||
|
|
||||||
|
### 批量审核报告厅预约
|
||||||
|
|
||||||
|
**接口描述**: 批量批准或拒绝报告厅预约申请
|
||||||
|
**请求方式**: `PUT`
|
||||||
|
**请求路径**: `/hq/hallReservation/audit`
|
||||||
|
**权限要求**: `hq:hallReservation:audit`
|
||||||
|
|
||||||
|
#### 请求体
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ids": [1234567890123456789, 1234567890123456790],
|
||||||
|
"status": "1",
|
||||||
|
"auditRemark": "审核通过,请按时使用报告厅"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 请求参数说明
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 | 示例值 |
|
||||||
|
| ----------- | ---------- | ---- | ------------------------------ | ----------------------------------------------- |
|
||||||
|
| ids | Long[] | 是 | 要审核的预约ID数组 | [1234567890123456789, 1234567890123456790] |
|
||||||
|
| status | String | 是 | 审核状态(1-批准 2-拒绝) | 1 |
|
||||||
|
| auditRemark | String | 否 | 审核备注(拒绝时建议填写原因) | 审核通过,请按时使用报告厅 |
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
**成功时:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**失败时:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 500,
|
||||||
|
"msg": "审核失败,请稍后重试"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 审核业务逻辑
|
||||||
|
|
||||||
|
1. **状态检查**:只有状态为"0"(审核中)的预约可以被审核
|
||||||
|
2. **权限验证**:必须具有`hq:hallReservation:audit`权限
|
||||||
|
3. **审核信息记录**:
|
||||||
|
- auditBy:当前登录用户ID
|
||||||
|
- auditName:当前登录用户姓名
|
||||||
|
- auditTime:当前系统时间
|
||||||
|
- auditRemark:审核备注
|
||||||
|
4. **批量操作**:支持一次审核多个预约,保证操作的原子性
|
||||||
|
|
||||||
|
#### 审核状态说明
|
||||||
|
|
||||||
|
| 状态值 | 状态名称 | 说明 |
|
||||||
|
| ------ | -------- | ---------------------- |
|
||||||
|
| 0 | 审核中 | 用户提交,等待审核 |
|
||||||
|
| 1 | 已批准 | 管理员审核通过 |
|
||||||
|
| 2 | 已拒绝 | 管理员审核拒绝 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 数据字典
|
||||||
|
|
||||||
|
### 预约状态 (hall_reserv_status)
|
||||||
|
|
||||||
|
| 字典值 | 字典标签 | 说明 | 颜色标识 |
|
||||||
|
| ------ | -------- | ------------ | -------- |
|
||||||
|
| 0 | 审核中 | 待管理员审核 | 橙色 |
|
||||||
|
| 1 | 已批准 | 审核通过 | 绿色 |
|
||||||
|
| 2 | 已拒绝 | 审核拒绝 | 红色 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔒 权限配置
|
||||||
|
|
||||||
|
### 接口权限要求
|
||||||
|
|
||||||
|
| 接口 | 权限标识 | 说明 |
|
||||||
|
| ----------------------------- | --------------------------- | -------------- |
|
||||||
|
| 查询报告厅预约列表 | hq:hallReservation:list | 列表查询权限 |
|
||||||
|
| 获取报告厅预约详情 | hq:hallReservation:query | 详情查询权限 |
|
||||||
|
| 检查报告厅预约时间冲突 | hq:hallReservation:query | 详情查询权限 |
|
||||||
|
| 批量审核报告厅预约 | hq:hallReservation:audit | 审核操作权限 |
|
||||||
|
|
||||||
|
### 权限配置SQL
|
||||||
|
|
||||||
|
参考文件:`docs/设计文档/database/hall-audit-permission.sql`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 开发建议
|
||||||
|
|
||||||
|
### 前端集成建议
|
||||||
|
|
||||||
|
1. **审核建议显示**:
|
||||||
|
- 调用时间冲突检查接口
|
||||||
|
- 根据返回结果显示审核建议
|
||||||
|
- 冲突时显示警告图标和冲突详情
|
||||||
|
|
||||||
|
2. **批量操作优化**:
|
||||||
|
- 支持全选/反选功能
|
||||||
|
- 批量操作前进行确认提示
|
||||||
|
- 操作结果统一反馈
|
||||||
|
|
||||||
|
3. **用户体验优化**:
|
||||||
|
- 实时冲突检查
|
||||||
|
- 操作loading状态
|
||||||
|
- 详细的错误提示
|
||||||
|
|
||||||
|
### 后端开发注意事项
|
||||||
|
|
||||||
|
1. **时间处理**:
|
||||||
|
- 统一使用数据库时间进行比较
|
||||||
|
- 注意时区处理
|
||||||
|
- 精确到秒级别
|
||||||
|
|
||||||
|
2. **并发控制**:
|
||||||
|
- 审核操作加锁机制
|
||||||
|
- 防止重复审核
|
||||||
|
- 事务一致性保证
|
||||||
|
|
||||||
|
3. **日志记录**:
|
||||||
|
- 详细的操作日志
|
||||||
|
- 异常情况记录
|
||||||
|
- 性能监控
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 常见问题
|
||||||
|
|
||||||
|
### Q1: 时间冲突检查不准确怎么办?
|
||||||
|
|
||||||
|
**A**: 检查以下几点:
|
||||||
|
1. 确认时间格式是否正确(yyyy-MM-dd HH:mm:ss)
|
||||||
|
2. 检查数据库中的时间数据是否准确
|
||||||
|
3. 确认冲突检查的SQL逻辑是否正确
|
||||||
|
4. 检查是否正确排除了指定的预约ID
|
||||||
|
|
||||||
|
### Q2: 批量审核部分失败怎么处理?
|
||||||
|
|
||||||
|
**A**:
|
||||||
|
1. 后端使用事务确保原子性
|
||||||
|
2. 如果部分失败,整个操作回滚
|
||||||
|
3. 返回具体的失败原因
|
||||||
|
4. 前端提示用户重新操作
|
||||||
|
|
||||||
|
### Q3: 审核权限验证失败?
|
||||||
|
|
||||||
|
**A**:
|
||||||
|
1. 检查用户是否具有`hq:hallReservation:audit`权限
|
||||||
|
2. 确认权限配置SQL是否正确执行
|
||||||
|
3. 检查角色权限分配是否正确
|
||||||
|
4. 确认Token是否有效
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 版本记录
|
||||||
|
|
||||||
|
### v1.0.0 (2025-01-09)
|
||||||
|
|
||||||
|
**新增功能**:
|
||||||
|
- ✨ 报告厅预约时间冲突检查接口
|
||||||
|
- ✨ 智能审核建议生成功能
|
||||||
|
- ✨ 批量审核处理功能
|
||||||
|
- ✨ 完整的权限控制机制
|
||||||
|
- ✨ 详细的审核记录管理
|
||||||
|
|
||||||
|
**技术特点**:
|
||||||
|
- 🔍 精确的时间重叠检测算法
|
||||||
|
- 📊 批量操作支持
|
||||||
|
- 🔒 严格的权限验证
|
||||||
|
- 📝 完整的操作日志
|
||||||
|
|
||||||
|
**API接口**:
|
||||||
|
- GET `/hq/hallReservation/list` - 查询预约列表
|
||||||
|
- GET `/hq/hallReservation/{id}` - 获取预约详情
|
||||||
|
- POST `/hq/hallReservation/checkTimeConflict` - 检查时间冲突
|
||||||
|
- PUT `/hq/hallReservation/audit` - 批量审核预约
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**📝 维护人**: 开发团队
|
||||||
|
**🔄 最后更新**: 2025-01-09 16:30:00
|
||||||
|
**📁 文件位置**: `docs/开发文档/API/报告厅预约审核API.md`
|
||||||
|
**🎯 相关文档**: [API文档基础规范](./API文档基础规范.md) | [API文档总览](./API文档总览.md)
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
# 用户认证登录 API
|
# 用户认证登录API文档
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
1. [用户登录](#用户登录)
|
||||||
|
2. [获取用户信息](#获取用户信息)
|
||||||
|
3. [获取具有指定权限的用户列表](#获取具有指定权限的用户列表)
|
||||||
|
|
||||||
## 📋 文档说明
|
## 📋 文档说明
|
||||||
|
|
||||||
@@ -660,3 +665,88 @@ methods: {
|
|||||||
**📝 维护**: 用户认证登录 API 文档
|
**📝 维护**: 用户认证登录 API 文档
|
||||||
**🔄 更新**: 2025-01-03
|
**🔄 更新**: 2025-01-03
|
||||||
**📁 文件**: 用户认证登录 API.md
|
**📁 文件**: 用户认证登录 API.md
|
||||||
|
|
||||||
|
## 获取具有指定权限的用户列表
|
||||||
|
|
||||||
|
### 基本信息
|
||||||
|
- **接口URL**: `/system/user/list-by-permission`
|
||||||
|
- **请求方式**: GET
|
||||||
|
- **接口描述**: 获取具有指定权限的用户列表
|
||||||
|
- **权限标识**: `system:user:list`
|
||||||
|
|
||||||
|
### 请求参数
|
||||||
|
#### Query参数
|
||||||
|
| 参数名 | 类型 | 是否必须 | 说明 | 示例值 |
|
||||||
|
|--------|------|----------|------|--------|
|
||||||
|
| permission | string | 是 | 权限标识符 | hq:hallAudit:list |
|
||||||
|
|
||||||
|
### 响应参数
|
||||||
|
```typescript
|
||||||
|
{
|
||||||
|
code: number; // 状态码
|
||||||
|
msg: string; // 提示信息
|
||||||
|
rows: {
|
||||||
|
userId: string; // 用户ID
|
||||||
|
userName: string; // 用户名
|
||||||
|
nickName: string; // 昵称
|
||||||
|
dept: {
|
||||||
|
deptId: string; // 部门ID
|
||||||
|
deptName: string; // 部门名称
|
||||||
|
};
|
||||||
|
avatar: string; // 头像URL
|
||||||
|
}[];
|
||||||
|
total: number; // 总记录数
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 响应示例
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"userId": "1",
|
||||||
|
"userName": "admin",
|
||||||
|
"nickName": "管理员",
|
||||||
|
"dept": {
|
||||||
|
"deptId": "1",
|
||||||
|
"deptName": "后勤部"
|
||||||
|
},
|
||||||
|
"avatar": "http://example.com/avatar.jpg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 错误码
|
||||||
|
| 错误码 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 401 | 未登录或登录超时 |
|
||||||
|
| 403 | 没有权限 |
|
||||||
|
| 500 | 服务器内部错误 |
|
||||||
|
|
||||||
|
### 注意事项
|
||||||
|
1. 该接口需要用户登录后才能访问
|
||||||
|
2. 返回的用户信息已过滤敏感字段
|
||||||
|
3. 建议前端对结果进行缓存,避免频繁请求
|
||||||
|
4. 返回结果按照用户ID升序排序
|
||||||
|
|
||||||
|
### 使用示例
|
||||||
|
```typescript
|
||||||
|
// 前端调用示例
|
||||||
|
import { listUsersByPermission } from '@/api/system/user';
|
||||||
|
|
||||||
|
async function getAuditors() {
|
||||||
|
try {
|
||||||
|
const res = await listUsersByPermission('hq:hallAudit:list');
|
||||||
|
if (res.code === 200) {
|
||||||
|
return res.rows;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取审核人员列表失败:', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# 报告厅信息界面测试执行报告 (2025-07-09)
|
||||||
|
|
||||||
|
## ✨ 执行概览
|
||||||
|
|
||||||
|
- **执行时间**: 2025-07-09
|
||||||
|
- **测试环境**: macOS darwin 24.5.0 / Chrome (Playwright MCP 默认浏览器)
|
||||||
|
- **前端地址**: http://localhost
|
||||||
|
- **后端地址**: http://localhost:8080
|
||||||
|
- **登录账号**: admin / admin123
|
||||||
|
|
||||||
|
## 📋 关联用例
|
||||||
|
|
||||||
|
来源: `报告厅信息界面测试用例-2025-07-09.md`
|
||||||
|
|
||||||
|
## 🧪 执行结果一览
|
||||||
|
|
||||||
|
| 用例编号 | 用例名称 | 结果 | 备注 |
|
||||||
|
|----------|----------|------|------|
|
||||||
|
| TC001 | 页面加载和核心元素检查 | ❌ 失败 | 访问路径 `/hq/hallInfo` 返回 404 页面 |
|
||||||
|
| TC002-TC012 | 依赖页面正常加载 | ⏸ 未执行 | 前置条件 (TC001) 不通过 |
|
||||||
|
|
||||||
|
## ❌ 失败详情 (TC001)
|
||||||
|
|
||||||
|
1. **操作步骤回放**
|
||||||
|
- 访问登录页 `http://localhost`,成功登录 (admin / admin123)。
|
||||||
|
- 登录后自动跳转到首页 `/index`。
|
||||||
|
- 调用 `page.goto('http://localhost/hq/hallInfo')`。
|
||||||
|
- 等待 3 秒后页面展示 **404 错误**,提示“找不到网页”。
|
||||||
|
2. **预期**: 报告厅信息页在 3 秒内加载并显示核心元素。
|
||||||
|
3. **实际**: 返回 404,页面不存在。
|
||||||
|
4. **截图**: (已保存在 Playwright 执行记录)
|
||||||
|
|
||||||
|
## 🔍 结论 & 建议
|
||||||
|
|
||||||
|
- **路由未注册**: 前端路由 `/hq/hallInfo` 在当前发布版本中未生效,导致 404。
|
||||||
|
- **菜单/权限缺失**: 若使用动态路由,请确认后台菜单数据已包含 `hq/hallInfo` 且管理员拥有 `hq:hallInfo:query` 权限。
|
||||||
|
- **接口可用性**: API 文件和 Vue 组件已存在,说明功能开发中;建议前端注册路由并在后台菜单启用后重新执行测试。
|
||||||
|
|
||||||
|
## 📌 后续行动
|
||||||
|
|
||||||
|
1. 核对后台菜单配置,确认是否已发布“报告厅信息”功能。
|
||||||
|
2. 确认前端 `router.ts` (或动态路由加载逻辑) 已包含该页面。
|
||||||
|
3. 功能上线完成后重新执行全部 12 条用例,并生成新的执行报告。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **提示**: 测试执行失败时,应先解决环境/功能就绪问题,再进行自动化测试脚本调试。
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
# 报告厅信息界面功能测试用例
|
||||||
|
|
||||||
|
## 🎯 测试概览
|
||||||
|
|
||||||
|
**编写时间**: 2025-07-09
|
||||||
|
**测试工具**: Cursor + Playwright MCP
|
||||||
|
**测试范围**: 后勤管理 → 报告厅信息界面
|
||||||
|
**测试类型**: 端到端功能 + UI 可用性 + 校验逻辑
|
||||||
|
**预计执行时长**: 40–60 分钟
|
||||||
|
|
||||||
|
## 📋 测试准备
|
||||||
|
|
||||||
|
### 1. 环境要求
|
||||||
|
|
||||||
|
- ✅ 前端运行地址: `http://localhost` (默认 80 端口)
|
||||||
|
- ✅ 后端运行地址: `http://localhost:8080`
|
||||||
|
- ✅ 管理员测试账号: `admin / admin123`
|
||||||
|
- ✅ Playwright MCP 插件已启用
|
||||||
|
- ✅ 测试图片目录: `test/hall-info/test-images/`
|
||||||
|
|
||||||
|
### 2. 基础测试数据
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"testHalls": [
|
||||||
|
{
|
||||||
|
"hallName": "测试报告厅 A",
|
||||||
|
"hallDescription": "可容纳 200 人的大型多媒体报告厅",
|
||||||
|
"hallStatus": "1",
|
||||||
|
"hallImageFile": "报告厅-01.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hallName": "测试报告厅 B",
|
||||||
|
"hallDescription": "小型多功能报告厅,适合研讨会",
|
||||||
|
"hallStatus": "1",
|
||||||
|
"hallImageFile": "报告厅-02.jpg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 测试执行计划
|
||||||
|
|
||||||
|
> **Playwright 代码片段**示例均遵循 MCP snapshot → click/type → waitFor 的通用写法,可直接复制到 Playwright 脚本中。
|
||||||
|
|
||||||
|
### 阶段一:页面基础验证(10 分钟)
|
||||||
|
|
||||||
|
#### TC001: 页面加载和核心元素检查
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 验证“报告厅信息”页面可以在 3 秒内完成加载并正确渲染核心元素 |
|
||||||
|
| **前置条件** | 已登录系统,导航到 `后勤管理 → 报告厅管理 → 报告厅信息` 菜单 |
|
||||||
|
| **步骤** | 1. 调用 `browser.navigate('http://localhost/hq/bgtgl/hallInfo')` <br/>2. `await browser.waitFor(3000)` <br/>3. `const snapshot = await browser.snapshot()` 验证页面包含“报告厅信息”标题、搜索框、【新增】按钮、表格区域、分页组件 |
|
||||||
|
| **预期结果** | 页面 3 秒内加载完成;所有核心元素可见且可交互 |
|
||||||
|
| **Playwright 示例** |
|
||||||
|
```javascript
|
||||||
|
await browser.navigate('http://localhost/hq/hallInfo');
|
||||||
|
await browser.waitFor(3000);
|
||||||
|
const snapshot = await browser.snapshot();
|
||||||
|
// 断言标题存在
|
||||||
|
```
|
||||||
|
|
||||||
|
#### TC002: 默认数据列表展示
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 验证表格列(名称、状态、图片、描述、操作)显示完整,数据加载正确 |
|
||||||
|
| **步骤** | 1. 页面加载完成后解析表格 <br/>2. 检查列头文本 <br/>3. 验证至少存在 1 条数据 |
|
||||||
|
| **预期结果** | 列头文本正确,数据行显示完整,分页信息正确 |
|
||||||
|
|
||||||
|
### 阶段二:CRUD 功能测试(20 分钟)
|
||||||
|
|
||||||
|
#### TC003: 新增报告厅信息
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 验证新增功能完整性,包括表单校验、图片上传、保存成功提示及列表刷新 |
|
||||||
|
| **前置条件** | None |
|
||||||
|
| **步骤** | 1. 点击【新增】按钮 <br/>2. 填写“报告厅名称”、“描述” <br/>3. 选择状态为“可用” <br/>4. 上传 任意一张图片 (路径: test/hall-info/test-images/`) <br/>5. 点击【保存】按钮 <br/>6. 等待成功提示并搜索新增名称 |
|
||||||
|
| **预期结果** | 弹窗关闭、提示“操作成功”,列表第一行显示新数据,图片缩略图显示正常 |
|
||||||
|
| **Playwright 示例** |
|
||||||
|
```javascript
|
||||||
|
await browser.click('新增按钮', "button:has-text('新增')");
|
||||||
|
await browser.type('名称', "input[placeholder*='报告厅名称']", '测试报告厅 A');
|
||||||
|
await browser.type('描述', "textarea[placeholder*='描述']", '可容纳 200 人的大型多媒体报告厅');
|
||||||
|
await browser.click('状态下拉', "select[placeholder*='状态']");
|
||||||
|
await browser.selectOption('状态选项', 'select', ['1']);
|
||||||
|
// 上传图片
|
||||||
|
await browser.fileUpload('选择图片', "input[type='file']", 'test/hall-info/test-images/');
|
||||||
|
await browser.click('保存', "button:has-text('保存')");
|
||||||
|
await browser.waitFor(2000);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### TC004: 编辑报告厅信息
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 验证编辑功能并确保修改后的数据正确保存 |
|
||||||
|
| **前置条件** | 已存在“测试报告厅 A”记录 |
|
||||||
|
| **步骤** | 1. 在列表中搜索并点击对应行【编辑】 <br/>2. 修改描述为“可容纳 180–200 人,带高清投影” <br/>3. 点击【保存】 <br/>4. 验证修改生效 |
|
||||||
|
| **预期结果** | 提示“操作成功”,描述字段显示新内容 |
|
||||||
|
|
||||||
|
#### TC005: 状态切换(可用 ↔ 不可用)
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 验证状态切换按钮或下拉框能实时更新报告厅可用状态 |
|
||||||
|
| **步骤** | 1. 点击状态切换或下拉,改为“不可用” <br/>2. 等待提示刷新 <br/>3. 再次切换回“可用” |
|
||||||
|
| **预期结果** | 状态字段值正确切换,表格颜色/标签同步更新 |
|
||||||
|
|
||||||
|
#### TC006: 删除报告厅信息
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 验证单条删除与批量删除功能 |
|
||||||
|
| **步骤** | 1. 勾选“测试报告厅 A”复选框 <br/>2. 点击【删除】按钮,确认弹窗 <br/>3. 验证提示成功并列表中不再出现该数据 |
|
||||||
|
| **预期结果** | 数据删除成功,表格刷新后该条目消失 |
|
||||||
|
|
||||||
|
### 阶段三:表单校验与异常测试(5 分钟)
|
||||||
|
|
||||||
|
#### TC007: 必填字段校验
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 验证未填写必填项时的校验提示 |
|
||||||
|
| **步骤** | 1. 点击【新增】 <br/>2. 不填任何字段直接保存 |
|
||||||
|
| **预期结果** | 名称、状态、图片均显示红色校验提示,无法提交成功 |
|
||||||
|
|
||||||
|
#### TC008: 名称重复校验
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 当报告厅名称已存在时,系统应提示重复并阻止保存 |
|
||||||
|
| **步骤** | 1. 新增或编辑时填写已存在的名称“测试报告厅 B” <br/>2. 点击保存 |
|
||||||
|
| **预期结果** | 弹窗提示“报告厅名称已存在”,表单不关闭 |
|
||||||
|
|
||||||
|
### 阶段四:搜索、排序与分页(5 分钟)
|
||||||
|
|
||||||
|
#### TC009: 关键字搜索
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **步骤** | 1. 在搜索框输入“测试报告厅” <br/>2. 点击【搜索】 |
|
||||||
|
| **预期结果** | 表格仅显示名称包含“测试报告厅”的记录,分页信息更新 |
|
||||||
|
|
||||||
|
#### TC010: 分页跳转
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **步骤** | 1. 若数据超过 10 条,点击分页到第 2 页 <br/>2. 观察页面加载 |
|
||||||
|
| **预期结果** | 正确跳转到第 2 页,数据加载正常 |
|
||||||
|
|
||||||
|
### 阶段五:图片上传专项测试(5 分钟)
|
||||||
|
|
||||||
|
#### TC011: 多张图片上传
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 验证支持一次上传多张图片并正确保存 |
|
||||||
|
| **步骤** | 1. 新增报告厅时选择 任意多张图片 <br/>2. 保存后查看图片列表 |
|
||||||
|
| **预期结果** | 所有上传图片均生成缩略图,放大预览正常 |
|
||||||
|
|
||||||
|
#### TC012: 不合法格式/大小校验
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **测试目标** | 上传超出大小或非图片格式文件时提示错误 |
|
||||||
|
| **步骤** | 1. 尝试上传 `test.txt` 或 >5MB 的图片 |
|
||||||
|
| **预期结果** | 显示“仅支持 jpg/png 且大小 ≤5MB”错误提示,禁止上传 |
|
||||||
|
|
||||||
|
### 阶段六:权限与安全(可选)
|
||||||
|
|
||||||
|
- TC013: 普通用户无法访问“报告厅信息”菜单
|
||||||
|
- TC014: Token 失效后访问页面应跳转登录
|
||||||
|
|
||||||
|
## ✅ 验证点汇总
|
||||||
|
|
||||||
|
- 页面元素存在性与响应速度
|
||||||
|
- CRUD 全流程成功提示与数据持久化
|
||||||
|
- 表单前端 & 后端校验一致性
|
||||||
|
- 图片上传与文件系统存储完整性
|
||||||
|
- 搜索/分页/排序交互稳定性
|
||||||
|
- 权限与安全控制
|
||||||
|
|
||||||
|
## ⏱️ 性能指标
|
||||||
|
|
||||||
|
| 指标 | 目标 |
|
||||||
|
|------|------|
|
||||||
|
| 页面首次加载 | ≤ 3 秒 |
|
||||||
|
| 新增 / 编辑请求 | ≤ 1 秒 |
|
||||||
|
| 图片上传 | ≤ 2 秒/张 |
|
||||||
|
|
||||||
|
## 📂 Playwright 代码与资源路径
|
||||||
|
|
||||||
|
- **脚本目录**: `test/hall-info/`
|
||||||
|
- **示例脚本**: `test/hall-info/hall-info-e2e.spec.js`
|
||||||
|
- **图片资源**: `test/hall-info/test-images/`
|
||||||
|
|
||||||
|
## 📝 备注
|
||||||
|
|
||||||
|
1. 以上测试用例可作为 Playwright 自动化脚本直接参考。
|
||||||
|
2. 图片上传请使用绝对路径或 `path.join(process.env.HOME, 'Downloads/报告厅照片', fileName)` 动态拼接。
|
||||||
|
3. 测试完成后,请生成执行报告并提交至 `docs/测试文档/后勤管理/报告厅信息/` 目录下,命名为 `报告厅信息界面测试执行报告-YYYY-MM-DD.md`。
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
-- ==========================================
|
-- ==========================================
|
||||||
-- 物业报修管理模块数据库脚本
|
-- 物业报修管理模块数据库脚本
|
||||||
-- 版本:V1.0.1
|
-- 版本:V1.0.2
|
||||||
-- 功能:物业报修管理模块完整表结构
|
-- 功能:物业报修管理模块完整表结构(表名规范化调整)
|
||||||
-- 作者:Cursor AI 辅助
|
-- 作者:Cursor AI 辅助
|
||||||
-- 时间:2025-01-23
|
-- 时间:2025-01-23
|
||||||
-- 依据文档:docs/业务模块/property-maintenance/技术设计/数据库设计.md
|
-- 依据文档:docs/业务模块/property-maintenance/技术设计/数据库设计.md
|
||||||
|
-- 表名规范:使用hq_前缀标识后勤管理模块
|
||||||
-- ==========================================
|
-- ==========================================
|
||||||
|
|
||||||
-- 设置字符集
|
-- 设置字符集
|
||||||
@@ -12,10 +13,10 @@ SET NAMES utf8mb4;
|
|||||||
SET FOREIGN_KEY_CHECKS = 0;
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_repair_order
|
-- Table structure for hq_pm_repair_order
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_repair_order`;
|
DROP TABLE IF EXISTS `hq_pm_repair_order`;
|
||||||
CREATE TABLE `pm_repair_order` (
|
CREATE TABLE `hq_pm_repair_order` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -33,7 +34,7 @@ CREATE TABLE `pm_repair_order` (
|
|||||||
`repair_location` varchar(200) NOT NULL COMMENT '报修地点',
|
`repair_location` varchar(200) NOT NULL COMMENT '报修地点',
|
||||||
|
|
||||||
-- 分类和紧急程度
|
-- 分类和紧急程度
|
||||||
`category_id` bigint(20) NOT NULL COMMENT '维修类型ID,关联pm_repair_category.id',
|
`category_id` bigint(20) NOT NULL COMMENT '维修类型ID,关联hq_pm_repair_category.id',
|
||||||
`priority_level` tinyint(1) NOT NULL DEFAULT 3 COMMENT '紧急程度:1-非常紧急,2-紧急,3-一般,4-不紧急,5-可延后',
|
`priority_level` tinyint(1) NOT NULL DEFAULT 3 COMMENT '紧急程度:1-非常紧急,2-紧急,3-一般,4-不紧急,5-可延后',
|
||||||
`expected_finish_time` datetime DEFAULT NULL COMMENT '期望完成时间',
|
`expected_finish_time` datetime DEFAULT NULL COMMENT '期望完成时间',
|
||||||
|
|
||||||
@@ -89,10 +90,10 @@ CREATE TABLE `pm_repair_order` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修工单表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修工单表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_repair_attachment
|
-- Table structure for hq_pm_repair_attachment
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_repair_attachment`;
|
DROP TABLE IF EXISTS `hq_pm_repair_attachment`;
|
||||||
CREATE TABLE `pm_repair_attachment` (
|
CREATE TABLE `hq_pm_repair_attachment` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -104,7 +105,7 @@ CREATE TABLE `pm_repair_attachment` (
|
|||||||
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
||||||
|
|
||||||
-- 关联信息
|
-- 关联信息
|
||||||
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联pm_repair_order.id',
|
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联hq_pm_repair_order.id',
|
||||||
|
|
||||||
-- 文件信息
|
-- 文件信息
|
||||||
`file_name` varchar(200) NOT NULL COMMENT '文件原始名称',
|
`file_name` varchar(200) NOT NULL COMMENT '文件原始名称',
|
||||||
@@ -141,10 +142,10 @@ CREATE TABLE `pm_repair_attachment` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修附件表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修附件表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_repair_progress
|
-- Table structure for hq_pm_repair_progress
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_repair_progress`;
|
DROP TABLE IF EXISTS `hq_pm_repair_progress`;
|
||||||
CREATE TABLE `pm_repair_progress` (
|
CREATE TABLE `hq_pm_repair_progress` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -156,7 +157,7 @@ CREATE TABLE `pm_repair_progress` (
|
|||||||
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
||||||
|
|
||||||
-- 关联信息
|
-- 关联信息
|
||||||
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联pm_repair_order.id',
|
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联hq_pm_repair_order.id',
|
||||||
|
|
||||||
-- 进度信息
|
-- 进度信息
|
||||||
`progress_type` char(1) NOT NULL COMMENT '进度类型:1-工单分派,2-接收确认,3-到达现场,4-开始维修,5-进度更新,6-完成维修,7-用户评价,8-工单归档,9-其他',
|
`progress_type` char(1) NOT NULL COMMENT '进度类型:1-工单分派,2-接收确认,3-到达现场,4-开始维修,5-进度更新,6-完成维修,7-用户评价,8-工单归档,9-其他',
|
||||||
@@ -199,10 +200,10 @@ CREATE TABLE `pm_repair_progress` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修进度表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修进度表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_service_evaluation
|
-- Table structure for hq_pm_service_evaluation
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_service_evaluation`;
|
DROP TABLE IF EXISTS `hq_pm_service_evaluation`;
|
||||||
CREATE TABLE `pm_service_evaluation` (
|
CREATE TABLE `hq_pm_service_evaluation` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -214,7 +215,7 @@ CREATE TABLE `pm_service_evaluation` (
|
|||||||
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
`deleted` tinyint(1) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)',
|
||||||
|
|
||||||
-- 关联信息
|
-- 关联信息
|
||||||
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联pm_repair_order.id',
|
`order_id` bigint(20) NOT NULL COMMENT '报修工单ID,关联hq_pm_repair_order.id',
|
||||||
`evaluator_id` bigint(20) NOT NULL COMMENT '评价人ID,关联sys_user.id',
|
`evaluator_id` bigint(20) NOT NULL COMMENT '评价人ID,关联sys_user.id',
|
||||||
`evaluator_name` varchar(50) NOT NULL COMMENT '评价人姓名',
|
`evaluator_name` varchar(50) NOT NULL COMMENT '评价人姓名',
|
||||||
`evaluated_worker_id` bigint(20) NOT NULL COMMENT '被评价维修员ID,关联sys_user.id',
|
`evaluated_worker_id` bigint(20) NOT NULL COMMENT '被评价维修员ID,关联sys_user.id',
|
||||||
@@ -263,10 +264,10 @@ CREATE TABLE `pm_service_evaluation` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='服务评价表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='服务评价表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_repair_category
|
-- Table structure for hq_pm_repair_category
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_repair_category`;
|
DROP TABLE IF EXISTS `hq_pm_repair_category`;
|
||||||
CREATE TABLE `pm_repair_category` (
|
CREATE TABLE `hq_pm_repair_category` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -322,10 +323,10 @@ CREATE TABLE `pm_repair_category` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修类型表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修类型表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for pm_system_config
|
-- Table structure for hq_pm_system_config
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
DROP TABLE IF EXISTS `pm_system_config`;
|
DROP TABLE IF EXISTS `hq_pm_system_config`;
|
||||||
CREATE TABLE `pm_system_config` (
|
CREATE TABLE `hq_pm_system_config` (
|
||||||
-- 标准基础字段(必须)
|
-- 标准基础字段(必须)
|
||||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
@@ -373,7 +374,7 @@ CREATE TABLE `pm_system_config` (
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- 初始化数据:维修类型分类
|
-- 初始化数据:维修类型分类
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT INTO `pm_repair_category` (
|
INSERT INTO `hq_pm_repair_category` (
|
||||||
`id`, `tenant_id`, `category_name`, `category_code`, `category_description`,
|
`id`, `tenant_id`, `category_name`, `category_code`, `category_description`,
|
||||||
`parent_id`, `level_depth`, `required_skills`, `skill_level`,
|
`parent_id`, `level_depth`, `required_skills`, `skill_level`,
|
||||||
`estimated_duration`, `icon_url`, `color_code`, `sort_order`, `status`,
|
`estimated_duration`, `icon_url`, `color_code`, `sort_order`, `status`,
|
||||||
@@ -389,7 +390,7 @@ INSERT INTO `pm_repair_category` (
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- 初始化数据:系统配置参数
|
-- 初始化数据:系统配置参数
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT INTO `pm_system_config` (
|
INSERT INTO `hq_pm_system_config` (
|
||||||
`id`, `tenant_id`, `config_key`, `config_value`, `config_type`, `config_group`,
|
`id`, `tenant_id`, `config_key`, `config_value`, `config_type`, `config_group`,
|
||||||
`config_name`, `config_description`, `default_value`, `is_system`, `is_editable`,
|
`config_name`, `config_description`, `default_value`, `is_system`, `is_editable`,
|
||||||
`sort_order`, `status`, `create_time`, `create_by`
|
`sort_order`, `status`, `create_time`, `create_by`
|
||||||
@@ -410,16 +411,16 @@ INSERT INTO `pm_system_config` (
|
|||||||
-- 创建核心业务查询索引
|
-- 创建核心业务查询索引
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- 报修工单表的核心查询索引
|
-- 报修工单表的核心查询索引
|
||||||
CREATE INDEX idx_status_time ON pm_repair_order (order_status, create_time);
|
CREATE INDEX idx_status_time ON hq_pm_repair_order (order_status, create_time);
|
||||||
CREATE INDEX idx_assignee_status ON pm_repair_order (assignee_id, order_status);
|
CREATE INDEX idx_assignee_status ON hq_pm_repair_order (assignee_id, order_status);
|
||||||
CREATE INDEX idx_reporter_time ON pm_repair_order (reporter_id, create_time);
|
CREATE INDEX idx_reporter_time ON hq_pm_repair_order (reporter_id, create_time);
|
||||||
CREATE INDEX idx_priority_assign ON pm_repair_order (priority_level, assign_time);
|
CREATE INDEX idx_priority_assign ON hq_pm_repair_order (priority_level, assign_time);
|
||||||
|
|
||||||
-- 附件表的查询索引
|
-- 附件表的查询索引
|
||||||
CREATE INDEX idx_uploader_time ON pm_repair_attachment (uploader_id, create_time);
|
CREATE INDEX idx_uploader_time ON hq_pm_repair_attachment (uploader_id, create_time);
|
||||||
|
|
||||||
-- 进度表的查询索引
|
-- 进度表的查询索引
|
||||||
CREATE INDEX idx_order_operation_time ON pm_repair_progress (order_id, operation_time);
|
CREATE INDEX idx_order_operation_time ON hq_pm_repair_progress (order_id, operation_time);
|
||||||
CREATE INDEX idx_operator_time ON pm_repair_progress (operator_id, operation_time);
|
CREATE INDEX idx_operator_time ON hq_pm_repair_progress (operator_id, operation_time);
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
-- ==========================================
|
||||||
|
-- 物业报修管理模块表名重命名脚本
|
||||||
|
-- 版本:V1.0.0
|
||||||
|
-- 功能:将现有pm_开头的表名重命名为hq_pm_开头
|
||||||
|
-- 作者:Cursor AI 辅助
|
||||||
|
-- 时间:2025-01-23
|
||||||
|
-- 目的:符合项目表名规范(后勤管理模块使用hq_前缀)
|
||||||
|
-- ==========================================
|
||||||
|
|
||||||
|
-- 设置字符集
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
|
-- 检查表是否存在并进行重命名
|
||||||
|
-- 注意:在重命名之前请确保没有其他进程在使用这些表
|
||||||
|
|
||||||
|
-- 1. 重命名报修工单表
|
||||||
|
-- 先检查表是否存在
|
||||||
|
SELECT 'Checking table existence...' AS step;
|
||||||
|
|
||||||
|
-- 重命名主要业务表
|
||||||
|
-- 1. pm_repair_order -> hq_pm_repair_order
|
||||||
|
SET @sql = IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_repair_order') > 0,
|
||||||
|
'RENAME TABLE pm_repair_order TO hq_pm_repair_order',
|
||||||
|
'SELECT "Table pm_repair_order does not exist" AS info'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2. pm_repair_attachment -> hq_pm_repair_attachment
|
||||||
|
SET @sql = IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_repair_attachment') > 0,
|
||||||
|
'RENAME TABLE pm_repair_attachment TO hq_pm_repair_attachment',
|
||||||
|
'SELECT "Table pm_repair_attachment does not exist" AS info'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 3. pm_repair_progress -> hq_pm_repair_progress
|
||||||
|
SET @sql = IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_repair_progress') > 0,
|
||||||
|
'RENAME TABLE pm_repair_progress TO hq_pm_repair_progress',
|
||||||
|
'SELECT "Table pm_repair_progress does not exist" AS info'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 4. pm_service_evaluation -> hq_pm_service_evaluation
|
||||||
|
SET @sql = IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_service_evaluation') > 0,
|
||||||
|
'RENAME TABLE pm_service_evaluation TO hq_pm_service_evaluation',
|
||||||
|
'SELECT "Table pm_service_evaluation does not exist" AS info'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 5. pm_repair_category -> hq_pm_repair_category
|
||||||
|
SET @sql = IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_repair_category') > 0,
|
||||||
|
'RENAME TABLE pm_repair_category TO hq_pm_repair_category',
|
||||||
|
'SELECT "Table pm_repair_category does not exist" AS info'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 6. pm_system_config -> hq_pm_system_config
|
||||||
|
SET @sql = IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_system_config') > 0,
|
||||||
|
'RENAME TABLE pm_system_config TO hq_pm_system_config',
|
||||||
|
'SELECT "Table pm_system_config does not exist" AS info'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 验证重命名结果
|
||||||
|
SELECT 'Verifying table rename results...' AS step;
|
||||||
|
|
||||||
|
-- 检查新表名是否存在
|
||||||
|
SELECT
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hq_pm_repair_order')
|
||||||
|
THEN 'EXISTS'
|
||||||
|
ELSE 'NOT EXISTS'
|
||||||
|
END AS hq_pm_repair_order_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hq_pm_repair_attachment')
|
||||||
|
THEN 'EXISTS'
|
||||||
|
ELSE 'NOT EXISTS'
|
||||||
|
END AS hq_pm_repair_attachment_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hq_pm_repair_progress')
|
||||||
|
THEN 'EXISTS'
|
||||||
|
ELSE 'NOT EXISTS'
|
||||||
|
END AS hq_pm_repair_progress_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hq_pm_service_evaluation')
|
||||||
|
THEN 'EXISTS'
|
||||||
|
ELSE 'NOT EXISTS'
|
||||||
|
END AS hq_pm_service_evaluation_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hq_pm_repair_category')
|
||||||
|
THEN 'EXISTS'
|
||||||
|
ELSE 'NOT EXISTS'
|
||||||
|
END AS hq_pm_repair_category_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hq_pm_system_config')
|
||||||
|
THEN 'EXISTS'
|
||||||
|
ELSE 'NOT EXISTS'
|
||||||
|
END AS hq_pm_system_config_status;
|
||||||
|
|
||||||
|
-- 检查旧表名是否还存在(应该不存在)
|
||||||
|
SELECT
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_repair_order')
|
||||||
|
THEN 'STILL EXISTS (ERROR)'
|
||||||
|
ELSE 'REMOVED (OK)'
|
||||||
|
END AS old_pm_repair_order_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_repair_attachment')
|
||||||
|
THEN 'STILL EXISTS (ERROR)'
|
||||||
|
ELSE 'REMOVED (OK)'
|
||||||
|
END AS old_pm_repair_attachment_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_repair_progress')
|
||||||
|
THEN 'STILL EXISTS (ERROR)'
|
||||||
|
ELSE 'REMOVED (OK)'
|
||||||
|
END AS old_pm_repair_progress_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_service_evaluation')
|
||||||
|
THEN 'STILL EXISTS (ERROR)'
|
||||||
|
ELSE 'REMOVED (OK)'
|
||||||
|
END AS old_pm_service_evaluation_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_repair_category')
|
||||||
|
THEN 'STILL EXISTS (ERROR)'
|
||||||
|
ELSE 'REMOVED (OK)'
|
||||||
|
END AS old_pm_repair_category_status,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pm_system_config')
|
||||||
|
THEN 'STILL EXISTS (ERROR)'
|
||||||
|
ELSE 'REMOVED (OK)'
|
||||||
|
END AS old_pm_system_config_status;
|
||||||
|
|
||||||
|
SELECT 'Table rename operation completed!' AS result;
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
-- ==========================================
|
||||||
|
-- 报告厅审核权限配置脚本
|
||||||
|
-- 功能:为报告厅审核功能添加完整权限配置
|
||||||
|
-- 时间:2025-01-09 16:30:00
|
||||||
|
-- 说明:使用UPSERT逻辑,支持重复执行
|
||||||
|
-- ==========================================
|
||||||
|
|
||||||
|
-- 第一部分:添加报告厅审核权限到现有菜单下
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_id, menu_name, parent_id, order_num, path, component,
|
||||||
|
query_param, is_frame, is_cache, menu_type, visible, status,
|
||||||
|
perms, icon, create_by, create_time, update_by, update_time, remark
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
12216, '报告厅预约审核', 2100, 6, '', '', '', 1, 0, 'F', '0', '0',
|
||||||
|
'hq:hallReservation:audit', '#', 1, now(), 1, now(), '报告厅预约审核权限'
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 12216);
|
||||||
|
|
||||||
|
-- 第二部分:为admin角色分配审核权限(如果未分配)
|
||||||
|
INSERT IGNORE INTO sys_role_menu (role_id, menu_id)
|
||||||
|
SELECT 1, 12216 WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM sys_role_menu WHERE role_id = 1 AND menu_id = 12216
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 第三部分:验证配置结果
|
||||||
|
SELECT '报告厅审核权限配置验证' as message,
|
||||||
|
COUNT(*) as new_menu_count,
|
||||||
|
(SELECT COUNT(*) FROM sys_role_menu WHERE role_id = 1 AND menu_id = 12216) as role_permission_count
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE menu_id = 12216;
|
||||||
|
|
||||||
|
-- 第四部分:查看所有报告厅相关权限
|
||||||
|
SELECT menu_id, menu_name, perms, menu_type, parent_id
|
||||||
|
FROM sys_menu
|
||||||
|
WHERE perms LIKE 'hq:hall%'
|
||||||
|
ORDER BY menu_id;
|
||||||
@@ -3,25 +3,30 @@ org.dromara.system.domain.vo.SysNoticeVo
|
|||||||
org.dromara.system.domain.bo.SysDictDataBo
|
org.dromara.system.domain.bo.SysDictDataBo
|
||||||
org.dromara.system.domain.bo.SysNoticeBo
|
org.dromara.system.domain.bo.SysNoticeBo
|
||||||
org.dromara.xg.domain.vo.XgAuditRecordVo
|
org.dromara.xg.domain.vo.XgAuditRecordVo
|
||||||
|
org.dromara.hq.domain.vo.HqPmRepairOrderVo
|
||||||
org.dromara.system.domain.vo.SysClientVo
|
org.dromara.system.domain.vo.SysClientVo
|
||||||
org.dromara.hq.domain.vo.HqSatSurveyQuestionVo
|
org.dromara.hq.domain.vo.HqSatSurveyQuestionVo
|
||||||
org.dromara.system.domain.vo.SysConfigVo
|
org.dromara.system.domain.vo.SysConfigVo
|
||||||
|
org.dromara.hq.domain.bo.HqPmRepairAttachmentBo
|
||||||
org.dromara.hq.domain.bo.HqHallInfoBo
|
org.dromara.hq.domain.bo.HqHallInfoBo
|
||||||
org.dromara.system.domain.vo.SysDeptVo
|
org.dromara.system.domain.vo.SysDeptVo
|
||||||
org.dromara.hq.domain.bo.HqSatSurveyBo
|
org.dromara.hq.domain.bo.HqSatSurveyBo
|
||||||
org.dromara.hq.domain.bo.PmRepairOrderBo
|
|
||||||
org.dromara.system.domain.bo.SysDictTypeBo
|
org.dromara.system.domain.bo.SysDictTypeBo
|
||||||
org.dromara.system.domain.bo.SysDeptBo
|
org.dromara.system.domain.bo.SysDeptBo
|
||||||
org.dromara.system.domain.vo.SysOssConfigVo
|
org.dromara.system.domain.vo.SysOssConfigVo
|
||||||
org.dromara.hq.domain.vo.HqSatSurveyVo
|
org.dromara.hq.domain.vo.HqSatSurveyVo
|
||||||
org.dromara.hq.domain.vo.HqSatRecordVo
|
org.dromara.hq.domain.vo.HqSatRecordVo
|
||||||
org.dromara.hq.domain.bo.HqHallReservationBo
|
org.dromara.hq.domain.bo.HqHallReservationBo
|
||||||
|
org.dromara.hq.domain.bo.HqPmServiceEvaluationBo
|
||||||
org.dromara.hq.domain.bo.HqSatRecordBo
|
org.dromara.hq.domain.bo.HqSatRecordBo
|
||||||
org.dromara.system.domain.bo.SysSocialBo
|
org.dromara.system.domain.bo.SysSocialBo
|
||||||
org.dromara.system.domain.bo.SysTenantPackageBo
|
org.dromara.system.domain.bo.SysTenantPackageBo
|
||||||
org.dromara.test.domain.vo.XgStuMsgVo
|
org.dromara.test.domain.vo.XgStuMsgVo
|
||||||
org.dromara.system.domain.vo.SysDictTypeVo
|
org.dromara.system.domain.vo.SysDictTypeVo
|
||||||
org.dromara.hq.domain.bo.HqSatQuestionBo
|
org.dromara.hq.domain.bo.HqSatQuestionBo
|
||||||
|
org.dromara.hq.domain.bo.HqPmRepairProgressBo
|
||||||
|
org.dromara.hq.domain.bo.HqPmRepairOrderBo
|
||||||
|
org.dromara.hq.domain.vo.HqPmRepairAttachmentVo
|
||||||
org.dromara.system.domain.vo.SysTenantPackageVo
|
org.dromara.system.domain.vo.SysTenantPackageVo
|
||||||
org.dromara.system.domain.vo.SysSocialVo
|
org.dromara.system.domain.vo.SysSocialVo
|
||||||
org.dromara.hq.domain.bo.HqSatCategoryBo
|
org.dromara.hq.domain.bo.HqSatCategoryBo
|
||||||
@@ -35,8 +40,9 @@ org.dromara.hq.domain.vo.HqHallInfoVo
|
|||||||
org.dromara.system.domain.bo.SysConfigBo
|
org.dromara.system.domain.bo.SysConfigBo
|
||||||
org.dromara.web.domain.vo.TenantListVo
|
org.dromara.web.domain.vo.TenantListVo
|
||||||
org.dromara.system.domain.bo.SysLogininforBo
|
org.dromara.system.domain.bo.SysLogininforBo
|
||||||
org.dromara.hq.domain.bo.PmRepairCategoryBo
|
org.dromara.hq.domain.vo.HqPmRepairProgressVo
|
||||||
org.dromara.xg.domain.vo.XgStudentInfoVo
|
org.dromara.xg.domain.vo.XgStudentInfoVo
|
||||||
|
org.dromara.hq.domain.vo.HqPmRepairCategoryVo
|
||||||
org.dromara.hq.domain.bo.HqSatOptionBo
|
org.dromara.hq.domain.bo.HqSatOptionBo
|
||||||
org.dromara.system.domain.bo.SysOssBo
|
org.dromara.system.domain.bo.SysOssBo
|
||||||
org.dromara.system.domain.vo.SysMenuVo
|
org.dromara.system.domain.vo.SysMenuVo
|
||||||
@@ -44,27 +50,25 @@ org.dromara.hq.domain.vo.HqSatCategoryVo
|
|||||||
org.dromara.system.domain.vo.SysUserVo
|
org.dromara.system.domain.vo.SysUserVo
|
||||||
org.dromara.hq.domain.vo.HqVenueInfoVo
|
org.dromara.hq.domain.vo.HqVenueInfoVo
|
||||||
org.dromara.xg.domain.vo.XgClassStudentVo
|
org.dromara.xg.domain.vo.XgClassStudentVo
|
||||||
org.dromara.hq.domain.vo.PmRepairCategoryVo
|
|
||||||
org.dromara.system.domain.bo.SysTenantBo
|
org.dromara.system.domain.bo.SysTenantBo
|
||||||
org.dromara.hq.domain.vo.PmRepairAttachmentVo
|
|
||||||
org.dromara.system.domain.bo.SysOssConfigBo
|
org.dromara.system.domain.bo.SysOssConfigBo
|
||||||
org.dromara.system.domain.bo.SysMenuBo
|
org.dromara.system.domain.bo.SysMenuBo
|
||||||
org.dromara.hq.domain.vo.HqVenueReservationVo
|
org.dromara.hq.domain.vo.HqVenueReservationVo
|
||||||
org.dromara.system.domain.vo.SysOperLogVo
|
org.dromara.system.domain.vo.SysOperLogVo
|
||||||
org.dromara.system.domain.vo.SysLogininforVo
|
org.dromara.system.domain.vo.SysLogininforVo
|
||||||
org.dromara.hq.domain.vo.PmRepairOrderVo
|
|
||||||
org.dromara.hq.domain.bo.HqSatDetailBo
|
org.dromara.hq.domain.bo.HqSatDetailBo
|
||||||
org.dromara.test.domain.bo.XgStuMsgBo
|
org.dromara.test.domain.bo.XgStuMsgBo
|
||||||
org.dromara.hq.domain.bo.HqVenueInfoBo
|
org.dromara.hq.domain.bo.HqVenueInfoBo
|
||||||
org.dromara.system.domain.bo.SysUserBo
|
org.dromara.system.domain.bo.SysUserBo
|
||||||
org.dromara.system.domain.vo.SysOssVo
|
org.dromara.system.domain.vo.SysOssVo
|
||||||
|
org.dromara.hq.domain.bo.HqPmRepairCategoryBo
|
||||||
org.dromara.hq.domain.vo.HqSatOptionVo
|
org.dromara.hq.domain.vo.HqSatOptionVo
|
||||||
org.dromara.hq.domain.vo.HqHallReservationVo
|
org.dromara.hq.domain.vo.HqHallReservationVo
|
||||||
|
org.dromara.hq.domain.vo.HqPmServiceEvaluationVo
|
||||||
org.dromara.system.domain.vo.SysTenantVo
|
org.dromara.system.domain.vo.SysTenantVo
|
||||||
org.dromara.hq.domain.vo.HqSatQuestionVo
|
org.dromara.hq.domain.vo.HqSatQuestionVo
|
||||||
org.dromara.hq.domain.bo.HqSatSurveyQuestionBo
|
org.dromara.hq.domain.bo.HqSatSurveyQuestionBo
|
||||||
org.dromara.system.domain.vo.SysDictDataVo
|
org.dromara.system.domain.vo.SysDictDataVo
|
||||||
org.dromara.hq.domain.bo.PmRepairAttachmentBo
|
|
||||||
org.dromara.xg.domain.bo.XgClassInfoBo
|
org.dromara.xg.domain.bo.XgClassInfoBo
|
||||||
org.dromara.hq.domain.bo.HqVenueReservationBo
|
org.dromara.hq.domain.bo.HqVenueReservationBo
|
||||||
org.dromara.system.domain.bo.SysRoleBo
|
org.dromara.system.domain.bo.SysRoleBo
|
||||||
|
|||||||
@@ -1,112 +1,65 @@
|
|||||||
|
org.dromara.system.domain.vo.SysSocialVoToSysSocialMapper
|
||||||
org.dromara.system.domain.vo.SysDictDataVoToSysDictDataMapper
|
org.dromara.system.domain.vo.SysDictDataVoToSysDictDataMapper
|
||||||
org.dromara.hq.domain.HqSatDetailToHqSatDetailVoMapper
|
|
||||||
org.dromara.xg.domain.vo.XgCollectionBatchVoToXgCollectionBatchMapper
|
org.dromara.xg.domain.vo.XgCollectionBatchVoToXgCollectionBatchMapper
|
||||||
org.dromara.hq.domain.HqSatSurveyQuestionToHqSatSurveyQuestionVoMapper
|
org.dromara.system.domain.SysOssConfigToSysOssConfigVoMapper
|
||||||
org.dromara.system.domain.vo.SysLogininforVoToSysLogininforMapper
|
org.dromara.system.domain.vo.SysLogininforVoToSysLogininforMapper
|
||||||
org.dromara.system.domain.bo.SysConfigBoToSysConfigMapper
|
org.dromara.system.domain.bo.SysConfigBoToSysConfigMapper
|
||||||
org.dromara.hq.domain.bo.HqSatSurveyBoToHqSatSurveyMapper
|
|
||||||
org.dromara.system.domain.SysTenantPackageToSysTenantPackageVoMapper
|
org.dromara.system.domain.SysTenantPackageToSysTenantPackageVoMapper
|
||||||
org.dromara.system.domain.bo.SysPostBoToSysPostMapper
|
org.dromara.system.domain.bo.SysPostBoToSysPostMapper
|
||||||
org.dromara.system.domain.vo.SysOssConfigVoToSysOssConfigMapper
|
org.dromara.system.domain.vo.SysOssConfigVoToSysOssConfigMapper
|
||||||
org.dromara.system.domain.SysDictDataToSysDictDataVoMapper
|
|
||||||
org.dromara.hq.domain.bo.HqSatRecordBoToHqSatRecordMapper
|
|
||||||
org.dromara.system.domain.vo.SysRoleVoToSysRoleMapper
|
|
||||||
org.dromara.hq.domain.bo.HqHallReservationBoToHqHallReservationMapper
|
|
||||||
org.dromara.system.domain.vo.SysClientVoToSysClientMapper
|
|
||||||
org.dromara.system.domain.bo.SysOssConfigBoToSysOssConfigMapper
|
|
||||||
org.dromara.system.domain.bo.SysDeptBoToSysDeptMapper
|
|
||||||
org.dromara.hq.domain.vo.PmRepairAttachmentVoToPmRepairAttachmentMapper
|
|
||||||
org.dromara.hq.domain.HqSatCategoryToHqSatCategoryVoMapper
|
|
||||||
org.dromara.hq.domain.bo.HqSatDetailBoToHqSatDetailMapper
|
|
||||||
org.dromara.system.domain.bo.SysOssBoToSysOssMapper
|
|
||||||
org.dromara.system.domain.vo.SysMenuVoToSysMenuMapper
|
|
||||||
org.dromara.hq.domain.vo.HqHallInfoVoToHqHallInfoMapper
|
|
||||||
org.dromara.hq.domain.bo.HqHallInfoBoToHqHallInfoMapper
|
|
||||||
org.dromara.xg.domain.XgAuditRecordToXgAuditRecordVoMapper
|
|
||||||
org.dromara.xg.domain.XgStudentInfoToXgStudentInfoVoMapper
|
|
||||||
org.dromara.hq.domain.bo.HqVenueReservationBoToHqVenueReservationMapper
|
|
||||||
org.dromara.hq.domain.vo.PmRepairOrderVoToPmRepairOrderMapper
|
|
||||||
org.dromara.system.domain.bo.SysClientBoToSysClientMapper
|
|
||||||
org.dromara.system.domain.SysClientToSysClientVoMapper
|
|
||||||
org.dromara.hq.domain.HqVenueReservationToHqVenueReservationVoMapper
|
|
||||||
org.dromara.hq.domain.vo.HqSatCategoryVoToHqSatCategoryMapper
|
|
||||||
org.dromara.test.domain.XgStuMsgToXgStuMsgVoMapper
|
|
||||||
org.dromara.hq.domain.vo.HqSatRecordVoToHqSatRecordMapper
|
|
||||||
org.dromara.system.domain.SysTenantToSysTenantVoMapper
|
|
||||||
org.dromara.hq.domain.vo.HqHallReservationVoToHqHallReservationMapper
|
|
||||||
org.dromara.system.domain.vo.SysConfigVoToSysConfigMapper
|
|
||||||
org.dromara.xg.domain.vo.XgClassInfoVoToXgClassInfoMapper
|
|
||||||
org.dromara.system.domain.bo.SysSocialBoToSysSocialMapper
|
|
||||||
org.dromara.xg.domain.vo.XgStudentInfoVoToXgStudentInfoMapper
|
|
||||||
org.dromara.system.domain.vo.SysOssVoToSysOssMapper
|
|
||||||
org.dromara.system.domain.SysDictTypeToSysDictTypeVoMapper
|
|
||||||
org.dromara.hq.domain.HqHallReservationToHqHallReservationVoMapper
|
|
||||||
org.dromara.hq.domain.vo.HqVenueInfoVoToHqVenueInfoMapper
|
|
||||||
org.dromara.hq.domain.vo.HqSatOptionVoToHqSatOptionMapper
|
|
||||||
org.dromara.xg.domain.XgClassStudentToXgClassStudentVoMapper
|
|
||||||
org.dromara.hq.domain.bo.HqVenueInfoBoToHqVenueInfoMapper
|
|
||||||
org.dromara.hq.domain.bo.HqSatOptionBoToHqSatOptionMapper
|
|
||||||
org.dromara.hq.domain.bo.HqSatCategoryBoToHqSatCategoryMapper
|
|
||||||
org.dromara.system.domain.SysLogininforToSysLogininforVoMapper
|
|
||||||
org.dromara.web.domain.vo.TenantListVoToSysTenantVoMapper
|
|
||||||
org.dromara.system.domain.vo.SysPostVoToSysPostMapper
|
|
||||||
org.dromara.system.domain.SysSocialToSysSocialVoMapper
|
|
||||||
org.dromara.system.domain.bo.SysDictTypeBoToSysDictTypeMapper
|
|
||||||
org.dromara.common.log.event.OperLogEventToSysOperLogBoMapper
|
|
||||||
org.dromara.xg.domain.bo.XgStudentInfoBoToXgStudentInfoMapper
|
|
||||||
org.dromara.system.domain.bo.SysNoticeBoToSysNoticeMapper
|
|
||||||
org.dromara.system.domain.vo.SysSocialVoToSysSocialMapper
|
|
||||||
org.dromara.hq.domain.bo.HqSatSurveyQuestionBoToHqSatSurveyQuestionMapper
|
|
||||||
org.dromara.system.domain.SysOssConfigToSysOssConfigVoMapper
|
|
||||||
org.dromara.hq.domain.vo.HqSatSurveyQuestionVoToHqSatSurveyQuestionMapper
|
|
||||||
org.dromara.system.domain.SysUserToSysUserVoMapper
|
org.dromara.system.domain.SysUserToSysUserVoMapper
|
||||||
org.dromara.system.domain.vo.SysDictTypeVoToSysDictTypeMapper
|
org.dromara.system.domain.vo.SysDictTypeVoToSysDictTypeMapper
|
||||||
org.dromara.test.domain.vo.XgStuMsgVoToXgStuMsgMapper
|
org.dromara.system.domain.SysDictDataToSysDictDataVoMapper
|
||||||
org.dromara.system.domain.bo.SysMenuBoToSysMenuMapper
|
org.dromara.system.domain.bo.SysMenuBoToSysMenuMapper
|
||||||
org.dromara.hq.domain.HqVenueInfoToHqVenueInfoVoMapper
|
org.dromara.system.domain.vo.SysRoleVoToSysRoleMapper
|
||||||
org.dromara.system.domain.vo.SysTenantVoToTenantListVoMapper
|
org.dromara.system.domain.vo.SysClientVoToSysClientMapper
|
||||||
org.dromara.hq.domain.HqHallInfoToHqHallInfoVoMapper
|
org.dromara.system.domain.bo.SysOssConfigBoToSysOssConfigMapper
|
||||||
org.dromara.system.domain.SysConfigToSysConfigVoMapper
|
org.dromara.system.domain.SysConfigToSysConfigVoMapper
|
||||||
org.dromara.system.domain.bo.SysOperLogBoToOperLogEventMapper
|
org.dromara.system.domain.bo.SysOperLogBoToOperLogEventMapper
|
||||||
org.dromara.hq.domain.PmRepairAttachmentToPmRepairAttachmentVoMapper
|
org.dromara.system.domain.bo.SysDeptBoToSysDeptMapper
|
||||||
org.dromara.hq.domain.bo.PmRepairAttachmentBoToPmRepairAttachmentMapper
|
|
||||||
org.dromara.hq.domain.HqSatSurveyToHqSatSurveyVoMapper
|
|
||||||
org.dromara.hq.domain.vo.HqSatDetailVoToHqSatDetailMapper
|
|
||||||
org.dromara.system.domain.vo.SysNoticeVoToSysNoticeMapper
|
org.dromara.system.domain.vo.SysNoticeVoToSysNoticeMapper
|
||||||
org.dromara.hq.domain.bo.PmRepairOrderBoToPmRepairOrderMapper
|
|
||||||
org.dromara.hq.domain.HqSatQuestionToHqSatQuestionVoMapper
|
|
||||||
org.dromara.xg.domain.bo.XgClassInfoBoToXgClassInfoMapper
|
org.dromara.xg.domain.bo.XgClassInfoBoToXgClassInfoMapper
|
||||||
org.dromara.hq.domain.vo.HqVenueReservationVoToHqVenueReservationMapper
|
org.dromara.system.domain.bo.SysOssBoToSysOssMapper
|
||||||
org.dromara.xg.domain.vo.XgClassStudentVoToXgClassStudentMapper
|
org.dromara.xg.domain.vo.XgClassStudentVoToXgClassStudentMapper
|
||||||
|
org.dromara.system.domain.vo.SysMenuVoToSysMenuMapper
|
||||||
org.dromara.system.domain.SysMenuToSysMenuVoMapper
|
org.dromara.system.domain.SysMenuToSysMenuVoMapper
|
||||||
org.dromara.system.domain.vo.SysTenantVoToSysTenantMapper
|
org.dromara.system.domain.vo.SysTenantVoToSysTenantMapper
|
||||||
org.dromara.system.domain.bo.SysUserBoToSysUserMapper
|
org.dromara.system.domain.bo.SysUserBoToSysUserMapper
|
||||||
|
org.dromara.xg.domain.XgAuditRecordToXgAuditRecordVoMapper
|
||||||
|
org.dromara.xg.domain.XgStudentInfoToXgStudentInfoVoMapper
|
||||||
org.dromara.xg.domain.XgClassInfoToXgClassInfoVoMapper
|
org.dromara.xg.domain.XgClassInfoToXgClassInfoVoMapper
|
||||||
|
org.dromara.system.domain.bo.SysClientBoToSysClientMapper
|
||||||
org.dromara.system.domain.bo.SysDictDataBoToSysDictDataMapper
|
org.dromara.system.domain.bo.SysDictDataBoToSysDictDataMapper
|
||||||
org.dromara.hq.domain.vo.HqSatSurveyVoToHqSatSurveyMapper
|
org.dromara.system.domain.SysClientToSysClientVoMapper
|
||||||
org.dromara.system.domain.vo.SysUserVoToSysUserMapper
|
org.dromara.system.domain.vo.SysUserVoToSysUserMapper
|
||||||
org.dromara.system.domain.SysNoticeToSysNoticeVoMapper
|
org.dromara.system.domain.SysNoticeToSysNoticeVoMapper
|
||||||
org.dromara.system.domain.SysOssToSysOssVoMapper
|
org.dromara.system.domain.SysOssToSysOssVoMapper
|
||||||
org.dromara.system.domain.SysOperLogToSysOperLogVoMapper
|
org.dromara.system.domain.SysOperLogToSysOperLogVoMapper
|
||||||
org.dromara.system.domain.bo.SysLogininforBoToSysLogininforMapper
|
org.dromara.system.domain.bo.SysLogininforBoToSysLogininforMapper
|
||||||
|
org.dromara.system.domain.SysTenantToSysTenantVoMapper
|
||||||
org.dromara.system.domain.vo.SysDeptVoToSysDeptMapper
|
org.dromara.system.domain.vo.SysDeptVoToSysDeptMapper
|
||||||
org.dromara.hq.domain.PmRepairCategoryToPmRepairCategoryVoMapper
|
org.dromara.system.domain.vo.SysConfigVoToSysConfigMapper
|
||||||
org.dromara.hq.domain.bo.PmRepairCategoryBoToPmRepairCategoryMapper
|
org.dromara.xg.domain.vo.XgClassInfoVoToXgClassInfoMapper
|
||||||
org.dromara.hq.domain.PmRepairOrderToPmRepairOrderVoMapper
|
org.dromara.system.domain.bo.SysSocialBoToSysSocialMapper
|
||||||
org.dromara.hq.domain.HqSatOptionToHqSatOptionVoMapper
|
|
||||||
org.dromara.hq.domain.vo.PmRepairCategoryVoToPmRepairCategoryMapper
|
|
||||||
org.dromara.system.domain.bo.SysRoleBoToSysRoleMapper
|
org.dromara.system.domain.bo.SysRoleBoToSysRoleMapper
|
||||||
org.dromara.hq.domain.bo.HqSatQuestionBoToHqSatQuestionMapper
|
org.dromara.xg.domain.vo.XgStudentInfoVoToXgStudentInfoMapper
|
||||||
org.dromara.hq.domain.HqSatRecordToHqSatRecordVoMapper
|
org.dromara.system.domain.vo.SysOssVoToSysOssMapper
|
||||||
|
org.dromara.system.domain.SysDictTypeToSysDictTypeVoMapper
|
||||||
org.dromara.system.domain.SysRoleToSysRoleVoMapper
|
org.dromara.system.domain.SysRoleToSysRoleVoMapper
|
||||||
org.dromara.hq.domain.vo.HqSatQuestionVoToHqSatQuestionMapper
|
|
||||||
org.dromara.system.domain.vo.SysTenantPackageVoToSysTenantPackageMapper
|
org.dromara.system.domain.vo.SysTenantPackageVoToSysTenantPackageMapper
|
||||||
|
org.dromara.xg.domain.XgClassStudentToXgClassStudentVoMapper
|
||||||
org.dromara.system.domain.bo.SysTenantBoToSysTenantMapper
|
org.dromara.system.domain.bo.SysTenantBoToSysTenantMapper
|
||||||
org.dromara.system.domain.bo.SysTenantPackageBoToSysTenantPackageMapper
|
org.dromara.system.domain.bo.SysTenantPackageBoToSysTenantPackageMapper
|
||||||
org.dromara.test.domain.bo.XgStuMsgBoToXgStuMsgMapper
|
org.dromara.system.domain.SysLogininforToSysLogininforVoMapper
|
||||||
|
org.dromara.system.domain.vo.SysPostVoToSysPostMapper
|
||||||
|
org.dromara.system.domain.SysSocialToSysSocialVoMapper
|
||||||
|
org.dromara.system.domain.bo.SysDictTypeBoToSysDictTypeMapper
|
||||||
|
org.dromara.common.log.event.OperLogEventToSysOperLogBoMapper
|
||||||
|
org.dromara.xg.domain.bo.XgStudentInfoBoToXgStudentInfoMapper
|
||||||
org.dromara.system.domain.bo.SysOperLogBoToSysOperLogMapper
|
org.dromara.system.domain.bo.SysOperLogBoToSysOperLogMapper
|
||||||
org.dromara.xg.domain.vo.XgAuditRecordVoToXgAuditRecordMapper
|
org.dromara.xg.domain.vo.XgAuditRecordVoToXgAuditRecordMapper
|
||||||
org.dromara.system.domain.vo.SysOperLogVoToSysOperLogMapper
|
org.dromara.system.domain.vo.SysOperLogVoToSysOperLogMapper
|
||||||
org.dromara.system.domain.SysDeptToSysDeptVoMapper
|
org.dromara.system.domain.SysDeptToSysDeptVoMapper
|
||||||
|
org.dromara.system.domain.bo.SysNoticeBoToSysNoticeMapper
|
||||||
org.dromara.xg.domain.XgCollectionBatchToXgCollectionBatchVoMapper
|
org.dromara.xg.domain.XgCollectionBatchToXgCollectionBatchVoMapper
|
||||||
org.dromara.system.domain.SysPostToSysPostVoMapper
|
org.dromara.system.domain.SysPostToSysPostVoMapper
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 320 KiB |
|
After Width: | Height: | Size: 953 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 189 KiB |
|
After Width: | Height: | Size: 139 KiB |
@@ -1,4 +0,0 @@
|
|||||||
测试附件内容
|
|
||||||
创建时间: 6/30/2025, 7:16:26 PM
|
|
||||||
文件用途: 验证附件上传功能
|
|
||||||
测试编号: ATT-1751282186462
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
测试附件内容
|
|
||||||
创建时间: 6/30/2025, 7:17:10 PM
|
|
||||||
文件用途: 验证附件上传功能
|
|
||||||
测试编号: ATT-1751282230141
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
测试附件内容
|
|
||||||
创建时间: 6/30/2025, 7:17:38 PM
|
|
||||||
文件用途: 验证附件上传功能
|
|
||||||
测试编号: ATT-1751282258774
|
|
||||||
@@ -1,84 +1,39 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import { AxiosPromise } from 'axios';
|
import { HallReservationVO, HallReservationQuery } from '../hallReservation/types';
|
||||||
import { HallReservationVO, HallReservationForm, HallReservationQuery } from '@/api/hq/hallReservation/types';
|
import { HallReservationAuditForm, TimeCheckParams, TimeCheckResult } from './types';
|
||||||
|
import { TableDataInfo, R } from '@/api/types';
|
||||||
|
|
||||||
/**
|
// 查询报告厅预约列表
|
||||||
* 查询报告厅预约列表
|
export function listHallReservation(query: HallReservationQuery) {
|
||||||
* @param query
|
return request<TableDataInfo<HallReservationVO>>({
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const listHallReservation = (query?: HallReservationQuery): AxiosPromise<HallReservationVO[]> => {
|
|
||||||
return request({
|
|
||||||
url: '/hq/hallReservation/list',
|
url: '/hq/hallReservation/list',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
// 获取报告厅预约详细信息
|
||||||
* 查询报告厅预约详细
|
export function getHallReservation(id: string | number) {
|
||||||
* @param id
|
return request<R<HallReservationVO>>({
|
||||||
*/
|
|
||||||
export const getHallReservation = (id: string | number): AxiosPromise<HallReservationVO> => {
|
|
||||||
return request({
|
|
||||||
url: '/hq/hallReservation/' + id,
|
url: '/hq/hallReservation/' + id,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增报告厅预约
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const addHallReservation = (data: HallReservationForm) => {
|
|
||||||
return request({
|
|
||||||
url: '/hq/hallReservation',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改报告厅预约
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const updateHallReservation = (data: HallReservationForm) => {
|
|
||||||
return request({
|
|
||||||
url: '/hq/hallReservation',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除报告厅预约
|
|
||||||
* @param id
|
|
||||||
*/
|
|
||||||
export const delHallReservation = (id: string | number | Array<string | number>) => {
|
|
||||||
return request({
|
|
||||||
url: '/hq/hallReservation/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核报告厅预约(批准/拒绝)
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export interface HallReservationAuditForm {
|
|
||||||
/** 预约记录ID列表 */
|
|
||||||
ids: Array<string | number>;
|
|
||||||
/** 审核状态:1-批准,2-拒绝 */
|
|
||||||
status: string;
|
|
||||||
/** 审核备注 */
|
|
||||||
auditRemark?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const auditHallReservation = (data: HallReservationAuditForm) => {
|
// 审核报告厅预约
|
||||||
return request({
|
export function auditHallReservation(data: HallReservationAuditForm) {
|
||||||
|
return request<R<any>>({
|
||||||
url: '/hq/hallReservation/audit',
|
url: '/hq/hallReservation/audit',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// 检查报告厅预约时间是否存在冲突
|
||||||
|
export function checkTimeConflict(data: TimeCheckParams) {
|
||||||
|
return request<R<TimeCheckResult>>({
|
||||||
|
url: '/hq/hallReservation/checkTimeConflict',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,200 +1,39 @@
|
|||||||
export interface HallReservationVO {
|
import { HallReservationVO } from '../hallReservation/types';
|
||||||
/**
|
|
||||||
* 主键ID
|
|
||||||
*/
|
|
||||||
id: string | number;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报告厅ID
|
* 报告厅预约审核表单
|
||||||
*/
|
|
||||||
hallId: string | number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 报告厅名称
|
|
||||||
*/
|
|
||||||
hallName: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
startTime: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束时间
|
|
||||||
*/
|
|
||||||
endTime: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 预约用途
|
|
||||||
*/
|
|
||||||
reservationPurpose: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请人id
|
|
||||||
*/
|
|
||||||
applicantId: string | number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请人姓名
|
|
||||||
*/
|
|
||||||
applicantName: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请人电话
|
|
||||||
*/
|
|
||||||
applicantPhone: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 预约状态
|
|
||||||
*/
|
*/
|
||||||
|
export interface HallReservationAuditForm {
|
||||||
|
/** 预约ID列表 */
|
||||||
|
ids: Array<string | number>;
|
||||||
|
/** 审核状态 */
|
||||||
status: string;
|
status: string;
|
||||||
|
/** 审核备注 */
|
||||||
/**
|
|
||||||
* 审核人id
|
|
||||||
*/
|
|
||||||
auditBy: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核人
|
|
||||||
*/
|
|
||||||
auditName: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核时间
|
|
||||||
*/
|
|
||||||
auditTime: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核备注
|
|
||||||
*/
|
|
||||||
auditRemark: string;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HallReservationForm extends BaseEntity {
|
|
||||||
/**
|
|
||||||
* 主键ID
|
|
||||||
*/
|
|
||||||
id?: string | number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 报告厅ID
|
|
||||||
*/
|
|
||||||
hallId?: string | number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 报告厅名称
|
|
||||||
*/
|
|
||||||
hallName?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
startTime?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束时间
|
|
||||||
*/
|
|
||||||
endTime?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 预约用途
|
|
||||||
*/
|
|
||||||
reservationPurpose?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请人id
|
|
||||||
*/
|
|
||||||
applicantId?: string | number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请人姓名
|
|
||||||
*/
|
|
||||||
applicantName?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请人电话
|
|
||||||
*/
|
|
||||||
applicantPhone?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 预约状态
|
|
||||||
*/
|
|
||||||
status?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核人id
|
|
||||||
*/
|
|
||||||
auditBy?: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核人
|
|
||||||
*/
|
|
||||||
auditName?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核时间
|
|
||||||
*/
|
|
||||||
auditTime?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核备注
|
|
||||||
*/
|
|
||||||
auditRemark?: string;
|
auditRemark?: string;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HallReservationQuery extends PageQuery {
|
/**
|
||||||
|
* 时间冲突检查参数
|
||||||
|
*/
|
||||||
|
export interface TimeCheckParams {
|
||||||
|
/** 报告厅ID */
|
||||||
|
hallId: string | number;
|
||||||
|
/** 预约开始时间 */
|
||||||
|
startTime: string;
|
||||||
|
/** 预约结束时间 */
|
||||||
|
endTime: string;
|
||||||
|
/** 排除的预约ID */
|
||||||
|
excludeId?: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报告厅ID
|
* 时间冲突检查结果
|
||||||
*/
|
*/
|
||||||
hallId?: string | number;
|
export interface TimeCheckResult {
|
||||||
|
/** 是否存在冲突 */
|
||||||
/**
|
hasConflict: boolean;
|
||||||
* 报告厅名称
|
/** 冲突的预约列表 */
|
||||||
*/
|
conflictList: HallReservationVO[];
|
||||||
hallName?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
startTime?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束时间
|
|
||||||
*/
|
|
||||||
endTime?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始时间查询参数(字符串格式)
|
|
||||||
*/
|
|
||||||
startTimeStr?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束时间查询参数(字符串格式)
|
|
||||||
*/
|
|
||||||
endTimeStr?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请人ID
|
|
||||||
*/
|
|
||||||
applicantId?: string | number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请人姓名
|
|
||||||
*/
|
|
||||||
applicantName?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 预约状态
|
|
||||||
*/
|
|
||||||
status?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 日期范围参数
|
|
||||||
*/
|
|
||||||
params?: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
import { RepairCategoryVO, RepairCategoryForm, RepairCategoryQuery } from '@/api/hq/hq/pm/types';
|
import { RepairCategoryVO, RepairCategoryForm, RepairCategoryQuery } from '@/api/hq/pm/types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询维修类型列表
|
* 查询维修类型列表
|
||||||
|
|||||||
@@ -209,6 +209,19 @@ export const deptTreeSelect = (): AxiosPromise<DeptTreeVO[]> => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 获取具有指定权限的用户列表 */
|
||||||
|
export function listUsersByPermission(permission: string, tenantId?: string): AxiosPromise<UserVO[]> {
|
||||||
|
return request({
|
||||||
|
url: '/system/user/list-by-permission',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
permission,
|
||||||
|
tenantId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
listUser,
|
listUser,
|
||||||
getUser,
|
getUser,
|
||||||
@@ -225,5 +238,6 @@ export default {
|
|||||||
getAuthRole,
|
getAuthRole,
|
||||||
updateAuthRole,
|
updateAuthRole,
|
||||||
deptTreeSelect,
|
deptTreeSelect,
|
||||||
listUserByDeptId
|
listUserByDeptId,
|
||||||
|
listUsersByPermission
|
||||||
};
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752052172719" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8134" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M756.01248 336.814072l-20.336164 0 0 510.696308-67.101257 0L668.575058 336.814072 556.73383 336.814072l0 510.696308-67.106374 0L489.627457 336.814072 377.791345 336.814072l0 510.696308-67.102281 0L310.689065 336.814072l-42.702568 0c-50.532907 0-91.50711-0.727571-91.50711 0l0 533.587668c0 49.123814 40.974203 88.944751 91.50711 88.944751l488.019843 0c50.544163 0 91.50097-39.820937 91.50097-88.944751L847.50731 336.814072C847.512427 333.065701 806.562782 336.814072 756.01248 336.814072L756.01248 336.814072zM891.467521 176.488597 690.943508 176.488597l0-54.57292c0-31.630395-56.529481-57.263192-89.479941-57.263192L422.525176 64.652486c-32.933063 0-89.468684 25.632797-89.468684 57.263192l0 54.57292L132.566248 176.488597c-25.160029 0-45.548382 20.033265-45.548382 44.740994 0 24.695448 20.382213 44.727691 45.548382 44.727691L891.467521 265.957281c25.137517 0 45.514613-20.032242 45.514613-44.727691C936.975994 196.521862 916.593781 176.488597 891.467521 176.488597L891.467521 176.488597zM601.468684 176.488597 422.530292 176.488597l0-22.367427 178.938392 0L601.468684 176.488597 601.468684 176.488597zM601.468684 176.488597" fill="#272636" p-id="8135"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752052134276" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5447" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M220.094304 322.742967l247.380709-82.457849c33.513211-11.171411 70.457561-2.450813 95.438462 22.529064l198.273366 198.270297c24.979878 24.977831 33.704569 61.924228 22.534181 95.439485l-82.463989 247.376616a93.251661 93.251661 0 0 1-64.445649 60.616444L63.720126 1017.340337c-24.88164 6.634081-50.436615-8.158804-57.070696-33.040445a46.613551 46.613551 0 0 1 0-24.028205L159.471719 387.186569a93.250638 93.250638 0 0 1 60.622585-64.443602m125.403877 420.158452a91.065883 91.065883 0 0 1 70.947724-26.441156c1.682312 0.12075 3.266387 0.181125 4.754271 0.181125 62.869761 0 113.84054-50.966687 113.84054-113.842587 0-62.87283-50.97078-113.841564-113.84054-113.841564-62.87283 0-113.84361 50.968733-113.84361 113.841564 0 1.490954 0.061398 3.072982 0.182148 4.752224a91.080209 91.080209 0 0 1-26.437063 70.94977L156.663773 802.936627c-17.781956 17.781956-17.781956 46.617644 0 64.398577 17.781956 17.784003 46.615597 17.784003 64.401647 0l124.432761-124.433785zM579.671104 80.436823c100.483351-100.484375 263.404629-100.484375 363.89105 0 100.484375 100.485398 100.484375 263.404629 0 363.890027-28.784523 28.784523-75.449239 28.784523-104.229668 0L579.671104 184.666491c-28.783499-28.781453-28.783499-75.448215 0-104.229668" fill="#040000" p-id="5448"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752052118757" class="icon" viewBox="0 0 1829 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4426" xmlns:xlink="http://www.w3.org/1999/xlink" width="357.2265625" height="200"><path d="M914.297945 0C314.456393 0 0 441.928431 0 512.019026c0 70.052544 314.456393 511.980974 914.297945 511.980974 599.8035 0 914.297945-441.928431 914.297945-511.980974C1828.633942 441.928431 1514.101446 0 914.297945 0zM914.297945 905.888596c-224.46494 0-406.388466-176.329977-406.388466-393.86957 0-217.539593 181.923526-393.86957 406.388466-393.86957 224.426889 0 406.388466 176.291925 406.388466 393.86957C1320.686411 729.558619 1138.762885 905.888596 914.297945 905.888596zM914.297945 512.019026c-37.252276-40.867155 60.653859-196.953811 0-196.953811-112.213444 0-203.194233 88.20304-203.194233 196.953811s90.980789 196.915759 203.194233 196.915759c112.175393 0 203.194233-88.164988 203.194233-196.915759C1117.492178 462.057597 945.918621 546.759912 914.297945 512.019026z" fill="#090909" p-id="4427"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -1686,3 +1686,8 @@ body {
|
|||||||
outline: none !important;
|
outline: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 隐藏图片上传列表的删除按钮
|
||||||
|
.el-upload-list--picture-card .el-upload-list__item .el-icon--close {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
@@ -441,12 +441,13 @@ img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 禁用状态
|
// 禁用状态
|
||||||
.disabled,
|
// 禁用状态取消,让分页组件可以点击跳转
|
||||||
[disabled] {
|
// .disabled,
|
||||||
opacity: 0.6;
|
// [disabled] {
|
||||||
cursor: not-allowed;
|
// opacity: 0.6;
|
||||||
pointer-events: none;
|
// cursor: not-allowed;
|
||||||
}
|
// pointer-events: none;
|
||||||
|
// }
|
||||||
|
|
||||||
// 加载状态
|
// 加载状态
|
||||||
.loading {
|
.loading {
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
:root {
|
:root {
|
||||||
// Theme color
|
// Theme color
|
||||||
// --art-primary: 50, 50, 222;
|
// --art-primary: 50, 50, 222;
|
||||||
--art-primary: 93, 135, 255;
|
// --art-primary: 93, 135, 255;
|
||||||
|
--art-primary: 0, 58, 255;
|
||||||
--art-secondary: 73, 190, 255;
|
--art-secondary: 73, 190, 255;
|
||||||
--art-error: 250, 137, 107;
|
--art-error: 250, 137, 107;
|
||||||
--art-info: 0, 75, 178;
|
--art-info: 0, 75, 178;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
:to="{ path: tag.path ? tag.path : '', query: tag.query }"
|
:to="{ path: tag.path ? tag.path : '', query: tag.query }"
|
||||||
class="tags-view-item"
|
class="tags-view-item"
|
||||||
:style="activeStyle(tag)"
|
:style="activeStyle(tag)"
|
||||||
|
@click="handleTagClick(tag, $event)"
|
||||||
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
|
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
|
||||||
@contextmenu.prevent="openMenu(tag, $event)"
|
@contextmenu.prevent="openMenu(tag, $event)"
|
||||||
>
|
>
|
||||||
@@ -232,6 +233,27 @@ const handleScroll = () => {
|
|||||||
closeMenu();
|
closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 点击标签时,如果标签已激活,则执行刷新操作
|
||||||
|
const handleTagClick = (tag: RouteLocationNormalized, e: MouseEvent) => {
|
||||||
|
// 阻止 router-link 默认行为,统一由脚本控制导航和刷新
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (isActive(tag)) {
|
||||||
|
// 当前已激活,直接刷新
|
||||||
|
refreshSelectedTag(tag);
|
||||||
|
} else {
|
||||||
|
// 尚未激活,先导航到对应路由,导航成功后再刷新
|
||||||
|
router
|
||||||
|
.push({ path: tag.path || '', query: tag.query })
|
||||||
|
.then(() => {
|
||||||
|
refreshSelectedTag(tag);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
/* 忽略重复导航错误 */
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initTags();
|
initTags();
|
||||||
addTags();
|
addTags();
|
||||||
|
|||||||
@@ -3,31 +3,65 @@
|
|||||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
|
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
|
||||||
<el-card shadow="hover">
|
<el-card shadow="hover">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
|
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||||
<el-form-item label="报告厅ID" prop="hallId">
|
<!-- 第一行:4个检索元素 -->
|
||||||
<el-input v-model="queryParams.hallId" placeholder="请输入报告厅ID" clearable @keyup.enter="handleQuery" />
|
<el-row :gutter="20">
|
||||||
</el-form-item>
|
<el-col :span="6">
|
||||||
<el-form-item label="报告厅名称" prop="hallName">
|
<el-form-item label="报告厅名称" prop="hallName">
|
||||||
<el-input v-model="queryParams.hallName" placeholder="请输入报告厅名称" clearable @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.hallName" placeholder="请输入报告厅名称" clearable @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="预约开始时间" prop="startTime">
|
<el-form-item label="预约开始时间" prop="startTime">
|
||||||
<el-date-picker clearable v-model="queryParams.startTime" type="date" placeholder="请选择开始时间" value-format="YYYY-MM-DD" />
|
<el-date-picker
|
||||||
|
clearable
|
||||||
|
v-model="queryParams.startTime"
|
||||||
|
type="date"
|
||||||
|
placeholder="请选择开始时间"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="预约结束时间" prop="endTime">
|
<el-form-item label="预约结束时间" prop="endTime">
|
||||||
<el-date-picker clearable v-model="queryParams.endTime" type="date" placeholder="请选择结束时间" value-format="YYYY-MM-DD" />
|
<el-date-picker
|
||||||
|
clearable
|
||||||
|
v-model="queryParams.endTime"
|
||||||
|
type="date"
|
||||||
|
placeholder="请选择结束时间"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="申请人姓名" prop="applicantName">
|
<el-form-item label="申请人姓名" prop="applicantName">
|
||||||
<el-input v-model="queryParams.applicantName" placeholder="请输入申请人姓名" clearable @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.applicantName" placeholder="请输入申请人姓名" clearable @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第二行:剩余检索元素 -->
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="预约状态" prop="status">
|
<el-form-item label="预约状态" prop="status">
|
||||||
<el-select v-model="queryParams.status" placeholder="请选择预约状态" clearable>
|
<el-select v-model="queryParams.status" placeholder="请选择预约状态" clearable style="width: 100%">
|
||||||
<el-option v-for="dict in hall_reserv_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
<el-option v-for="dict in hall_reserv_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 操作按钮行 -->
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" class="search-btn-container">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,7 +87,14 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table v-loading="loading" border :data="hallReservationList" @selection-change="handleSelectionChange" style="margin-bottom: 0">
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
border
|
||||||
|
:data="hallReservationList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@row-dblclick="handleView"
|
||||||
|
style="margin-bottom: 0"
|
||||||
|
>
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="报告厅ID" align="center" prop="hallId" />
|
<el-table-column label="报告厅ID" align="center" prop="hallId" />
|
||||||
<el-table-column label="报告厅名称" align="center" prop="hallName" />
|
<el-table-column label="报告厅名称" align="center" prop="hallName" />
|
||||||
@@ -80,13 +121,9 @@
|
|||||||
:hide-after="100"
|
:hide-after="100"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
>
|
>
|
||||||
<span class="purpose-text">
|
<div class="purpose-text line-clamp-3">
|
||||||
{{
|
{{ scope.row.reservationPurpose }}
|
||||||
scope.row.reservationPurpose && scope.row.reservationPurpose.length > 100
|
</div>
|
||||||
? scope.row.reservationPurpose.substring(0, 100) + '...'
|
|
||||||
: scope.row.reservationPurpose
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -112,17 +149,13 @@
|
|||||||
:hide-after="100"
|
:hide-after="100"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
>
|
>
|
||||||
<span class="audit-remark-text">
|
<div class="audit-remark-text line-clamp-3">
|
||||||
{{
|
{{ scope.row.auditRemark }}
|
||||||
scope.row.auditRemark && scope.row.auditRemark.length > 100
|
</div>
|
||||||
? scope.row.auditRemark.substring(0, 100) + '...'
|
|
||||||
: scope.row.auditRemark
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- 查看按钮,所有记录都可以查看 -->
|
<!-- 查看按钮,所有记录都可以查看 -->
|
||||||
<el-tooltip content="查看" placement="top">
|
<el-tooltip content="查看" placement="top">
|
||||||
@@ -180,9 +213,9 @@
|
|||||||
<span class="form-text">{{ viewForm.hallName }}</span>
|
<span class="form-text">{{ viewForm.hallName }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 报告厅图片展示区域 -->
|
<!-- 报告厅图片展示区域 -->
|
||||||
<el-form-item label="报告厅图片" v-if="viewHallImages.length > 0">
|
<el-form-item label="报告厅图片">
|
||||||
<div class="view-hall-images">
|
<div class="view-hall-images">
|
||||||
<div class="image-gallery">
|
<div class="image-gallery" v-if="viewHallImages.length > 0">
|
||||||
<div v-for="(image, index) in viewHallImages" :key="index" class="image-item" @click="previewImage(image, index)">
|
<div v-for="(image, index) in viewHallImages" :key="index" class="image-item" @click="previewImage(image, index)">
|
||||||
<img :src="image" class="gallery-image" @error="handleImageError" />
|
<img :src="image" class="gallery-image" @error="handleImageError" />
|
||||||
<div class="image-overlay">
|
<div class="image-overlay">
|
||||||
@@ -190,6 +223,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="no-images-placeholder">
|
||||||
|
<el-icon><Picture /></el-icon>
|
||||||
|
<span>暂无图片</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="预约开始时间">
|
<el-form-item label="预约开始时间">
|
||||||
@@ -265,8 +302,7 @@
|
|||||||
<div class="reservation-details">
|
<div class="reservation-details">
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span class="detail-label">申请人:</span>
|
<span class="detail-label">申请人:</span>
|
||||||
<span class="detail-value">{{ record.applicantName }}</span>
|
<span class="detail-value"> {{ record.applicantName }}({{ record.applicantPhone || '手机号暂无' }}) </span>
|
||||||
<span class="detail-phone">({{ record.applicantPhone || '手机号暂无' }})</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span class="detail-label">预约时间:</span>
|
<span class="detail-label">预约时间:</span>
|
||||||
@@ -278,6 +314,46 @@
|
|||||||
<span class="detail-label">预约用途:</span>
|
<span class="detail-label">预约用途:</span>
|
||||||
<span class="detail-value purpose-content">{{ record.reservationPurpose }}</span>
|
<span class="detail-value purpose-content">{{ record.reservationPurpose }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">审核建议:</span>
|
||||||
|
<span class="detail-value audit-suggestion-content" :class="getConflictStatusClass(record)">
|
||||||
|
<template v-if="getConflictCheckStatus(record).isLoading">
|
||||||
|
<el-icon class="rotate-loading"><Loading /></el-icon> 正在检查时间冲突...
|
||||||
|
</template>
|
||||||
|
<template v-else-if="getConflictCheckStatus(record).hasError">
|
||||||
|
<el-icon class="text-warning"><Warning /></el-icon> 冲突检查失败,请手动核实
|
||||||
|
</template>
|
||||||
|
<template v-else-if="hasTimeConflict(record)">
|
||||||
|
<el-icon class="text-danger"><Warning /></el-icon> 发现时间冲突,建议拒绝
|
||||||
|
<div class="conflict-details" v-if="getConflictReservations(record).length > 0">
|
||||||
|
<small>冲突详情:</small>
|
||||||
|
<ul class="conflict-list">
|
||||||
|
<li v-for="conflict in getConflictReservations(record)" :key="conflict.id">
|
||||||
|
<el-tag type="warning" size="small" v-if="conflict.internal">本次批次</el-tag>
|
||||||
|
<el-tag type="info" size="small" v-else>已审批</el-tag>
|
||||||
|
{{ conflict.applicantName }} ({{ parseTime(conflict.startTime, '{h}:{i}') }}-{{
|
||||||
|
parseTime(conflict.endTime, '{h}:{i}')
|
||||||
|
}})
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="getConflictCheckStatus(record).isChecked">
|
||||||
|
<el-icon class="text-success"><Check /></el-icon> 无时间冲突,可以批准
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-icon class="text-info"><InfoFilled /></el-icon> 未检查时间冲突
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
@click="manualCheckConflict(record)"
|
||||||
|
:loading="getConflictCheckStatus(record).isLoading"
|
||||||
|
>
|
||||||
|
立即检查
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -294,6 +370,22 @@
|
|||||||
{{ auditForm.status === '1' ? '批准' : '拒绝' }}
|
{{ auditForm.status === '1' ? '批准' : '拒绝' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 批准时显示冲突检查统计 -->
|
||||||
|
<div v-if="auditForm.status === '1'" class="conflict-summary">
|
||||||
|
<span class="audit-label">冲突检查统计:</span>
|
||||||
|
<div class="summary-stats">
|
||||||
|
<el-tag type="info" size="small"> 总计:{{ selectedRecords.length }} 个预约 </el-tag>
|
||||||
|
<el-tag type="success" size="small"> 无冲突:{{ getNoConflictCount() }} 个 </el-tag>
|
||||||
|
<el-tag type="danger" size="small" v-if="getConflictCount() > 0"> 有冲突:{{ getConflictCount() }} 个 </el-tag>
|
||||||
|
<el-tag type="warning" size="small" v-if="getUncheckCount() > 0"> 未检查:{{ getUncheckCount() }} 个 </el-tag>
|
||||||
|
</div>
|
||||||
|
<div v-if="getConflictCount() > 0" class="conflict-warning-text">
|
||||||
|
<el-icon><Warning /></el-icon>
|
||||||
|
建议先处理时间冲突的预约,或选择拒绝有冲突的申请
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="audit-remark-section">
|
<div class="audit-remark-section">
|
||||||
<span class="audit-label">审核备注:</span>
|
<span class="audit-label">审核备注:</span>
|
||||||
<el-input
|
<el-input
|
||||||
@@ -320,7 +412,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="HallAudit" lang="ts">
|
<script setup name="HallAudit" lang="ts">
|
||||||
import { listHallReservation, getHallReservation, auditHallReservation, HallReservationAuditForm } from '@/api/hq/hallAudit';
|
import { listHallReservation, getHallReservation, auditHallReservation, HallReservationAuditForm, checkTimeConflict } from '@/api/hq/hallAudit';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
import { listHallInfo } from '@/api/hq/hallInfo';
|
import { listHallInfo } from '@/api/hq/hallInfo';
|
||||||
import { HallReservationVO, HallReservationQuery, HallReservationForm } from '@/api/hq/hallReservation/types';
|
import { HallReservationVO, HallReservationQuery, HallReservationForm } from '@/api/hq/hallReservation/types';
|
||||||
import { HallInfoVO } from '@/api/hq/hallInfo/types';
|
import { HallInfoVO } from '@/api/hq/hallInfo/types';
|
||||||
@@ -385,6 +478,10 @@ const auditForm = ref({
|
|||||||
const selectedRecords = ref<HallReservationVO[]>([]);
|
const selectedRecords = ref<HallReservationVO[]>([]);
|
||||||
const auditLoading = ref(false);
|
const auditLoading = ref(false);
|
||||||
|
|
||||||
|
// 审核建议相关状态
|
||||||
|
const conflictCheckResults = reactive(new Map<string | number, any>());
|
||||||
|
const conflictCheckLoading = reactive(new Set<string | number>());
|
||||||
|
|
||||||
const queryParams = ref<HallReservationQuery>({
|
const queryParams = ref<HallReservationQuery>({
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -430,7 +527,7 @@ const getHallList = async () => {
|
|||||||
const getHallImages = (imageUrl: string): string[] => {
|
const getHallImages = (imageUrl: string): string[] => {
|
||||||
if (!imageUrl || imageUrl.trim() === '') return [];
|
if (!imageUrl || imageUrl.trim() === '') return [];
|
||||||
// 支持多种分隔符:逗号、分号、空格
|
// 支持多种分隔符:逗号、分号、空格
|
||||||
const separators = /[,;|\s]+/;
|
const separators = /[,;|\\s]+/;
|
||||||
const images = imageUrl
|
const images = imageUrl
|
||||||
.split(separators)
|
.split(separators)
|
||||||
.map((url) => url.trim())
|
.map((url) => url.trim())
|
||||||
@@ -680,13 +777,22 @@ const handleReject = async (row?: HallReservationVO) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** 打开审核对话框 */
|
/** 打开审核对话框 */
|
||||||
const openAuditDialog = (status: string, ids: Array<string | number>, records: HallReservationVO[], title: string) => {
|
const openAuditDialog = async (status: string, ids: Array<string | number>, records: HallReservationVO[], title: string) => {
|
||||||
auditForm.value.status = status;
|
auditForm.value.status = status;
|
||||||
auditForm.value.auditRemark = '';
|
auditForm.value.auditRemark = '';
|
||||||
auditForm.value.ids = ids;
|
auditForm.value.ids = ids;
|
||||||
selectedRecords.value = records;
|
selectedRecords.value = records;
|
||||||
auditDialog.title = title;
|
auditDialog.title = title;
|
||||||
auditDialog.visible = true;
|
auditDialog.visible = true;
|
||||||
|
|
||||||
|
// 在打开审核对话框时统一检查时间冲突(无论批准/拒绝)
|
||||||
|
// 清除选中记录旧的缓存(尤其是 internal 冲突信息)
|
||||||
|
records.forEach((rec) => conflictCheckResults.delete(rec.id));
|
||||||
|
|
||||||
|
if (records.length > 0) {
|
||||||
|
console.log('审核对话框打开,开始检查时间冲突...');
|
||||||
|
await batchCheckTimeConflict(records);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 确认审核操作 */
|
/** 确认审核操作 */
|
||||||
@@ -753,6 +859,242 @@ const handleExport = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 检查单个记录的时间冲突 */
|
||||||
|
const checkRecordTimeConflict = async (record: HallReservationVO) => {
|
||||||
|
const recordId = record.id;
|
||||||
|
|
||||||
|
// 如果已经在检查中,跳过
|
||||||
|
if (conflictCheckLoading.has(recordId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已有缓存结果,直接返回
|
||||||
|
if (conflictCheckResults.has(recordId)) {
|
||||||
|
return conflictCheckResults.get(recordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
conflictCheckLoading.add(recordId);
|
||||||
|
|
||||||
|
const res = await checkTimeConflict({
|
||||||
|
hallId: record.hallId,
|
||||||
|
startTime: dayjs(record.startTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
endTime: dayjs(record.endTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
excludeId: record.id
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
hasConflict: res.data.hasConflict,
|
||||||
|
conflictList: (res.data.conflictList || []).map((item: any) => ({ ...item, internal: false })),
|
||||||
|
conflictMessage: res.data.conflictMessage || '',
|
||||||
|
checkTime: new Date().getTime()
|
||||||
|
};
|
||||||
|
|
||||||
|
// 缓存结果
|
||||||
|
conflictCheckResults.set(recordId, result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查时间冲突失败:', error);
|
||||||
|
const errorResult = {
|
||||||
|
hasConflict: false,
|
||||||
|
conflictList: [],
|
||||||
|
conflictMessage: '冲突检查失败',
|
||||||
|
checkTime: new Date().getTime(),
|
||||||
|
error: true
|
||||||
|
};
|
||||||
|
conflictCheckResults.set(recordId, errorResult);
|
||||||
|
return errorResult;
|
||||||
|
} finally {
|
||||||
|
conflictCheckLoading.delete(recordId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 批量检查选中记录的时间冲突 */
|
||||||
|
const batchCheckTimeConflict = async (records: HallReservationVO[]) => {
|
||||||
|
console.log('开始批量检查时间冲突,记录数:', records.length);
|
||||||
|
|
||||||
|
const promises = records.map((record) => checkRecordTimeConflict(record));
|
||||||
|
await Promise.all(promises);
|
||||||
|
|
||||||
|
// 前端额外校验勾选记录之间的时间交叉冲突(同一报告厅)
|
||||||
|
addInternalConflictInfo(records);
|
||||||
|
|
||||||
|
console.log('批量时间冲突检查完成');
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 判断两个时间段是否重叠 */
|
||||||
|
const isTimeOverlap = (startA: any, endA: any, startB: any, endB: any) => {
|
||||||
|
const sA = dayjs(startA);
|
||||||
|
const eA = dayjs(endA);
|
||||||
|
const sB = dayjs(startB);
|
||||||
|
const eB = dayjs(endB);
|
||||||
|
return sA.isBefore(eB) && sB.isBefore(eA); // 开始 < 另一结束 且 另一开始 < 结束
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 在选中记录之间标记内部冲突 */
|
||||||
|
const addInternalConflictInfo = (records: HallReservationVO[]) => {
|
||||||
|
// 若不足两条记录无需内部冲突检测
|
||||||
|
if (records.length < 2) return;
|
||||||
|
|
||||||
|
const hallGroups: Record<string, HallReservationVO[]> = {};
|
||||||
|
records.forEach((rec) => {
|
||||||
|
const key = `${rec.hallId || ''}`;
|
||||||
|
hallGroups[key] = hallGroups[key] || [];
|
||||||
|
hallGroups[key].push(rec);
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.values(hallGroups).forEach((list) => {
|
||||||
|
// 对同一报告厅的申请做两两比较
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
for (let j = i + 1; j < list.length; j++) {
|
||||||
|
const r1 = list[i];
|
||||||
|
const r2 = list[j];
|
||||||
|
if (isTimeOverlap(r1.startTime, r1.endTime, r2.startTime, r2.endTime)) {
|
||||||
|
// r1 冲突信息
|
||||||
|
const res1 = conflictCheckResults.get(r1.id) || {
|
||||||
|
hasConflict: false,
|
||||||
|
conflictList: [],
|
||||||
|
conflictMessage: '',
|
||||||
|
checkTime: new Date().getTime()
|
||||||
|
};
|
||||||
|
res1.hasConflict = true;
|
||||||
|
res1.conflictList.push({ ...r2, internal: true });
|
||||||
|
conflictCheckResults.set(r1.id, res1);
|
||||||
|
|
||||||
|
// r2 冲突信息
|
||||||
|
const res2 = conflictCheckResults.get(r2.id) || {
|
||||||
|
hasConflict: false,
|
||||||
|
conflictList: [],
|
||||||
|
conflictMessage: '',
|
||||||
|
checkTime: new Date().getTime()
|
||||||
|
};
|
||||||
|
res2.hasConflict = true;
|
||||||
|
res2.conflictList.push({ ...r1, internal: true });
|
||||||
|
conflictCheckResults.set(r2.id, res2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取记录的冲突检查结果 */
|
||||||
|
const getConflictResult = (record: HallReservationVO) => {
|
||||||
|
return (
|
||||||
|
conflictCheckResults.get(record.id) || {
|
||||||
|
hasConflict: false,
|
||||||
|
conflictList: [],
|
||||||
|
conflictMessage: '未检查',
|
||||||
|
checkTime: 0
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 检查是否存在时间冲突(同步方法) */
|
||||||
|
const hasTimeConflict = (record: HallReservationVO): boolean => {
|
||||||
|
const result = getConflictResult(record);
|
||||||
|
return result.hasConflict;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取时间冲突的预约列表(同步方法) */
|
||||||
|
const getConflictReservations = (record: HallReservationVO) => {
|
||||||
|
const result = getConflictResult(record);
|
||||||
|
return result.conflictList || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取冲突检查状态 */
|
||||||
|
const getConflictCheckStatus = (record: HallReservationVO) => {
|
||||||
|
const isLoading = conflictCheckLoading.has(record.id);
|
||||||
|
const result = getConflictResult(record);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isLoading,
|
||||||
|
isChecked: result.checkTime > 0,
|
||||||
|
hasError: result.error || false,
|
||||||
|
result
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取冲突状态对应的CSS类 */
|
||||||
|
const getConflictStatusClass = (record: HallReservationVO) => {
|
||||||
|
const status = getConflictCheckStatus(record);
|
||||||
|
|
||||||
|
if (status.isLoading) {
|
||||||
|
return 'checking-conflict';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.hasError) {
|
||||||
|
return 'check-error';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.isChecked) {
|
||||||
|
return hasTimeConflict(record) ? 'has-conflict' : 'no-conflict';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'not-checked';
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取审核建议文本 */
|
||||||
|
const getAuditSuggestionText = (record: HallReservationVO) => {
|
||||||
|
const status = getConflictCheckStatus(record);
|
||||||
|
|
||||||
|
if (status.isLoading) {
|
||||||
|
return '正在检查时间冲突...';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.hasError) {
|
||||||
|
return '冲突检查失败,请手动核实';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.isChecked) {
|
||||||
|
return hasTimeConflict(record) ? '发现时间冲突,建议拒绝' : '无时间冲突,可以批准';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '未检查时间冲突';
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 手动触发时间冲突检查 */
|
||||||
|
const manualCheckConflict = async (record: HallReservationVO) => {
|
||||||
|
// 清除缓存,强制重新检查
|
||||||
|
conflictCheckResults.delete(record.id);
|
||||||
|
await checkRecordTimeConflict(record);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取无冲突的预约数量 */
|
||||||
|
const getNoConflictCount = () => {
|
||||||
|
return selectedRecords.value.filter((record) => {
|
||||||
|
const status = getConflictCheckStatus(record);
|
||||||
|
return status.isChecked && !hasTimeConflict(record);
|
||||||
|
}).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取有冲突的预约数量 */
|
||||||
|
const getConflictCount = () => {
|
||||||
|
return selectedRecords.value.filter((record) => {
|
||||||
|
const status = getConflictCheckStatus(record);
|
||||||
|
return status.isChecked && hasTimeConflict(record);
|
||||||
|
}).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取未检查的预约数量 */
|
||||||
|
const getUncheckCount = () => {
|
||||||
|
return selectedRecords.value.filter((record) => {
|
||||||
|
const status = getConflictCheckStatus(record);
|
||||||
|
return !status.isChecked && !status.isLoading;
|
||||||
|
}).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取预约状态文本 */
|
||||||
|
const getStatusText = (status: string) => {
|
||||||
|
const statusMap: { [key: string]: string } = {
|
||||||
|
'0': '审核中',
|
||||||
|
'1': '已批准',
|
||||||
|
'2': '已拒绝'
|
||||||
|
};
|
||||||
|
return statusMap[status] || status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 页面加载完成后的初始化 */
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList();
|
getList();
|
||||||
getHallList();
|
getHallList();
|
||||||
@@ -855,22 +1197,31 @@ onMounted(() => {
|
|||||||
|
|
||||||
/* 表格中预约用途文本样式 */
|
/* 表格中预约用途文本样式 */
|
||||||
.purpose-text {
|
.purpose-text {
|
||||||
display: inline-block;
|
display: -webkit-box;
|
||||||
max-width: 100%;
|
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding: 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 表格中审核备注文本样式 */
|
/* 表格中审核备注文本样式 */
|
||||||
.audit-remark-text {
|
.audit-remark-text {
|
||||||
display: inline-block;
|
display: -webkit-box;
|
||||||
max-width: 100%;
|
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 三行省略样式 */
|
||||||
|
.line-clamp-3 {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
max-height: 4.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 查看详情表单样式 */
|
/* 查看详情表单样式 */
|
||||||
@@ -920,11 +1271,6 @@ onMounted(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 选中报告厅的图片展示区域 */
|
|
||||||
.selected-hall-images {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-gallery {
|
.image-gallery {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -977,6 +1323,30 @@ onMounted(() => {
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 暂无图片占位样式 */
|
||||||
|
.no-images-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 450px;
|
||||||
|
height: 120px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border: 2px dashed #dcdfe6;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-images-placeholder .el-icon {
|
||||||
|
font-size: 32px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-images-placeholder span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 审核对话框样式 */
|
/* 审核对话框样式 */
|
||||||
.audit-form .form-text {
|
.audit-form .form-text {
|
||||||
color: #303133;
|
color: #303133;
|
||||||
@@ -1026,7 +1396,7 @@ onMounted(() => {
|
|||||||
.hall-id {
|
.hall-id {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
background: #f0f2f5;
|
/* background: #f0f2f5; */
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
@@ -1161,6 +1531,136 @@ onMounted(() => {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
resize: none !important;
|
resize: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 审核建议样式 - 增强版 */
|
||||||
|
.audit-suggestion-content {
|
||||||
|
line-height: 1.6;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audit-suggestion-content .el-icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 冲突详情在新行展示 */
|
||||||
|
.audit-suggestion-content .conflict-details {
|
||||||
|
flex-basis: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 不同状态的颜色 */
|
||||||
|
.audit-suggestion-content.checking-conflict {
|
||||||
|
color: #409eff; /* 检查中 - 蓝色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.audit-suggestion-content.check-error {
|
||||||
|
color: #e6a23c; /* 检查错误 - 橙色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.audit-suggestion-content.has-conflict {
|
||||||
|
color: #f56c6c; /* 有冲突 - 红色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.audit-suggestion-content.no-conflict {
|
||||||
|
color: #67c23a; /* 无冲突 - 绿色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.audit-suggestion-content.not-checked {
|
||||||
|
color: #909399; /* 未检查 - 灰色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 冲突详情样式 */
|
||||||
|
.conflict-details {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #fef2f2;
|
||||||
|
border-left: 3px solid #f56c6c;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conflict-list {
|
||||||
|
margin: 4px 0 0 0;
|
||||||
|
padding-left: 16px;
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conflict-list li {
|
||||||
|
margin: 2px 0;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文本颜色工具类 */
|
||||||
|
.text-success {
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-warning {
|
||||||
|
color: #e6a23c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-info {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载动画 */
|
||||||
|
.rotate-loading {
|
||||||
|
animation: rotate 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 冲突检查统计样式 */
|
||||||
|
.conflict-summary {
|
||||||
|
margin: 0px 0;
|
||||||
|
padding: 0px;
|
||||||
|
/* background-color: #f9fafe; */
|
||||||
|
border-radius: 6px;
|
||||||
|
/* border: 1px solid #e4e7ed; */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap; /* 超出时自动换行 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-stats {
|
||||||
|
display: inline-flex; /* 与标签同行 */
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 0; /* 移除顶部间距,保持同一行 */
|
||||||
|
flex-wrap: wrap; /* 达到最大宽度时自身也可换行 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.conflict-warning-text {
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #e6a23c;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
/* 搜索按钮容器样式 */
|
||||||
|
.search-btn-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -3,19 +3,30 @@
|
|||||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
<div v-show="showSearch" class="mb-[10px]">
|
<div v-show="showSearch" class="mb-[10px]">
|
||||||
<el-card shadow="hover">
|
<el-card shadow="hover">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
|
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="报告厅名称" prop="hallName">
|
<el-form-item label="报告厅名称" prop="hallName">
|
||||||
<el-input v-model="queryParams.hallName" placeholder="请输入报告厅名称" clearable @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.hallName" placeholder="请输入报告厅名称" clearable @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="报告厅状态" prop="hallStatus">
|
<el-form-item label="报告厅状态" prop="hallStatus">
|
||||||
<el-select v-model="queryParams.hallStatus" placeholder="请选择报告厅状态" clearable>
|
<el-select v-model="queryParams.hallStatus" placeholder="请选择报告厅状态" clearable style="width: 100%">
|
||||||
<el-option v-for="dict in hall_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
<el-option v-for="dict in hall_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" class="search-btn-container">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -40,11 +51,11 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table v-loading="loading" border :data="hallInfoList" @selection-change="handleSelectionChange" style="margin-bottom: 20px">
|
<el-table v-loading="loading" border :data="hallInfoList" @selection-change="handleSelectionChange" @row-dblclick="handleView">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<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="主键ID" align="center" prop="id" v-if="true" /> -->
|
||||||
<el-table-column label="报告厅名称" align="center" prop="hallName" />
|
<el-table-column label="报告厅名称" align="center" prop="hallName" />
|
||||||
<el-table-column label="报告厅图片" align="center" prop="hallImage" width="100">
|
<el-table-column label="报告厅图片" align="center" prop="hallImage" width="200">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div v-if="scope.row.hallImage" class="table-image">
|
<div v-if="scope.row.hallImage" class="table-image">
|
||||||
<image-preview :src="scope.row.hallImage" :width="50" :height="50" />
|
<image-preview :src="scope.row.hallImage" :width="50" :height="50" />
|
||||||
@@ -54,21 +65,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="报告厅状态" align="center" prop="hallStatus">
|
<el-table-column label="报告厅状态" align="center" prop="hallStatus" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :options="hall_status" :value="scope.row.hallStatus" />
|
<dict-tag :options="hall_status" :value="scope.row.hallStatus" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="报告厅描述" align="center" prop="hallDescription" />
|
<el-table-column label="报告厅描述" align="center" prop="hallDescription">
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160">
|
<template #default="scope">
|
||||||
|
<div class="description-cell">{{ scope.row.hallDescription }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="240">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip content="查看" placement="top">
|
<el-tooltip content="查看" placement="top">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
type="info"
|
type="primary"
|
||||||
icon="View"
|
icon="View"
|
||||||
size="default"
|
size="default"
|
||||||
style="font-size: 16px; margin-right: 8px"
|
style="font-size: 16px; margin-right: 8px; color: blue"
|
||||||
@click="handleView(scope.row)"
|
@click="handleView(scope.row)"
|
||||||
v-hasPermi="['hq:hallInfo:query']"
|
v-hasPermi="['hq:hallInfo:query']"
|
||||||
></el-button>
|
></el-button>
|
||||||
@@ -477,4 +492,68 @@ onMounted(() => {
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
margin-top: 0px !important;
|
margin-top: 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-popper.description-tooltip-popper {
|
||||||
|
width: 300px !important;
|
||||||
|
max-width: 300px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-popper.description-tooltip-popper .el-popper__content {
|
||||||
|
width: 300px !important;
|
||||||
|
max-width: 300px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-popper.description-tooltip-popper .el-tooltip__content {
|
||||||
|
width: 100% !important;
|
||||||
|
max-height: 200px !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
white-space: pre-wrap !important;
|
||||||
|
word-break: break-all !important;
|
||||||
|
text-align: left !important;
|
||||||
|
line-height: 1.5 !important;
|
||||||
|
padding: 8px 12px !important;
|
||||||
|
|
||||||
|
/* 自定义滚动条样式 */
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: rgba(144, 147, 153, 0.3);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(144, 147, 153, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-cell {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
line-height: 1.5;
|
||||||
|
max-height: 4.5em;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 搜索按钮容器样式 */
|
||||||
|
.search-btn-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -3,28 +3,54 @@
|
|||||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
|
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
|
||||||
<el-card shadow="hover">
|
<el-card shadow="hover">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
|
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||||
<el-form-item label="报告厅ID" prop="hallId">
|
<el-row :gutter="20">
|
||||||
<el-input v-model="queryParams.hallId" placeholder="请输入报告厅ID" clearable @keyup.enter="handleQuery" />
|
<el-col :span="6">
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="报告厅名称" prop="hallName">
|
<el-form-item label="报告厅名称" prop="hallName">
|
||||||
<el-input v-model="queryParams.hallName" placeholder="请输入报告厅名称" clearable @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.hallName" placeholder="请输入报告厅名称" clearable @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="预约开始时间" prop="startTime">
|
<el-form-item label="预约开始时间" prop="startTime">
|
||||||
<el-date-picker clearable v-model="queryParams.startTime" type="date" placeholder="请选择开始时间" value-format="YYYY-MM-DD" />
|
<el-date-picker
|
||||||
|
clearable
|
||||||
|
v-model="queryParams.startTime"
|
||||||
|
type="date"
|
||||||
|
placeholder="请选择开始时间"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="预约结束时间" prop="endTime">
|
<el-form-item label="预约结束时间" prop="endTime">
|
||||||
<el-date-picker clearable v-model="queryParams.endTime" type="date" placeholder="请选择结束时间" value-format="YYYY-MM-DD" />
|
<el-date-picker
|
||||||
|
clearable
|
||||||
|
v-model="queryParams.endTime"
|
||||||
|
type="date"
|
||||||
|
placeholder="请选择结束时间"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="预约状态" prop="status">
|
<el-form-item label="预约状态" prop="status">
|
||||||
<el-select v-model="queryParams.status" placeholder="请选择预约状态" clearable>
|
<el-select v-model="queryParams.status" placeholder="请选择预约状态" clearable style="width: 100%">
|
||||||
<el-option v-for="dict in hall_reserv_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
<el-option v-for="dict in hall_reserv_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" class="search-btn-container">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -37,14 +63,10 @@
|
|||||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['hq:hallReservation:add']">新增</el-button>
|
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['hq:hallReservation:add']">新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['hq:hallReservation:edit']"
|
<el-button icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['hq:hallReservation:edit']">修改</el-button>
|
||||||
>修改</el-button
|
|
||||||
>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['hq:hallReservation:remove']"
|
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['hq:hallReservation:remove']">删除</el-button>
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button icon="Download" @click="handleExport" v-hasPermi="['hq:hallReservation:export']">导出</el-button>
|
<el-button icon="Download" @click="handleExport" v-hasPermi="['hq:hallReservation:export']">导出</el-button>
|
||||||
@@ -53,7 +75,14 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table v-loading="loading" border :data="hallReservationList" @selection-change="handleSelectionChange" style="margin-bottom: 0">
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
border
|
||||||
|
:data="hallReservationList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
style="margin-bottom: 0"
|
||||||
|
@row-dblclick="handleView"
|
||||||
|
>
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="报告厅ID" align="center" prop="hallId" />
|
<el-table-column label="报告厅ID" align="center" prop="hallId" />
|
||||||
<el-table-column label="报告厅名称" align="center" prop="hallName" />
|
<el-table-column label="报告厅名称" align="center" prop="hallName" />
|
||||||
@@ -78,13 +107,9 @@
|
|||||||
:hide-after="100"
|
:hide-after="100"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
>
|
>
|
||||||
<span class="purpose-text">
|
<div class="purpose-text">
|
||||||
{{
|
{{ scope.row.reservationPurpose }}
|
||||||
scope.row.reservationPurpose && scope.row.reservationPurpose.length > 100
|
</div>
|
||||||
? scope.row.reservationPurpose.substring(0, 100) + '...'
|
|
||||||
: scope.row.reservationPurpose
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -110,17 +135,13 @@
|
|||||||
:hide-after="100"
|
:hide-after="100"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
>
|
>
|
||||||
<span class="audit-remark-text">
|
<div class="audit-remark-text">
|
||||||
{{
|
{{ scope.row.auditRemark }}
|
||||||
scope.row.auditRemark && scope.row.auditRemark.length > 100
|
</div>
|
||||||
? scope.row.auditRemark.substring(0, 100) + '...'
|
|
||||||
: scope.row.auditRemark
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- 查看按钮,所有记录都可以查看 -->
|
<!-- 查看按钮,所有记录都可以查看 -->
|
||||||
<el-tooltip content="查看" placement="top">
|
<el-tooltip content="查看" placement="top">
|
||||||
@@ -186,7 +207,7 @@
|
|||||||
<span class="hall-id">(ID: {{ hall.id }})</span>
|
<span class="hall-id">(ID: {{ hall.id }})</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="hall-description" v-if="hall.hallDescription">
|
<div class="hall-description" v-if="hall.hallDescription">
|
||||||
{{ hall.hallDescription }}
|
{{ displayHallDescription(hall.hallDescription) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="hall-images">
|
<div class="hall-images">
|
||||||
<template v-if="getHallImages(hall.hallImage || '').length > 0">
|
<template v-if="getHallImages(hall.hallImage || '').length > 0">
|
||||||
@@ -206,9 +227,9 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 报告厅图片展示区域 -->
|
<!-- 报告厅图片展示区域 -->
|
||||||
<el-form-item label="报告厅图片" v-if="selectedHallImages.length > 0">
|
<el-form-item label="报告厅图片">
|
||||||
<div class="selected-hall-images">
|
<div class="selected-hall-images">
|
||||||
<div class="image-gallery">
|
<div class="image-gallery" v-if="selectedHallImages.length > 0">
|
||||||
<div v-for="(image, index) in selectedHallImages" :key="index" class="image-item" @click="previewImage(image, index)">
|
<div v-for="(image, index) in selectedHallImages" :key="index" class="image-item" @click="previewImage(image, index)">
|
||||||
<img :src="image" class="gallery-image" @error="handleImageError" />
|
<img :src="image" class="gallery-image" @error="handleImageError" />
|
||||||
<div class="image-overlay">
|
<div class="image-overlay">
|
||||||
@@ -216,6 +237,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="no-images-placeholder">
|
||||||
|
<el-icon><Picture /></el-icon>
|
||||||
|
<span>暂无图片</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="预约开始时间" prop="startTime">
|
<el-form-item label="预约开始时间" prop="startTime">
|
||||||
@@ -226,6 +251,7 @@
|
|||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
placeholder="请选择预约开始时间"
|
placeholder="请选择预约开始时间"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@change="handleStartTimeChange"
|
||||||
>
|
>
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -269,9 +295,9 @@
|
|||||||
<span class="form-text">{{ viewForm.hallName }}</span>
|
<span class="form-text">{{ viewForm.hallName }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 报告厅图片展示区域 -->
|
<!-- 报告厅图片展示区域 -->
|
||||||
<el-form-item label="报告厅图片" v-if="viewHallImages.length > 0">
|
<el-form-item label="报告厅图片">
|
||||||
<div class="view-hall-images">
|
<div class="view-hall-images">
|
||||||
<div class="image-gallery">
|
<div class="image-gallery" v-if="viewHallImages.length > 0">
|
||||||
<div v-for="(image, index) in viewHallImages" :key="index" class="image-item" @click="previewImage(image, index)">
|
<div v-for="(image, index) in viewHallImages" :key="index" class="image-item" @click="previewImage(image, index)">
|
||||||
<img :src="image" class="gallery-image" @error="handleImageError" />
|
<img :src="image" class="gallery-image" @error="handleImageError" />
|
||||||
<div class="image-overlay">
|
<div class="image-overlay">
|
||||||
@@ -279,6 +305,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="no-images-placeholder">
|
||||||
|
<el-icon><Picture /></el-icon>
|
||||||
|
<span>暂无图片</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="预约开始时间">
|
<el-form-item label="预约开始时间">
|
||||||
@@ -301,6 +331,19 @@
|
|||||||
<el-form-item label="预约状态">
|
<el-form-item label="预约状态">
|
||||||
<dict-tag :options="hall_reserv_status" :value="viewForm.status" />
|
<dict-tag :options="hall_reserv_status" :value="viewForm.status" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 当状态为审核中时显示可审核人员列表 -->
|
||||||
|
<el-form-item label="可审核人员" v-if="viewForm.status === '0' && auditorList.length > 0">
|
||||||
|
<div class="auditor-list">
|
||||||
|
<div v-for="auditor in auditorList" :key="auditor.userId" class="auditor-item">
|
||||||
|
<el-avatar :size="32" :src="auditor.avatar">{{ auditor.nickName?.substring(0, 1) }}</el-avatar>
|
||||||
|
<div class="auditor-info">
|
||||||
|
<div class="auditor-name">{{ auditor.nickName || auditor.userName }}</div>
|
||||||
|
<div class="auditor-dept">{{ auditor.dept?.deptName }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="auditorList.length === 0" class="no-auditor">暂无可审核人员</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="审核人" v-if="viewForm.auditName">
|
<el-form-item label="审核人" v-if="viewForm.auditName">
|
||||||
<span class="form-text">{{ viewForm.auditName }}</span>
|
<span class="form-text">{{ viewForm.auditName }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -325,7 +368,7 @@
|
|||||||
<script setup name="HallReservation" lang="ts">
|
<script setup name="HallReservation" lang="ts">
|
||||||
import { listHallReservation, getHallReservation, delHallReservation, addHallReservation, updateHallReservation } from '@/api/hq/hallReservation';
|
import { listHallReservation, getHallReservation, delHallReservation, addHallReservation, updateHallReservation } from '@/api/hq/hallReservation';
|
||||||
import { listHallInfo } from '@/api/hq/hallInfo';
|
import { listHallInfo } from '@/api/hq/hallInfo';
|
||||||
import { getUserProfile } from '@/api/system/user';
|
import { getUserProfile, listUsersByPermission } from '@/api/system/user';
|
||||||
import { HallReservationVO, HallReservationQuery, HallReservationForm } from '@/api/hq/hallReservation/types';
|
import { HallReservationVO, HallReservationQuery, HallReservationForm } from '@/api/hq/hallReservation/types';
|
||||||
import { HallInfoVO } from '@/api/hq/hallInfo/types';
|
import { HallInfoVO } from '@/api/hq/hallInfo/types';
|
||||||
import { useUserStore } from '@/store/modules/user';
|
import { useUserStore } from '@/store/modules/user';
|
||||||
@@ -375,6 +418,44 @@ const viewForm = ref<HallReservationForm>({
|
|||||||
auditRemark: undefined
|
auditRemark: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加审核人员列表
|
||||||
|
const auditorList = ref<any[]>([]);
|
||||||
|
|
||||||
|
/** 获取具有审核权限的人员列表 */
|
||||||
|
const getAuditorList = async () => {
|
||||||
|
try {
|
||||||
|
const res = await listUsersByPermission('hq:hallAudit:list');
|
||||||
|
auditorList.value = res.data || [];
|
||||||
|
console.log('审核人员列表:', auditorList.value);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取审核人员列表失败:', error);
|
||||||
|
auditorList.value = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 验证结束时间 */
|
||||||
|
const validateEndTime = (rule: any, value: any, callback: any) => {
|
||||||
|
if (value && form.value.startTime) {
|
||||||
|
const startTime = new Date(form.value.startTime).getTime();
|
||||||
|
const endTime = new Date(value).getTime();
|
||||||
|
if (endTime <= startTime) {
|
||||||
|
callback(new Error('结束时间必须晚于开始时间'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 开始时间变化时触发结束时间验证 */
|
||||||
|
const handleStartTimeChange = () => {
|
||||||
|
// 如果结束时间已经填写,则触发验证
|
||||||
|
if (data.form.endTime) {
|
||||||
|
hallReservationFormRef.value?.validateField('endTime');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const initFormData: HallReservationForm = {
|
const initFormData: HallReservationForm = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
hallId: undefined,
|
hallId: undefined,
|
||||||
@@ -390,6 +471,7 @@ const initFormData: HallReservationForm = {
|
|||||||
auditTime: undefined,
|
auditTime: undefined,
|
||||||
auditRemark: undefined
|
auditRemark: undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
const data = reactive<PageData<HallReservationForm, HallReservationQuery>>({
|
const data = reactive<PageData<HallReservationForm, HallReservationQuery>>({
|
||||||
form: { ...initFormData },
|
form: { ...initFormData },
|
||||||
queryParams: {
|
queryParams: {
|
||||||
@@ -409,7 +491,25 @@ const data = reactive<PageData<HallReservationForm, HallReservationQuery>>({
|
|||||||
rules: {
|
rules: {
|
||||||
hallName: [{ required: true, message: '报告厅名称不能为空', trigger: 'change' }],
|
hallName: [{ required: true, message: '报告厅名称不能为空', trigger: 'change' }],
|
||||||
startTime: [{ required: true, message: '预约开始时间不能为空', trigger: 'blur' }],
|
startTime: [{ required: true, message: '预约开始时间不能为空', trigger: 'blur' }],
|
||||||
endTime: [{ required: true, message: '预约结束时间不能为空', trigger: 'blur' }],
|
endTime: [
|
||||||
|
{ required: true, message: '预约结束时间不能为空', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
|
if (value && data.form.startTime) {
|
||||||
|
const startTime = new Date(data.form.startTime).getTime();
|
||||||
|
const endTime = new Date(value).getTime();
|
||||||
|
if (endTime <= startTime) {
|
||||||
|
callback(new Error('结束时间必须晚于开始时间'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
reservationPurpose: [{ required: true, message: '预约用途不能为空', trigger: 'blur' }]
|
reservationPurpose: [{ required: true, message: '预约用途不能为空', trigger: 'blur' }]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -635,6 +735,11 @@ const handleView = async (row: HallReservationVO) => {
|
|||||||
const res = await getHallReservation(row.id);
|
const res = await getHallReservation(row.id);
|
||||||
Object.assign(viewForm.value, res.data);
|
Object.assign(viewForm.value, res.data);
|
||||||
|
|
||||||
|
// 如果状态是审核中,获取审核人员列表
|
||||||
|
if (viewForm.value.status === '0') {
|
||||||
|
await getAuditorList();
|
||||||
|
}
|
||||||
|
|
||||||
// 查找对应的报告厅并显示图片
|
// 查找对应的报告厅并显示图片
|
||||||
if (viewForm.value.hallName) {
|
if (viewForm.value.hallName) {
|
||||||
const selectedHall = hallList.value.find((hall) => hall.hallName === viewForm.value.hallName);
|
const selectedHall = hallList.value.find((hall) => hall.hallName === viewForm.value.hallName);
|
||||||
@@ -747,6 +852,13 @@ const handleExport = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 在 <script setup> 部分适当位置添加工具函数
|
||||||
|
/** 将文本截断到指定长度(默认20个字符),超出部分以省略号结尾 */
|
||||||
|
const displayHallDescription = (desc: string, maxLen = 20) => {
|
||||||
|
if (!desc) return '';
|
||||||
|
return desc.length > maxLen ? desc.slice(0, maxLen) + '...' : desc;
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList();
|
getList();
|
||||||
getHallList();
|
getHallList();
|
||||||
@@ -808,19 +920,19 @@ onMounted(() => {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #606266;
|
color: #606266;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
line-height: 1.3;
|
|
||||||
max-height: 36px;
|
max-height: 36px;
|
||||||
|
max-width: 240px; /* 新增:限制最大宽度,防止下拉框过宽 */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
white-space: nowrap; /* 单行显示 */
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
display: -webkit-box;
|
display: block;
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 下拉框图片容器:每行最多 6 张图片 */
|
||||||
.hall-images {
|
.hall-images {
|
||||||
display: flex;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(6, 40px); /* 6 列,每列宽 40px */
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hall-image {
|
.hall-image {
|
||||||
@@ -849,22 +961,28 @@ onMounted(() => {
|
|||||||
|
|
||||||
/* 表格中预约用途文本样式 */
|
/* 表格中预约用途文本样式 */
|
||||||
.purpose-text {
|
.purpose-text {
|
||||||
display: inline-block;
|
display: -webkit-box;
|
||||||
max-width: 100%;
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
overflow: hidden;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
max-height: 4.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 表格中审核备注文本样式 */
|
/* 表格中审核备注文本样式 */
|
||||||
.audit-remark-text {
|
.audit-remark-text {
|
||||||
display: inline-block;
|
display: -webkit-box;
|
||||||
max-width: 100%;
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
overflow: hidden;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
max-height: 4.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 查看详情表单样式 */
|
/* 查看详情表单样式 */
|
||||||
@@ -923,6 +1041,7 @@ onMounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
max-width: 450px; /* 与预约用途保持一致 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-item {
|
.image-item {
|
||||||
@@ -970,6 +1089,88 @@ onMounted(() => {
|
|||||||
color: white;
|
color: white;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 暂无图片占位样式 */
|
||||||
|
.no-images-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 450px; /* 与预约用途保持一致 */
|
||||||
|
height: 120px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border: 2px dashed #dcdfe6;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-images-placeholder .el-icon {
|
||||||
|
font-size: 32px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-images-placeholder span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 审核人员列表样式 */
|
||||||
|
.auditor-list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auditor-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auditor-item:hover {
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.auditor-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auditor-name {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auditor-dept {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-auditor {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面容器样式 */
|
||||||
|
|
||||||
|
/* 搜索按钮容器样式 */
|
||||||
|
.search-btn-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -4,27 +4,44 @@
|
|||||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
<div v-show="showSearch" class="mb-[10px]">
|
<div v-show="showSearch" class="mb-[10px]">
|
||||||
<el-card shadow="hover">
|
<el-card shadow="hover">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
|
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||||
|
<!-- 第一行:4个检索元素 -->
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="类型名称" prop="categoryName">
|
<el-form-item label="类型名称" prop="categoryName">
|
||||||
<el-input v-model="queryParams.categoryName" placeholder="请输入类型名称" clearable @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.categoryName" placeholder="请输入类型名称" clearable @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="类型编码" prop="categoryCode">
|
<el-form-item label="类型编码" prop="categoryCode">
|
||||||
<el-input v-model="queryParams.categoryCode" placeholder="请输入类型编码" clearable @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.categoryCode" placeholder="请输入类型编码" clearable @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="技能等级" prop="skillLevel">
|
<el-form-item label="技能等级" prop="skillLevel">
|
||||||
<el-select v-model="queryParams.skillLevel" placeholder="请选择技能等级" clearable>
|
<el-select v-model="queryParams.skillLevel" placeholder="请选择技能等级" clearable style="width: 100%">
|
||||||
<el-option v-for="dict in pm_skill_level" :key="dict.value" :label="dict.label" :value="dict.value" />
|
<el-option v-for="dict in pm_skill_level" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
|
||||||
<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 操作按钮行 -->
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" class="search-btn-container">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,15 +70,17 @@
|
|||||||
:default-expand-all="isExpandAll"
|
:default-expand-all="isExpandAll"
|
||||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||||
border
|
border
|
||||||
|
header-align="center"
|
||||||
|
@row-click="handleRowClick"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
class="tree-table"
|
class="tree-table"
|
||||||
>
|
>
|
||||||
<el-table-column prop="categoryName" label="类型名称" min-width="260" show-overflow-tooltip>
|
<el-table-column align="left" header-align="center" prop="categoryName" label="类型名称" min-width="260" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span class="category-name-cell">
|
<span class="category-name-cell">
|
||||||
<el-icon v-if="scope.row.iconUrl" class="category-icon" :style="{ color: scope.row.colorCode }">
|
<!-- <el-icon v-if="scope.row.iconUrl" class="category-icon" :style="{ color: scope.row.colorCode }">
|
||||||
<component :is="getCategoryIcon(scope.row.categoryCode)" />
|
<component :is="getCategoryIcon(scope.row.categoryCode)" />
|
||||||
</el-icon>
|
</el-icon> -->
|
||||||
<span class="category-name">{{ scope.row.categoryName }}</span>
|
<span class="category-name">{{ scope.row.categoryName }}</span>
|
||||||
<el-tag v-if="scope.row.childrenCount > 0" size="small" type="info" class="children-count-tag">
|
<el-tag v-if="scope.row.childrenCount > 0" size="small" type="info" class="children-count-tag">
|
||||||
{{ scope.row.childrenCount }}个子类
|
{{ scope.row.childrenCount }}个子类
|
||||||
@@ -69,8 +88,8 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="categoryCode" label="类型编码" width="150" show-overflow-tooltip />
|
<el-table-column prop="categoryCode" label="类型编码" width="150" align="left" header-align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="categoryDescription" label="类型描述" min-width="200" show-overflow-tooltip />
|
<el-table-column prop="categoryDescription" label="类型描述" min-width="200" align="left" header-align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="skillLevel" label="技能等级" width="100" align="center">
|
<el-table-column prop="skillLevel" label="技能等级" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="getSkillLevelTagType(scope.row.skillLevel)" size="small">
|
<el-tag :type="getSkillLevelTagType(scope.row.skillLevel)" size="small">
|
||||||
@@ -78,7 +97,7 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="estimatedDuration" label="预估时长" width="120" align="center">
|
<!-- <el-table-column prop="estimatedDuration" label="预估时长" width="120" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span v-if="scope.row.estimatedDuration">{{ formatDuration(scope.row.estimatedDuration) }}</span>
|
<span v-if="scope.row.estimatedDuration">{{ formatDuration(scope.row.estimatedDuration) }}</span>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
@@ -90,7 +109,7 @@
|
|||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="usageCount" label="使用次数" width="100" align="center" />
|
<el-table-column prop="usageCount" label="使用次数" width="100" align="center" /> -->
|
||||||
<el-table-column prop="sortOrder" label="排序" width="80" align="center" />
|
<el-table-column prop="sortOrder" label="排序" width="80" align="center" />
|
||||||
<el-table-column prop="status" label="状态" width="80" align="center">
|
<el-table-column prop="status" label="状态" width="80" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@@ -170,7 +189,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="20">
|
<!-- <el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="预估时长" prop="estimatedDuration">
|
<el-form-item label="预估时长" prop="estimatedDuration">
|
||||||
<el-input-number v-model="form.estimatedDuration" :min="0" :max="9999" placeholder="分钟" style="width: 100%" />
|
<el-input-number v-model="form.estimatedDuration" :min="0" :max="9999" placeholder="分钟" style="width: 100%" />
|
||||||
@@ -181,13 +200,13 @@
|
|||||||
<el-input-number v-model="form.standardCost" :min="0" :precision="2" placeholder="元" style="width: 100%" />
|
<el-input-number v-model="form.standardCost" :min="0" :precision="2" placeholder="元" style="width: 100%" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row> -->
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<!-- <el-col :span="12">
|
||||||
<el-form-item label="分类颜色" prop="colorCode">
|
<el-form-item label="分类颜色" prop="colorCode">
|
||||||
<el-color-picker v-model="form.colorCode" :predefine="predefineColors" :clearable="false" style="width: 100%" />
|
<el-color-picker v-model="form.colorCode" :predefine="predefineColors" :clearable="false" style="width: 100%" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col> -->
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="排序顺序" prop="sortOrder">
|
<el-form-item label="排序顺序" prop="sortOrder">
|
||||||
<el-input-number v-model="form.sortOrder" :min="0" placeholder="数字越小越靠前" style="width: 100%" />
|
<el-input-number v-model="form.sortOrder" :min="0" placeholder="数字越小越靠前" style="width: 100%" />
|
||||||
@@ -231,9 +250,9 @@
|
|||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="类型名称">
|
<el-descriptions-item label="类型名称">
|
||||||
<div class="category-name-view">
|
<div class="category-name-view">
|
||||||
<el-icon v-if="viewData.iconUrl" class="category-icon" :style="{ color: viewData.colorCode }">
|
<!-- <el-icon v-if="viewData.iconUrl" class="category-icon" :style="{ color: viewData.colorCode }">
|
||||||
<component :is="getCategoryIcon(viewData.categoryCode)" />
|
<component :is="getCategoryIcon(viewData.categoryCode)" />
|
||||||
</el-icon>
|
</el-icon> -->
|
||||||
<span class="category-name">{{ viewData.categoryName }}</span>
|
<span class="category-name">{{ viewData.categoryName }}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
@@ -244,7 +263,7 @@
|
|||||||
{{ getSkillLevelText(viewData.skillLevel) }}
|
{{ getSkillLevelText(viewData.skillLevel) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="预估时长">
|
<!-- <el-descriptions-item label="预估时长">
|
||||||
{{ viewData.estimatedDuration ? formatDuration(viewData.estimatedDuration) : '-' }}
|
{{ viewData.estimatedDuration ? formatDuration(viewData.estimatedDuration) : '-' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="标准成本">
|
<el-descriptions-item label="标准成本">
|
||||||
@@ -253,7 +272,7 @@
|
|||||||
<el-descriptions-item label="使用次数">{{ viewData.usageCount }}</el-descriptions-item>
|
<el-descriptions-item label="使用次数">{{ viewData.usageCount }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="最后使用时间">
|
<el-descriptions-item label="最后使用时间">
|
||||||
{{ viewData.lastUsedTime ? proxy.parseTime(viewData.lastUsedTime, '{y}-{m}-{d} {h}:{i}') : '-' }}
|
{{ viewData.lastUsedTime ? proxy.parseTime(viewData.lastUsedTime, '{y}-{m}-{d} {h}:{i}') : '-' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item> -->
|
||||||
<el-descriptions-item label="排序顺序">{{ viewData.sortOrder }}</el-descriptions-item>
|
<el-descriptions-item label="排序顺序">{{ viewData.sortOrder }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="状态">
|
<el-descriptions-item label="状态">
|
||||||
<el-tag :type="viewData.status === '1' ? 'success' : 'danger'" size="small">
|
<el-tag :type="viewData.status === '1' ? 'success' : 'danger'" size="small">
|
||||||
@@ -286,6 +305,8 @@ import {
|
|||||||
updateRepairCategory,
|
updateRepairCategory,
|
||||||
getRepairCategoryTree
|
getRepairCategoryTree
|
||||||
} from '@/api/hq/pm/repairCategory';
|
} from '@/api/hq/pm/repairCategory';
|
||||||
|
import { ref, reactive, getCurrentInstance, nextTick, onMounted, type ComponentInternalInstance } from 'vue';
|
||||||
|
import type { FormInstance as ElFormInstance, FormRules as ElFormRules } from 'element-plus';
|
||||||
import { RepairCategoryVO, RepairCategoryForm, RepairCategoryQuery } from '@/api/hq/pm/types';
|
import { RepairCategoryVO, RepairCategoryForm, RepairCategoryQuery } from '@/api/hq/pm/types';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
@@ -296,6 +317,8 @@ const loading = ref(true);
|
|||||||
const showSearch = ref(true);
|
const showSearch = ref(true);
|
||||||
const isExpandAll = ref(false);
|
const isExpandAll = ref(false);
|
||||||
const refreshTable = ref(true);
|
const refreshTable = ref(true);
|
||||||
|
// 标记首次加载,用于控制默认展示主分类树
|
||||||
|
const initialLoad = ref(true);
|
||||||
|
|
||||||
// 字典数据
|
// 字典数据
|
||||||
const pm_skill_level = ref([
|
const pm_skill_level = ref([
|
||||||
@@ -363,24 +386,20 @@ const buttonLoading = ref(false);
|
|||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
// 根据是否有搜索条件决定使用哪个接口
|
// 首次加载时使用树形接口获取所有分类
|
||||||
let res;
|
if (initialLoad.value) {
|
||||||
const hasSearchConditions =
|
const res = await getRepairCategoryTree();
|
||||||
queryParams.value.categoryName || queryParams.value.categoryCode || queryParams.value.skillLevel || queryParams.value.status;
|
if (res.code === 200 && res.data) {
|
||||||
|
categoryList.value = res.data;
|
||||||
if (hasSearchConditions) {
|
|
||||||
// 有搜索条件时使用列表接口,然后手动构建树形结构
|
|
||||||
res = await listRepairCategory(queryParams.value);
|
|
||||||
if (res.code === 200 && res.rows) {
|
|
||||||
categoryList.value = buildTreeFromList(res.rows);
|
|
||||||
} else {
|
} else {
|
||||||
categoryList.value = [];
|
categoryList.value = [];
|
||||||
}
|
}
|
||||||
|
initialLoad.value = false; // 首次加载完成后,后续操作都使用列表接口
|
||||||
} else {
|
} else {
|
||||||
// 无搜索条件时直接使用树形接口
|
// 后续操作使用列表接口,并根据搜索条件过滤
|
||||||
res = await getRepairCategoryTree();
|
const res = await listRepairCategory(queryParams.value);
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.rows) {
|
||||||
categoryList.value = res.data;
|
categoryList.value = buildTreeFromList(res.rows);
|
||||||
} else {
|
} else {
|
||||||
categoryList.value = [];
|
categoryList.value = [];
|
||||||
}
|
}
|
||||||
@@ -468,6 +487,10 @@ const handleUpdate = async (row: RepairCategoryVO) => {
|
|||||||
getCategoryTree();
|
getCategoryTree();
|
||||||
const res = await getRepairCategory(row.id);
|
const res = await getRepairCategory(row.id);
|
||||||
Object.assign(form.value, res.data);
|
Object.assign(form.value, res.data);
|
||||||
|
// 若后端未返回技能等级,默认设置为中级
|
||||||
|
if (!form.value.skillLevel) {
|
||||||
|
form.value.skillLevel = '2';
|
||||||
|
}
|
||||||
dialog.visible = true;
|
dialog.visible = true;
|
||||||
dialog.title = '修改维修类型';
|
dialog.title = '修改维修类型';
|
||||||
};
|
};
|
||||||
@@ -479,6 +502,11 @@ const handleView = async (row: RepairCategoryVO) => {
|
|||||||
viewDialog.visible = true;
|
viewDialog.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 行点击预览 */
|
||||||
|
const handleRowClick = (row: RepairCategoryVO) => {
|
||||||
|
handleView(row);
|
||||||
|
};
|
||||||
|
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
const submitForm = () => {
|
const submitForm = () => {
|
||||||
categoryFormRef.value?.validate(async (valid: boolean) => {
|
categoryFormRef.value?.validate(async (valid: boolean) => {
|
||||||
@@ -515,13 +543,17 @@ const handleDelete = async (row: RepairCategoryVO) => {
|
|||||||
|
|
||||||
/** 状态修改 */
|
/** 状态修改 */
|
||||||
const handleStatusChange = async (row: RepairCategoryVO) => {
|
const handleStatusChange = async (row: RepairCategoryVO) => {
|
||||||
|
const originalStatus = row.status;
|
||||||
const text = row.status === '1' ? '启用' : '停用';
|
const text = row.status === '1' ? '启用' : '停用';
|
||||||
try {
|
try {
|
||||||
await proxy?.$modal.confirm('确认要' + text + '"' + row.categoryName + '"类型吗?');
|
await proxy?.$modal.confirm(`确认要${text}"${row.categoryName}"类型吗?`);
|
||||||
await updateRepairCategory({ id: row.id, status: row.status });
|
// 移除前端辅助字段,只保留后端需要的核心字段
|
||||||
|
const { children, ...updateData } = row as any;
|
||||||
|
await updateRepairCategory(updateData);
|
||||||
proxy?.$modal.msgSuccess(text + '成功');
|
proxy?.$modal.msgSuccess(text + '成功');
|
||||||
} catch {
|
} catch (e) {
|
||||||
row.status = row.status === '1' ? '0' : '1';
|
// 如果请求失败或被取消,则还原原状态
|
||||||
|
row.status = originalStatus;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -543,7 +575,7 @@ const reset = () => {
|
|||||||
categoryDescription: '',
|
categoryDescription: '',
|
||||||
parentId: 0, // 使用数字类型,确保与树形选择器数据类型一致
|
parentId: 0, // 使用数字类型,确保与树形选择器数据类型一致
|
||||||
requiredSkills: '',
|
requiredSkills: '',
|
||||||
skillLevel: '',
|
skillLevel: '2', // 默认中级
|
||||||
estimatedDuration: undefined,
|
estimatedDuration: undefined,
|
||||||
standardCost: undefined,
|
standardCost: undefined,
|
||||||
iconUrl: '',
|
iconUrl: '',
|
||||||
@@ -840,4 +872,14 @@ onMounted(() => {
|
|||||||
:deep(.el-color-picker__color) {
|
:deep(.el-color-picker__color) {
|
||||||
border: 0px !important;
|
border: 0px !important;
|
||||||
}
|
}
|
||||||
|
/* 搜索按钮容器样式 */
|
||||||
|
.search-btn-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||