You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
8.7 KiB
8.7 KiB
| id | name | description | tags | version | author | ||||
|---|---|---|---|---|---|---|---|---|---|
| property-dev | 物业功能开发 Skill | UniApp 物业功能开发规范,包含接口定义、页面开发、样式规范等 |
|
1.0.0 | 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 对象:
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 页面基础结构
<template>
<z-paging ref="paging" v-model="records" @query="queryList">
<template #top>
<!-- 顶部区域 -->
</template>
<!-- 内容区域 -->
<template #bottom>
<!-- 底部区域 -->
</template>
</z-paging>
</template>
<script>
import { someApi } from '@/api/property.js';
export default {
dicts: ['dict_key'], // 使用的字典
data() {
return {
records: [],
// 其他数据
};
},
onLoad() {
// 页面加载
},
methods: {
async queryList(pageNo, pageSize) {
try {
const res = await someApi({ pageNo, pageSize });
this.$refs.paging.complete(res?.data?.list || []);
} catch (e) {
this.$refs.paging.complete(false);
}
}
}
};
</script>
<style lang="scss">
.page {
min-height: 100vh;
background: #f6f7fb;
}
</style>
2.2 表单页面结构
<template>
<z-paging ref="paging" v-model="records" @query="queryList" :layout-only="activeTab === 'form'">
<template #top>
<!-- 标签切换 -->
<view class="tabs">
<view class="tab" :class="activeTab === 'form' ? 'active' : ''" @click="activeTab = 'form'">
表单标题
</view>
<view class="tab" :class="activeTab === 'list' ? 'active' : ''" @click="switchToList">
记录列表
</view>
</view>
</template>
<!-- 表单区域 -->
<view class="tab-content" v-show="activeTab === 'form'">
<view class="form-card">
<!-- 表单项 -->
</view>
</view>
</z-paging>
</template>
2.3 字典使用
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 颜色变量
// 主色调
$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 常用样式类
// 页面容器
.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. 图片上传规范
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 分页组件
<z-paging
ref="paging"
v-model="records"
@query="queryList"
:layout-only="false"
:auto="true"
>
<template #top>
<!-- 顶部固定区域 -->
</template>
<!-- 列表内容 -->
<view v-for="item in records" :key="item.id">
<!-- 列表项 -->
</view>
<template #bottom>
<!-- 底部固定区域 -->
</template>
</z-paging>
5.2 uni-calendar 日历组件
<uni-calendar
ref="calendar"
:insert="false"
:range="false"
:start-date="'2026-01-01'"
:end-date="'2099-12-31'"
@confirm="onDateConfirm"
/>
5.3 picker 选择器
<picker
@change="onPickerChange"
:value="index"
:range="options"
:range-key="'label'"
>
<view class="picker">
{{ selectedLabel || '请选择' }}
</view>
</picker>
现有功能模块
已开发模块
-
每日菜单 (
day_menu/)- 按日期查看菜单
- 菜品点赞/点踩
- 菜品排行
- 食堂切换
-
报修管理 (
repair/)- 提交报修单
- 报修记录列表
- 图片上传
- 房屋选择
-
投诉建议 (
complaint/)- 提交投诉/建议
- 历史记录
- 图片上传
-
物资领用 (
stock/)- 物资列表
- 领用申请
- 领用记录
-
祈愿菜单 (
wish_menu/)- 提交祈愿
- 祈愿列表
-
公告通知 (
notice/)- 公告列表
- 公告详情
开发建议
新增功能步骤
-
创建 API 接口
- 在
app/api/property.js中添加接口函数 - 遵循命名规范:
listXxx,createXxx,updateXxx,deleteXxx
- 在
-
创建页面
- 在
app/pages/supply_chain/下新建文件夹 - 创建
index.vue文件 - 复制基础模板进行修改
- 在
-
配置路由
- 在
app/pages.json中添加页面配置 - 设置页面标题和样式
- 在
-
添加字典(如需要)
- 确认后端已配置字典
- 在页面
dicts中声明使用
代码复用
- 列表分页:使用
z-paging组件 - 图片上传:参考
repair/index.vue中的实现 - 表单验证:使用 uni-app 表单验证或自定义验证
- 日期处理:使用
uni-calendar组件
注意事项
- 所有接口请求使用
useAdminUrl: true - 图片上传使用
request.uploadFile方法 - 字典数据通过
this.dict.get(key)获取 - 页面背景统一使用
#f6f7fb - 卡片圆角统一使用
16rpx - 支持 H5 和微信小程序,注意平台差异处理
参考示例
- 表单+列表页面:参考
repair/index.vue - 纯列表页面:参考
notice/index.vue - 复杂交互页面:参考
day_menu/index.vue