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 @@