diff --git a/.codebuddy/skills/permission-dev/SKILL.md b/.codebuddy/skills/permission-dev/SKILL.md new file mode 100644 index 0000000..ff650e0 --- /dev/null +++ b/.codebuddy/skills/permission-dev/SKILL.md @@ -0,0 +1,192 @@ +--- +name: 权限功能开发 +description: This skill should be used when developing permission-related features in the UniApp property management mini-program. It provides guidance on admin info fetching, permission checking, role validation, and integrating permission controls into components. +--- + +# 权限功能开发 + +物业小程序已集成权限管理功能,参考 PC 端 `admin/src/directive/permission` 实现。提供便捷的权限校验方式,用于控制组件或功能入口的显示隐藏。 + +## 相关文件 + +``` +app/ +├── api/ +│ └── property.js # 管理员信息接口 +├── config/ +│ └── cache.js # 缓存常量 +├── store/ +│ ├── modules/ +│ │ └── app.js # 状态管理 +│ └── getters.js # 数据获取 +├── utils/ +│ └── auth/ +│ └── permission.js # 权限校验工具 +└── pages/users/login/index.vue # 登录页(已集成) +``` + +## 核心概念 + +### 管理员信息结构 + +```javascript +{ + id: 1, // 管理员ID + account: "admin", // 账号 + realName: "超管", // 真实姓名 + roles: "1", // 角色标识 + permissionsList: ["*:*:*"], // 权限列表 + phone: "11111111111", // 手机号 + status: true // 状态 +} +``` + +### 权限标识规则 + +- `*:*:*` - 超管权限,拥有所有权限 +- `system:user:add` - 系统管理-用户-新增 +- `system:user:edit` - 系统管理-用户-编辑 + +## Store 使用 + +### Getters + +```javascript +import { mapGetters } from 'vuex'; + +export default { + computed: { + ...mapGetters([ + 'adminInfo', // 管理员完整信息 + 'permissions', // 权限列表 + 'roles', // 角色列表 + 'isSuperAdmin' // 是否超管 + ]) + } +}; +``` + +### Actions + +```javascript +// 获取管理员信息 +this.$store.dispatch('ADMIN_INFO').then(res => console.log(res)); + +// 登录后自动获取(已在登录流程中集成) +this.$store.dispatch('LOGIN_ADMIN_INFO'); +``` + +## 权限校验工具 + +文件位置:`app/utils/auth/permission.js` + +### 引入方式 + +```javascript +import { checkPermi, checkRole, isSuperAdmin, getPermissions, getRoles, getAdminInfo } from '@/utils/auth/permission.js'; +``` + +### 方法说明 + +| 方法 | 说明 | 示例 | +|------|------|------| +| `checkPermi(value)` | 权限校验 | `checkPermi('system:user:add')` | +| `checkRole(value)` | 角色校验 | `checkRole('admin')` | +| `isSuperAdmin()` | 判断超管 | `isSuperAdmin()` | +| `getPermissions()` | 获取权限列表 | `getPermissions()` | +| `getAdminInfo()` | 获取管理员信息 | `getAdminInfo()` | + +## 使用示例 + +### 示例1:v-if 控制显示 + +```vue + + + +``` + +### 示例2:computed 便捷调用 + +```vue + + + +``` + +### 示例3:多个权限任一匹配 + +```vue + +``` + +### 示例4:权限指令封装 + +```vue + + + +``` + +## 与登录流程集成 + +登录成功后自动获取管理员信息(已在 `app/pages/users/login/index.vue` 集成): + +```javascript +this.$store.commit("SETUID", data.uid); +getUserInfo().then(res => { + this.$store.commit("UPDATE_USERINFO", res.data); + this.$store.dispatch('LOGIN_ADMIN_INFO'); // ✅ 自动获取管理员信息 +}); +``` + +## 退出登录清理 + +退出登录时自动清理管理员信息(已在 `app/store/modules/app.js` 的 LOGOUT mutation 中集成)。 + +## 注意事项 + +1. **权限标识大小写敏感** - 权限标识严格区分大小写 +2. **超管权限** - 拥有 `*:*:*` 权限的用户拥有所有权限 +3. **登录检查** - 使用权限前确保用户已登录 +4. **缓存持久化** - 管理员信息会缓存到本地Storage diff --git a/.codebuddy/skills/skills/SKILL.md b/.codebuddy/skills/skills/SKILL.md new file mode 100644 index 0000000..823324f --- /dev/null +++ b/.codebuddy/skills/skills/SKILL.md @@ -0,0 +1,431 @@ +--- +id: property-dev +name: 物业功能开发 Skill +description: UniApp 物业功能开发规范,包含接口定义、页面开发、样式规范等 +tags: [uniapp, property, vue2, miniprogram] +version: 1.0.0 +author: CodeBuddy +--- + +# 物业功能开发 Skill + +## 项目概述 + +这是一个基于 UniApp 开发的物业管理小程序项目,兼容 H5 和微信小程序。项目位于 `app/` 目录下,采用 Vue 2 语法风格。 + +## 项目结构 + +``` +app/ +├── api/ # API 接口文件 +│ └── property.js # 物业相关接口 +├── pages/ +│ └── supply_chain/ # 物业管理功能页面 +│ ├── day_menu/ # 每日菜单 +│ ├── repair/ # 报修管理 +│ ├── complaint/ # 投诉建议 +│ ├── stock/ # 物资领用 +│ ├── wish_menu/ # 祈愿菜单 +│ └── ... +├── utils/ +│ └── request.js # 请求封装 +├── config/ +│ └── app.js # 全局配置 +└── components/ # 公共组件 +``` + +## 技术规范 + +### 1. 接口定义规范 + +接口文件位于 `app/api/property.js`,统一使用 `request` 对象: + +```javascript +import request from '@/utils/request.js'; + +// GET 请求示例 +export function listSomething(params) { + return request.get( + 'autogencode/xxx/list', + params, + { useAdminUrl: true } + ); +} + +// POST 请求示例 +export function createSomething(data) { + return request.post( + 'autogencode/xxx/save', + data, + { useAdminUrl: true } + ); +} +``` + +**规范要点:** +- 所有物业接口使用 `useAdminUrl: true`,前缀为 `autogencode/` +- 列表查询用 `list` 后缀 +- 新增用 `save` 后缀 +- 删除用 `delete` 后缀 +- 详情用 `info/{id}` 后缀 + +### 2. 页面开发规范 + +#### 2.1 页面基础结构 + +```vue + + + + + +``` + +#### 2.2 表单页面结构 + +```vue + +``` + +#### 2.3 字典使用 + +```javascript +export default { + dicts: ['fault_type', 'cs_type'], // 声明使用的字典 + + methods: { + // 获取字典数据 + getDictLabel(dictKey, value) { + const dict = this.dict.get(dictKey) || []; + const item = dict.find(d => d.dictValue === value); + return item?.dictLabel || value; + } + } +}; +``` + +### 3. 样式规范 + +#### 3.1 颜色变量 + +```scss +// 主色调 +$primary: #3b82f6; // 蓝色主色 +$success: #16a34a; // 绿色成功 +$danger: #dc2626; // 红色危险/错误 +$warning: #f97316; // 橙色警告 + +// 背景色 +$bg-page: #f6f7fb; // 页面背景 +$bg-card: #ffffff; // 卡片背景 +$bg-gray: #f3f4f6; // 灰色背景 + +// 文字色 +$text-primary: #1f2937; // 主要文字 +$text-secondary: #6b7280; // 次要文字 +$text-muted: #9ca3af; // 弱化文字 +``` + +#### 3.2 常用样式类 + +```scss +// 页面容器 +.page { + min-height: 100vh; + background: #f6f7fb; + padding: 24rpx; +} + +// 卡片样式 +.card { + background: #fff; + border-radius: 16rpx; + padding: 24rpx; + margin-bottom: 20rpx; +} + +// 标签切换 +.tabs { + display: flex; + background: #fff; + border-radius: 16rpx; + padding: 8rpx; + margin-bottom: 20rpx; + + .tab { + flex: 1; + text-align: center; + padding: 20rpx 0; + font-size: 28rpx; + color: #6b7280; + border-radius: 12rpx; + + &.active { + background: #3b82f6; + color: #fff; + font-weight: 600; + } + } +} + +// 表单项 +.form-item { + margin-bottom: 24rpx; + + .label { + font-size: 28rpx; + color: #374151; + margin-bottom: 12rpx; + display: block; + } + + .input, .textarea { + background: #f9fafb; + border-radius: 12rpx; + padding: 20rpx; + font-size: 28rpx; + } +} + +// 按钮样式 +.btn-primary { + background: #3b82f6; + color: #fff; + border-radius: 12rpx; + padding: 24rpx 0; + text-align: center; + font-size: 30rpx; + font-weight: 600; +} +``` + +### 4. 图片上传规范 + +```javascript +methods: { + // 选择图片 + chooseImage() { + uni.chooseImage({ + count: 9 - this.images.length, + success: (res) => { + res.tempFilePaths.forEach(path => { + this.uploadImage(path); + }); + } + }); + }, + + // 上传图片 + async uploadImage(filePath) { + try { + uni.showLoading({ title: '上传中...' }); + const result = await request.uploadFile(filePath, 'file'); + this.images.push({ url: result.url }); + } catch (e) { + uni.showToast({ title: '上传失败', icon: 'none' }); + } finally { + uni.hideLoading(); + } + }, + + // 删除图片 + deleteImage(index) { + this.images.splice(index, 1); + } +} +``` + +### 5. 常用组件 + +#### 5.1 z-paging 分页组件 + +```vue + + + + + + + + + + +``` + +#### 5.2 uni-calendar 日历组件 + +```vue + +``` + +#### 5.3 picker 选择器 + +```vue + + + {{ selectedLabel || '请选择' }} + + +``` + +## 现有功能模块 + +### 已开发模块 + +1. **每日菜单** (`day_menu/`) + - 按日期查看菜单 + - 菜品点赞/点踩 + - 菜品排行 + - 食堂切换 + +2. **报修管理** (`repair/`) + - 提交报修单 + - 报修记录列表 + - 图片上传 + - 房屋选择 + +3. **投诉建议** (`complaint/`) + - 提交投诉/建议 + - 历史记录 + - 图片上传 + +4. **物资领用** (`stock/`) + - 物资列表 + - 领用申请 + - 领用记录 + +5. **祈愿菜单** (`wish_menu/`) + - 提交祈愿 + - 祈愿列表 + +6. **公告通知** (`notice/`) + - 公告列表 + - 公告详情 + +## 开发建议 + +### 新增功能步骤 + +1. **创建 API 接口** + - 在 `app/api/property.js` 中添加接口函数 + - 遵循命名规范:`listXxx`, `createXxx`, `updateXxx`, `deleteXxx` + +2. **创建页面** + - 在 `app/pages/supply_chain/` 下新建文件夹 + - 创建 `index.vue` 文件 + - 复制基础模板进行修改 + +3. **配置路由** + - 在 `app/pages.json` 中添加页面配置 + - 设置页面标题和样式 + +4. **添加字典(如需要)** + - 确认后端已配置字典 + - 在页面 `dicts` 中声明使用 + +### 代码复用 + +- **列表分页**:使用 `z-paging` 组件 +- **图片上传**:参考 `repair/index.vue` 中的实现 +- **表单验证**:使用 uni-app 表单验证或自定义验证 +- **日期处理**:使用 `uni-calendar` 组件 + +### 注意事项 + +1. 所有接口请求使用 `useAdminUrl: true` +2. 图片上传使用 `request.uploadFile` 方法 +3. 字典数据通过 `this.dict.get(key)` 获取 +4. 页面背景统一使用 `#f6f7fb` +5. 卡片圆角统一使用 `16rpx` +6. 支持 H5 和微信小程序,注意平台差异处理 + +## 参考示例 + +- 表单+列表页面:参考 `repair/index.vue` +- 纯列表页面:参考 `notice/index.vue` +- 复杂交互页面:参考 `day_menu/index.vue` diff --git a/admin/src/store/modules/permission.js b/admin/src/store/modules/permission.js index ff5e4dc..f10f3cd 100644 --- a/admin/src/store/modules/permission.js +++ b/admin/src/store/modules/permission.js @@ -64,6 +64,12 @@ const actions = { // const { rules } = await roleApi.getRoleById(roleid) let menusAll = await roleApi.menuListApi(); !Auth.isPhone() ? menusAll = menusAll.filter(item => item.component !== '/javaMobile') : menusAll = menusAll.filter(item => item.component === '/javaMobile') + menusAll = menusAll.filter(item => { + if (item.menuType === 'M' && (!item.childList || item.childList.length === 0)) { + return false; + } + return true; + }); // const routes = menusToRoutes(menusAll); const routes = copyRoutes(tempRoutes); const newRoutes = findRoutes(menusAll); diff --git a/app/api/property.js b/app/api/property.js index 5692e29..4114236 100644 --- a/app/api/property.js +++ b/app/api/property.js @@ -172,3 +172,39 @@ export function cancelBill(id) { ); } +// 部门树 +export function getDeptTree() { + return request.get( + 'autogencode/sysdept/tree', + {}, + { useAdminUrl: true } + ); +} + +// 用户列表 +export function listAdmins(params) { + return request.get( + 'admin/system/admin/list', + params, + { useAdminUrl: true } + ); +} + +// 更新派单(处理) +export function updateMaintenanceDispatch(data) { + return request.post( + 'autogencode/pmmaintenancedispatch/update', + data, + { useAdminUrl: true } + ); +} + +// 获取管理员账号信息 +export function getAdminInfoByUid() { + return request.get( + 'admin/getAdminInfoByUid', + {}, + { useAdminUrl: true } + ); +} + diff --git a/app/config/cache.js b/app/config/cache.js index 35fa418..6ce70ec 100644 --- a/app/config/cache.js +++ b/app/config/cache.js @@ -30,5 +30,7 @@ module.exports = { //缓存纬度 CACHE_LATITUDE: 'LATITUDE', //app手机信息 - PLATFORM: 'systemPlatform' + PLATFORM: 'systemPlatform', + //管理员账号信息 + ADMIN_INFO: 'ADMIN_INFO' } \ No newline at end of file diff --git a/app/pages.json b/app/pages.json index eb45822..d955383 100644 --- a/app/pages.json +++ b/app/pages.json @@ -312,16 +312,40 @@ }, { "path": "repair/index", - "style": { - "navigationBarTitleText": "报修服务", - "navigationBarBackgroundColor": "#FFFFFF", - "navigationBarTextStyle": "black" - // #ifdef H5 - , - "navigationStyle": "custom" - // #endif - } - }, + "style": { + "navigationBarTitleText": "报修服务", + "navigationBarBackgroundColor": "#FFFFFF", + "navigationBarTextStyle": "black" + // #ifdef H5 + , + "navigationStyle": "custom" + // #endif + } + }, + { + "path": "repair_handle/index", + "style": { + "navigationBarTitleText": "故障处理", + "navigationBarBackgroundColor": "#FFFFFF", + "navigationBarTextStyle": "black" + // #ifdef H5 + , + "navigationStyle": "custom" + // #endif + } + }, + { + "path": "dispatch/index", + "style": { + "navigationBarTitleText": "派单管理", + "navigationBarBackgroundColor": "#FFFFFF", + "navigationBarTextStyle": "black" + // #ifdef H5 + , + "navigationStyle": "custom" + // #endif + } + }, { "path": "notice/index", "style": { diff --git a/app/pages/index/index.vue b/app/pages/index/index.vue index f6a6345..76966cf 100644 --- a/app/pages/index/index.vue +++ b/app/pages/index/index.vue @@ -6,7 +6,7 @@ + 八方物业 - + @@ -89,37 +89,43 @@ 审批处理 --> - + 物资领用 - - - - - - 每日菜单 - + + + + + 每日菜单 + + 祈愿菜单 - + 投诉与建议 - + 报修服务 - + + + + + 报修处理 + + @@ -231,6 +237,7 @@ + + diff --git a/app/pages/supply_chain/dispatch/index.vue b/app/pages/supply_chain/dispatch/index.vue new file mode 100644 index 0000000..5e7f929 --- /dev/null +++ b/app/pages/supply_chain/dispatch/index.vue @@ -0,0 +1,837 @@ +