From 8bbe4e6a35e7f048b25c184e87f22d24a5c08796 Mon Sep 17 00:00:00 2001
From: zlwu <704541015@qq.com>
Date: Sun, 10 Aug 2025 09:53:20 +0800
Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=AB=AF=E9=9B=86=E4=B8=AD?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9dict=E5=AD=97=E5=85=B8=E5=B1=95=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.cursorrules | 13 +-
backend/ruoyi-admin/table_structures.txt | 0
.../workflow/domain/vo/XgStudentLeaveVo.java | 28 +
backend/script/fix-entity-fields.py | 47 -
mobile/src/common/dict.js | 37 +
.../src/components/Process/approvalRecord.vue | 19 +-
.../src/components/Process/submitVerify.vue | 7 +-
mobile/src/components/UserSelect/index.vue | 7 +-
mobile/src/components/WeChatDemo.vue | 14 +-
mobile/src/pages.json | 8 +
mobile/src/pages/index/index.vue | 9 +-
mobile/src/pages/xg/xsjcxx/xsjcxx/index.vue | 263 +++-
.../src/pages/xg/xsjcxx/xsqj/leave/index.vue | 1056 +++++++++++++++++
mobile/src/pages/xg/xsjcxx/xsws/index.vue | 27 +-
.../xg/xsjcxx/xsws/stuMsgDetailDialog.vue | 281 ++++-
mobile/src/utils/router.js | 2 +-
16 files changed, 1684 insertions(+), 134 deletions(-)
delete mode 100644 backend/ruoyi-admin/table_structures.txt
delete mode 100644 backend/script/fix-entity-fields.py
create mode 100644 mobile/src/pages/xg/xsjcxx/xsqj/leave/index.vue
diff --git a/.cursorrules b/.cursorrules
index b7b7b7eb..437b0931 100644
--- a/.cursorrules
+++ b/.cursorrules
@@ -34,7 +34,6 @@
#### 📋 文档管理规范 (.cursor/cursorrules-docs.md)
- 文档目录组织(中文化架构)
- **🚨 强制性文档同步更新规则**
-- 变更记录管理规范(按日期和用户分文件)
- 业务模块文档管理(为AI提供完整上下文)
- **📊 API文档拆分管理规范** (2025-07-01新增,文件夹重组):
- **📁 文件夹结构**: 所有API文档统一存放在 `docs/开发文档/API/` 文件夹下
@@ -107,11 +106,6 @@
- **移动端功能变更** → `docs/业务模块/[模块名称]/` 移动端部分
- **移动端技术规范变更** → `.cursor/cursorrules-mobile.md`
-#### 变更记录规范
-- **文件格式**: `docs/变更管理/code-adjust-record-YYYY-MM-DD-{username}.md`
-- **排序要求**: 按时间倒序排列,最新记录在最上面
-- **时间填写**: 必须填写真实的当前时间(YYYY-MM-DD HH:mm:ss)
-
### 2. 🔴 数据库开发强制要求
- **标准基础字段**: 所有业务表必须包含统一的基础字段
- **雪花ID主键**: 统一使用 `bigint(20)` 作为主键
@@ -141,8 +135,7 @@
1. **确定开发场景** → 自动应用对应技术栈规范
2. **编写/修改代码** → 遵循相应的编码规范
3. **立即更新文档** → 同步更新API文档和相关文档
-4. **记录变更日志** → 在当日变更文件中记录
-5. **验证和测试** → 确保功能正常和文档准确
+4. **验证和测试** → 确保功能正常和文档准确
```
### 🤖 Cursor AI 规范应用
@@ -173,7 +166,6 @@
- **技术规范**: 对应的`.cursor/cursorrules-*.md`文件
- **最佳实践**: `docs/开发文档/API开发最佳实践总结.md`
- **项目知识库**: `docs/知识库/`目录
-- **变更记录**: `docs/变更管理/code-adjust-record-YYYY-MM-DD-{username}.md`
#### 总结流程
```
@@ -190,13 +182,12 @@
**⚠️ 基于场地预约管理系统开发实践制定的标准流程**
-#### 完整开发流程(6个阶段)
+#### 完整开发流程(5个阶段)
1. **需求分析和文档创建** → 业务需求+技术架构文档
2. **数据库设计和初始化** → 表结构+字典+权限+示例数据
3. **后端模块开发** → 完整ruoyi模块(16个API接口)
4. **API文档编写** → 400+行详细API文档
5. **自动化测试脚本** → 450+行Python测试脚本
-6. **变更记录和验证** → 完整的变更日志
#### 16个标准API接口模式
- **基础管理接口(6个)**: list、详情、新增、修改、删除、可用选项
diff --git a/backend/ruoyi-admin/table_structures.txt b/backend/ruoyi-admin/table_structures.txt
deleted file mode 100644
index e69de29b..00000000
diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/XgStudentLeaveVo.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/XgStudentLeaveVo.java
index 29aee824..edf703ee 100644
--- a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/XgStudentLeaveVo.java
+++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/XgStudentLeaveVo.java
@@ -233,4 +233,32 @@ public class XgStudentLeaveVo implements Serializable {
@ExcelProperty(value = "销假备注")
private String cancelRemark;
+ // ========== 基础字段(项目强制性规范要求) ==========
+
+ /**
+ * 创建者
+ */
+ @ExcelProperty(value = "创建者")
+ private Long createBy;
+
+ /**
+ * 创建时间
+ */
+ @ExcelProperty(value = "创建时间")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date createTime;
+
+ /**
+ * 更新者
+ */
+ @ExcelProperty(value = "更新者")
+ private Long updateBy;
+
+ /**
+ * 更新时间
+ */
+ @ExcelProperty(value = "更新时间")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date updateTime;
+
}
diff --git a/backend/script/fix-entity-fields.py b/backend/script/fix-entity-fields.py
deleted file mode 100644
index 8bd10db1..00000000
--- a/backend/script/fix-entity-fields.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python3
-"""
-批量修复XgStudentInfo实体类中的字段映射
-将不存在的字段标记为 exist = false
-"""
-
-import re
-import os
-
-# 需要标记为不存在的字段
-NON_EXISTENT_FIELDS = [
- 'name_english', 'former_name', 'name_pinyin', 'marital_status', 'religion',
- 'photo_url', 'photo_path', 'enrollment_year', 'school_system', 'education_level',
- 'training_type', 'admission_category', 'source_region', 'middle_school',
- 'major_code', 'major_name', 'class_code', 'grade', 'college_code',
- 'counselor_id', 'counselor_name', 'class_teacher_id', 'class_teacher_name',
- 'current_address', 'postal_code', 'household_register_type', 'hukou_location',
- 'info_status', 'data_source', 'last_batch_id', 'last_audit_time',
- 'is_complete', 'completion_rate', 'ext_field1', 'ext_field2', 'ext_field3',
- 'ext_field4', 'ext_field5'
-]
-
-def fix_entity_file():
- file_path = '../ruoyi-modules/ruoyi-xg-xx/src/main/java/org/dromara/xg/domain/XgStudentInfo.java'
-
- if not os.path.exists(file_path):
- print(f"文件不存在: {file_path}")
- return
-
- with open(file_path, 'r', encoding='utf-8') as f:
- content = f.read()
-
- # 修复每个字段
- for field in NON_EXISTENT_FIELDS:
- # 查找 @TableField("field_name") 并替换为 @TableField(value = "field_name", exist = false)
- pattern = f'@TableField\\("{field}"\\)'
- replacement = f'@TableField(value = "{field}", exist = false)'
- content = re.sub(pattern, replacement, content)
-
- # 保存修改后的文件
- with open(file_path, 'w', encoding='utf-8') as f:
- f.write(content)
-
- print("实体类字段映射修复完成")
-
-if __name__ == '__main__':
- fix_entity_file()
\ No newline at end of file
diff --git a/mobile/src/common/dict.js b/mobile/src/common/dict.js
index 98953efd..27822eb8 100644
--- a/mobile/src/common/dict.js
+++ b/mobile/src/common/dict.js
@@ -305,5 +305,42 @@ export const refreshDict = async (dictTypes) => {
}
};
+/**
+ * 获取字典项的标签类型(Tag Type)
+ * @param {Array} dictData - 字典数据数组
+ * @param {string|number} value - 字典值
+ * @param {Object} fallbackMap - 降级处理映射对象(可选)
+ * @returns {string} 标签类型
+ */
+export const getDictTagType = (dictData, value, fallbackMap = {}) => {
+ // 参数验证
+ if (!Array.isArray(dictData) || value === null || value === undefined) {
+ return 'info'; // 默认类型
+ }
+
+ // 优先从字典数据中获取
+ if (dictData.length > 0) {
+ const dictItem = dictData.find((item) => String(item.value) === String(value));
+
+ if (dictItem && dictItem.elTagType) {
+ // 处理特殊值转换
+ let tagType = dictItem.elTagType;
+ if (tagType === 'danger') {
+ tagType = 'error';
+ } else if (tagType === 'default') {
+ tagType = 'primary';
+ }
+ return tagType;
+ }
+ }
+
+ // 字典未加载或无样式信息时的降级处理
+ if (fallbackMap && typeof fallbackMap === 'object') {
+ return fallbackMap[value] || 'info';
+ }
+
+ return 'info';
+};
+
// 导出缓存管理对象(用于高级用法)
export { dictCache };
diff --git a/mobile/src/components/Process/approvalRecord.vue b/mobile/src/components/Process/approvalRecord.vue
index 5e5f6c6b..89373740 100644
--- a/mobile/src/components/Process/approvalRecord.vue
+++ b/mobile/src/components/Process/approvalRecord.vue
@@ -80,12 +80,17 @@
)"
:key="nameIndex"
:text="name.trim()"
- type="success"
+ :type="getApproverType()"
size="mini"
class="approver-tag"
/>
-
+
@@ -458,6 +463,16 @@ export default {
}
},
+ // 获取审批人员标签类型
+ getApproverType() {
+ return 'success'; // 审批人员使用成功样式
+ },
+
+ // 获取无审批人员标签类型
+ getNoApproverType() {
+ return 'info'; // 无审批人员使用信息样式
+ },
+
// 注:getDownloadUrl方法已被移除,现在统一使用request.js中的downloadFile方法
},
};
diff --git a/mobile/src/components/Process/submitVerify.vue b/mobile/src/components/Process/submitVerify.vue
index 46e826eb..95a47e24 100644
--- a/mobile/src/components/Process/submitVerify.vue
+++ b/mobile/src/components/Process/submitVerify.vue
@@ -76,7 +76,7 @@
v-for="user in selectCopyUserList"
:key="user.userId"
:text="user.nickName"
- type="primary"
+ :type="getCopyUserType()"
size="mini"
closable
@close="handleCopyCloseTag(user)"
@@ -1060,6 +1060,11 @@ export default {
});
});
},
+
+ // 获取抄送用户标签类型
+ getCopyUserType() {
+ return 'primary'; // 抄送用户使用主要样式
+ },
},
};
diff --git a/mobile/src/components/UserSelect/index.vue b/mobile/src/components/UserSelect/index.vue
index bb9183b1..a6cfebae 100644
--- a/mobile/src/components/UserSelect/index.vue
+++ b/mobile/src/components/UserSelect/index.vue
@@ -20,7 +20,7 @@
v-for="user in selectUserList"
:key="user.userId"
:text="user.nickName"
- type="primary"
+ :type="getSelectedUserType()"
size="mini"
closable
@close="handleCloseTag(user)"
@@ -403,6 +403,11 @@ export default {
this.$emit('confirmCallBack', this.selectUserList);
this.close();
},
+
+ // 获取选中用户标签类型
+ getSelectedUserType() {
+ return 'primary'; // 选中用户使用主要样式
+ },
},
};
diff --git a/mobile/src/components/WeChatDemo.vue b/mobile/src/components/WeChatDemo.vue
index 76cf0ee9..167e73ae 100644
--- a/mobile/src/components/WeChatDemo.vue
+++ b/mobile/src/components/WeChatDemo.vue
@@ -11,7 +11,7 @@
@@ -23,7 +23,7 @@
@@ -462,6 +462,16 @@ export default {
duration: 2000,
});
},
+
+ // 获取初始化状态标签类型
+ getInitStatusType(isInitialized) {
+ return isInitialized ? 'success' : 'warning';
+ },
+
+ // 获取微信环境标签类型
+ getWeChatEnvType(isWeChatEnv) {
+ return isWeChatEnv ? 'success' : 'error';
+ },
},
};
diff --git a/mobile/src/pages.json b/mobile/src/pages.json
index 4ef1ba06..458bfad4 100644
--- a/mobile/src/pages.json
+++ b/mobile/src/pages.json
@@ -81,6 +81,14 @@
"navigationBarTextStyle": "white"
}
},
+ {
+ "path": "pages/xg/xsjcxx/xsqj/leave/index",
+ "style": {
+ "navigationBarTitleText": "学生请假",
+ "navigationBarBackgroundColor": "#0051d9",
+ "navigationBarTextStyle": "white"
+ }
+ },
{
"path": "pages/xg/xsjcxx/xsqj/leaveEdit/index",
"style": {
diff --git a/mobile/src/pages/index/index.vue b/mobile/src/pages/index/index.vue
index 2f81ef2e..7ea28225 100644
--- a/mobile/src/pages/index/index.vue
+++ b/mobile/src/pages/index/index.vue
@@ -99,7 +99,7 @@
@@ -725,6 +725,13 @@ export default {
});
},
+ // 跳转到学生请假页面
+ gotoStudentLeave() {
+ uni.navigateTo({
+ url: '/pages/xg/xsjcxx/xsqj/leave/index',
+ });
+ },
+
// 图片加载成功处理
handleImageLoad(event) {
console.log('✅ 轮播图片加载成功:', event.detail);
diff --git a/mobile/src/pages/xg/xsjcxx/xsjcxx/index.vue b/mobile/src/pages/xg/xsjcxx/xsjcxx/index.vue
index 4cacf816..2cf109ba 100644
--- a/mobile/src/pages/xg/xsjcxx/xsjcxx/index.vue
+++ b/mobile/src/pages/xg/xsjcxx/xsjcxx/index.vue
@@ -71,7 +71,7 @@
-
@@ -87,7 +87,7 @@
-
@@ -103,7 +103,7 @@
-
@@ -142,7 +142,7 @@
-
@@ -159,7 +159,7 @@
form.householdRegisterType,
)
"
- type="info"
+ :type="getHouseholdRegisterType()"
size="mini"
>
-
@@ -197,7 +197,7 @@
-
@@ -221,7 +221,7 @@
-
@@ -233,7 +233,7 @@
-
@@ -245,7 +245,7 @@
-
@@ -257,7 +257,7 @@
-
@@ -269,7 +269,7 @@
-
@@ -281,7 +281,7 @@
-
@@ -293,7 +293,7 @@
-
@@ -382,7 +382,7 @@
:text="
getDictLabel(familyEconomicOptions, form.familyEconomicStatus)
"
- type="primary"
+ :type="getFamilyEconomicStatusType()"
size="mini"
>
-
@@ -413,7 +413,7 @@
-
@@ -429,7 +429,7 @@
-
@@ -441,7 +441,7 @@
-
@@ -492,7 +492,7 @@
-
@@ -520,7 +520,7 @@
-
@@ -534,7 +534,7 @@
:text="
getDictLabel(admissionCategoryOptions, form.admissionCategory)
"
- type="info"
+ :type="getAdmissionCategoryType()"
size="mini"
>
-
@@ -546,7 +546,7 @@
-
@@ -558,7 +558,7 @@
-
@@ -615,7 +615,7 @@
+
+
diff --git a/mobile/src/pages/xg/xsjcxx/xsws/index.vue b/mobile/src/pages/xg/xsjcxx/xsws/index.vue
index 22e4ae29..29763473 100644
--- a/mobile/src/pages/xg/xsjcxx/xsws/index.vue
+++ b/mobile/src/pages/xg/xsjcxx/xsws/index.vue
@@ -43,7 +43,7 @@
@@ -67,7 +67,7 @@
收集类型:
@@ -143,7 +143,7 @@
状态:
@@ -151,7 +151,7 @@
收集类型:
@@ -181,6 +181,7 @@