docs: 更新README文档,完善项目介绍和技术栈说明
重构README文档结构,详细说明项目功能、技术栈、目录结构和开发规范 移除已屏蔽的认证功能相关说明,更新部署和更新日志信息
Showing
1 changed file
with
431 additions
and
28 deletions
| 1 | +# 捡个电驴 - Taro4 微信小程序项目 | ||
| 2 | + | ||
| 1 | ## 项目介绍 | 3 | ## 项目介绍 |
| 2 | 4 | ||
| 3 | -基于Taro4的微信小程序模版,集成了常用的功能,如登录、注册、列表、详情、购物车等。 | 5 | +基于Taro4框架开发的微信小程序,主要功能包括二手电动车交易、用户认证、订单管理、消息通知等。项目采用Vue3 + Composition API + Pinia状态管理的现代化开发方式。 |
| 4 | 6 | ||
| 5 | ## 技术栈 | 7 | ## 技术栈 |
| 6 | 8 | ||
| 7 | -- Taro4 | 9 | +- **框架**: Taro4 + Vue3 (Composition API) |
| 8 | -- Vue3 | 10 | +- **UI组件库**: NutUI4 + @nutui/icons-vue-taro |
| 9 | -- TypeScript | 11 | +- **状态管理**: Pinia |
| 10 | -- Pinia | 12 | +- **样式**: Less + TailwindCSS |
| 11 | -- Less | 13 | +- **网络请求**: axios-miniprogram |
| 14 | +- **包管理**: pnpm | ||
| 15 | +- **构建工具**: Webpack5 | ||
| 12 | 16 | ||
| 13 | ## 项目结构 | 17 | ## 项目结构 |
| 14 | 18 | ||
| 15 | -- src | 19 | +``` |
| 16 | - - api:请求接口 | 20 | +src/ |
| 17 | - - assets:静态资源 | 21 | +├── api/ # API接口层 |
| 18 | - - components:全局组件 | 22 | +│ ├── index.js # 用户相关API |
| 19 | - - config:项目配置 | 23 | +│ ├── car.js # 车辆相关API |
| 20 | - - pages:页面 | 24 | +│ ├── orders.js # 订单相关API |
| 21 | - - stores:状态管理 | 25 | +│ ├── chat.js # 聊天相关API |
| 22 | - - utils:工具函数 | 26 | +│ ├── common.js # 通用API |
| 23 | - - app.config.js:项目配置 | 27 | +│ ├── other.js # 其他API |
| 24 | - - app.js:应用入口 | 28 | +│ ├── fn.js # API请求封装函数 |
| 25 | - - app.less:全局样式 | 29 | +│ └── wx/ # 微信相关API |
| 26 | -- taro.config.js:Taro配置 | 30 | +├── assets/ # 静态资源 |
| 27 | -- tsconfig.json:TypeScript配置 | 31 | +│ ├── images/ # 图片资源 |
| 28 | -- package.json:依赖配置 | 32 | +│ └── styles/ # 全局样式 |
| 29 | - | 33 | +├── components/ # 全局组件 |
| 30 | -## 项目运行 | 34 | +│ ├── MessageDetail.vue # 消息详情组件 |
| 31 | - | 35 | +│ ├── TabBar.vue # 底部导航栏 |
| 32 | -1. 安装依赖 | 36 | +│ ├── navBar.vue # 顶部导航栏 |
| 37 | +│ └── ... | ||
| 38 | +├── pages/ # 页面文件 | ||
| 39 | +│ ├── index/ # 首页 | ||
| 40 | +│ ├── messages/ # 消息页面 | ||
| 41 | +│ ├── profile/ # 个人中心 | ||
| 42 | +│ ├── collectionSettings/ # 收款设置 | ||
| 43 | +│ └── ... | ||
| 44 | +├── stores/ # 状态管理 | ||
| 45 | +│ ├── user.js # 用户状态 | ||
| 46 | +│ ├── router.js # 路由状态 | ||
| 47 | +│ └── ... | ||
| 48 | +├── utils/ # 工具函数 | ||
| 49 | +│ ├── request.js # 网络请求配置 | ||
| 50 | +│ ├── config.js # 环境配置 | ||
| 51 | +│ ├── permission.js # 权限管理 | ||
| 52 | +│ ├── tools.js # 通用工具函数 | ||
| 53 | +│ └── ... | ||
| 54 | +├── app.config.js # 应用配置 | ||
| 55 | +├── app.js # 应用入口 | ||
| 56 | +└── app.less # 全局样式 | ||
| 57 | +``` | ||
| 58 | + | ||
| 59 | +## 快速开始 | ||
| 60 | + | ||
| 61 | +### 1. 安装依赖 | ||
| 33 | 62 | ||
| 34 | ```bash | 63 | ```bash |
| 64 | +# 推荐使用pnpm | ||
| 65 | +pnpm install | ||
| 66 | + | ||
| 67 | +# 或使用npm | ||
| 35 | npm install | 68 | npm install |
| 36 | ``` | 69 | ``` |
| 37 | 70 | ||
| 38 | -2. 运行项目 | 71 | +### 2. 开发环境运行 |
| 39 | 72 | ||
| 40 | ```bash | 73 | ```bash |
| 74 | +# 微信小程序开发 | ||
| 41 | npm run dev:weapp | 75 | npm run dev:weapp |
| 76 | + | ||
| 77 | +# H5开发 | ||
| 78 | +npm run dev:h5 | ||
| 42 | ``` | 79 | ``` |
| 43 | 80 | ||
| 44 | -3. 打包项目 | 81 | +### 3. 生产环境构建 |
| 45 | 82 | ||
| 46 | ```bash | 83 | ```bash |
| 84 | +# 构建微信小程序 | ||
| 47 | npm run build:weapp | 85 | npm run build:weapp |
| 86 | + | ||
| 87 | +# 构建H5 | ||
| 88 | +npm run build:h5 | ||
| 89 | +``` | ||
| 90 | +## API开发规范 | ||
| 91 | + | ||
| 92 | +### API文件组织结构 | ||
| 93 | + | ||
| 94 | +项目采用模块化的API组织方式,按功能模块划分API文件: | ||
| 95 | + | ||
| 96 | +- `api/index.js` - 用户相关API(注册、登录、个人信息等) | ||
| 97 | +- `api/car.js` - 车辆相关API(发布、编辑、列表、详情等) | ||
| 98 | +- `api/orders.js` - 订单相关API(创建、查询、状态更新等) | ||
| 99 | +- `api/chat.js` - 聊天消息相关API | ||
| 100 | +- `api/common.js` - 通用API(上传、地区数据等) | ||
| 101 | +- `api/other.js` - 其他业务API | ||
| 102 | +- `api/fn.js` - API请求封装函数 | ||
| 103 | + | ||
| 104 | +### API编写规范 | ||
| 105 | + | ||
| 106 | +#### 1. API接口定义 | ||
| 107 | + | ||
| 108 | +```javascript | ||
| 109 | +// 定义API端点常量 | ||
| 110 | +const Api = { | ||
| 111 | + ADD_VEHICLE: '/srv/?a=vehicle&t=add', | ||
| 112 | + EDIT_VEHICLE: '/srv/?a=vehicle&t=edit', | ||
| 113 | + LIST_VEHICLE: '/srv/?a=vehicle&t=list', | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | +/** | ||
| 117 | + * @description: 添加车辆 | ||
| 118 | + * @param {string} title - 标题 | ||
| 119 | + * @param {string} brand - 品牌 | ||
| 120 | + * @param {string} model - 型号 | ||
| 121 | + * @param {number} price - 出让价格 | ||
| 122 | + * @returns {Promise} API响应结果 | ||
| 123 | + */ | ||
| 124 | +export const addVehicleAPI = (params) => fn(fetch.post(Api.ADD_VEHICLE, params)); | ||
| 125 | +``` | ||
| 126 | + | ||
| 127 | +#### 2. 请求封装函数使用 | ||
| 128 | + | ||
| 129 | +项目使用统一的请求封装函数 `fn()` 来处理API响应: | ||
| 130 | + | ||
| 131 | +```javascript | ||
| 132 | +import { fn, fetch } from './fn'; | ||
| 133 | + | ||
| 134 | +// GET请求 | ||
| 135 | +export const getProfileAPI = (params) => fn(fetch.get(Api.GET_PROFILE, params)); | ||
| 136 | + | ||
| 137 | +// POST请求 | ||
| 138 | +export const updateProfileAPI = (params) => fn(fetch.post(Api.UPDATE_PROFILE, params)); | ||
| 139 | +``` | ||
| 140 | + | ||
| 141 | +#### 3. 错误处理机制 | ||
| 142 | + | ||
| 143 | +`fn()` 函数自动处理API响应: | ||
| 144 | +- 成功时返回 `response.data` | ||
| 145 | +- 失败时显示错误提示并返回 `false` | ||
| 146 | +- 特殊处理"计全付"相关错误,使用模态框显示 | ||
| 147 | + | ||
| 148 | +### 网络请求配置 | ||
| 149 | + | ||
| 150 | +#### 1. 环境配置 | ||
| 151 | + | ||
| 152 | +项目支持多环境自动切换(`utils/config.js`): | ||
| 153 | + | ||
| 154 | +```javascript | ||
| 155 | +// 根据小程序运行环境自动切换API地址 | ||
| 156 | +function getBaseUrl() { | ||
| 157 | + const accountInfo = wx.getAccountInfoSync(); | ||
| 158 | + const envVersion = accountInfo.miniProgram.envVersion; | ||
| 159 | + | ||
| 160 | + switch (envVersion) { | ||
| 161 | + case 'develop': // 开发版 | ||
| 162 | + return 'https://oa-dev.onwall.cn'; | ||
| 163 | + case 'trial': // 体验版 | ||
| 164 | + return 'https://oa-dev.onwall.cn'; | ||
| 165 | + case 'release': // 正式版 | ||
| 166 | + return 'https://jiangedianlv.onwall.cn'; | ||
| 167 | + default: | ||
| 168 | + return 'https://jiangedianlv.onwall.cn'; | ||
| 169 | + } | ||
| 170 | +} | ||
| 171 | +``` | ||
| 172 | + | ||
| 173 | +#### 2. 请求拦截器 | ||
| 174 | + | ||
| 175 | +自动添加sessionid到请求头: | ||
| 176 | + | ||
| 177 | +```javascript | ||
| 178 | +// 请求拦截器自动添加认证信息 | ||
| 179 | +service.interceptors.request.use(config => { | ||
| 180 | + const sessionid = getSessionId(); | ||
| 181 | + if (sessionid) { | ||
| 182 | + config.headers.cookie = sessionid; | ||
| 183 | + } | ||
| 184 | + return config; | ||
| 185 | +}); | ||
| 186 | +``` | ||
| 187 | + | ||
| 188 | +#### 3. 响应拦截器 | ||
| 189 | + | ||
| 190 | +自动处理sessionid更新和错误响应: | ||
| 191 | + | ||
| 192 | +```javascript | ||
| 193 | +// 响应拦截器处理sessionid和错误 | ||
| 194 | +service.interceptors.response.use( | ||
| 195 | + response => { | ||
| 196 | + // 自动更新sessionid | ||
| 197 | + const newSessionId = response.headers['set-cookie']; | ||
| 198 | + if (newSessionId) { | ||
| 199 | + setSessionId(newSessionId); | ||
| 200 | + } | ||
| 201 | + return response; | ||
| 202 | + }, | ||
| 203 | + error => { | ||
| 204 | + // 统一错误处理 | ||
| 205 | + console.error('请求失败:', error); | ||
| 206 | + return Promise.reject(error); | ||
| 207 | + } | ||
| 208 | +); | ||
| 209 | +``` | ||
| 210 | + | ||
| 211 | +## 状态管理规范 | ||
| 212 | + | ||
| 213 | +### Pinia Store使用 | ||
| 214 | + | ||
| 215 | +#### 1. 用户状态管理 (`stores/user.js`) | ||
| 216 | + | ||
| 217 | +```javascript | ||
| 218 | +export const useUserStore = defineStore('user', { | ||
| 219 | + state: () => ({ | ||
| 220 | + userInfo: { | ||
| 221 | + avatar_url: '', | ||
| 222 | + nickname: '', | ||
| 223 | + phone: '', | ||
| 224 | + // ... 其他用户信息字段 | ||
| 225 | + }, | ||
| 226 | + isAuthenticated: false, | ||
| 227 | + isLoading: false | ||
| 228 | + }), | ||
| 229 | + | ||
| 230 | + getters: { | ||
| 231 | + // 检查用户信息完整性 | ||
| 232 | + hasCompleteProfile: (state) => { | ||
| 233 | + return !!(state.userInfo.phone && state.userInfo.nickname); | ||
| 234 | + }, | ||
| 235 | + | ||
| 236 | + // 检查收款信息完整性 | ||
| 237 | + hasCompleteCollectionInfo: (state) => { | ||
| 238 | + return !!( | ||
| 239 | + state.userInfo.name && | ||
| 240 | + state.userInfo.bank_id && | ||
| 241 | + state.userInfo.bank_no && | ||
| 242 | + state.userInfo.idcard | ||
| 243 | + ); | ||
| 244 | + } | ||
| 245 | + }, | ||
| 246 | + | ||
| 247 | + actions: { | ||
| 248 | + // 获取用户信息 | ||
| 249 | + async fetchUserInfo() { | ||
| 250 | + this.isLoading = true; | ||
| 251 | + try { | ||
| 252 | + const result = await getProfileAPI(); | ||
| 253 | + if (result && result.data) { | ||
| 254 | + this.updateUserInfo(result.data); | ||
| 255 | + this.isAuthenticated = true; | ||
| 256 | + } | ||
| 257 | + } finally { | ||
| 258 | + this.isLoading = false; | ||
| 259 | + } | ||
| 260 | + }, | ||
| 261 | + | ||
| 262 | + // 更新用户信息 | ||
| 263 | + updateUserInfo(newUserInfo) { | ||
| 264 | + this.userInfo = { ...this.userInfo, ...newUserInfo }; | ||
| 265 | + } | ||
| 266 | + } | ||
| 267 | +}); | ||
| 48 | ``` | 268 | ``` |
| 49 | -# 屏蔽了我的认证相关功能 | 269 | + |
| 270 | +#### 2. 在组件中使用Store | ||
| 271 | + | ||
| 272 | +```javascript | ||
| 273 | +<script setup> | ||
| 274 | +import { useUserStore } from '@/stores/user'; | ||
| 275 | + | ||
| 276 | +const userStore = useUserStore(); | ||
| 277 | + | ||
| 278 | +// 获取用户信息 | ||
| 279 | +onMounted(() => { | ||
| 280 | + userStore.fetchUserInfo(); | ||
| 281 | +}); | ||
| 282 | + | ||
| 283 | +// 使用计算属性 | ||
| 284 | +const hasCompleteInfo = computed(() => userStore.hasCompleteProfile); | ||
| 285 | +</script> | ||
| 286 | +``` | ||
| 287 | + | ||
| 288 | +## 权限管理 | ||
| 289 | + | ||
| 290 | +### 权限检查机制 (`utils/permission.js`) | ||
| 291 | + | ||
| 292 | +```javascript | ||
| 293 | +/** | ||
| 294 | + * 检查用户权限 | ||
| 295 | + * @param {Object} userInfo - 用户信息 | ||
| 296 | + * @param {Array} requiredFields - 必需字段列表 | ||
| 297 | + * @returns {Object} 权限检查结果 | ||
| 298 | + */ | ||
| 299 | +export function checkUserPermissions(userInfo, requiredFields = []) { | ||
| 300 | + const missingFields = requiredFields.filter(field => { | ||
| 301 | + return !userInfo[field] || userInfo[field] === ''; | ||
| 302 | + }); | ||
| 303 | + | ||
| 304 | + return { | ||
| 305 | + hasPermission: missingFields.length === 0, | ||
| 306 | + missingFields, | ||
| 307 | + message: missingFields.length > 0 | ||
| 308 | + ? `请先完善:${missingFields.join('、')}` | ||
| 309 | + : '' | ||
| 310 | + }; | ||
| 311 | +} | ||
| 312 | +``` | ||
| 313 | + | ||
| 314 | +## 组件开发规范 | ||
| 315 | + | ||
| 316 | +### 1. Vue3 Composition API | ||
| 317 | + | ||
| 318 | +```javascript | ||
| 319 | +<script setup> | ||
| 320 | +import { ref, computed, onMounted } from 'vue'; | ||
| 321 | +import { useUserStore } from '@/stores/user'; | ||
| 322 | + | ||
| 323 | +// 响应式数据 | ||
| 324 | +const loading = ref(false); | ||
| 325 | +const userStore = useUserStore(); | ||
| 326 | + | ||
| 327 | +// 计算属性 | ||
| 328 | +const displayName = computed(() => { | ||
| 329 | + return userStore.userInfo.nickname || '未设置昵称'; | ||
| 330 | +}); | ||
| 331 | + | ||
| 332 | +// 生命周期 | ||
| 333 | +onMounted(() => { | ||
| 334 | + initData(); | ||
| 335 | +}); | ||
| 336 | + | ||
| 337 | +// 方法定义 | ||
| 338 | +const initData = async () => { | ||
| 339 | + loading.value = true; | ||
| 340 | + try { | ||
| 341 | + await userStore.fetchUserInfo(); | ||
| 342 | + } finally { | ||
| 343 | + loading.value = false; | ||
| 344 | + } | ||
| 345 | +}; | ||
| 346 | +</script> | ||
| 347 | +``` | ||
| 348 | + | ||
| 349 | +### 2. NutUI组件使用 | ||
| 350 | + | ||
| 351 | +```javascript | ||
| 352 | +<template> | ||
| 353 | + <nut-button type="primary" @click="handleSubmit"> | ||
| 354 | + 提交 | ||
| 355 | + </nut-button> | ||
| 356 | + | ||
| 357 | + <nut-popup v-model:visible="showPopup"> | ||
| 358 | + <nut-form> | ||
| 359 | + <nut-form-item label="姓名"> | ||
| 360 | + <nut-input v-model="form.name" placeholder="请输入姓名" /> | ||
| 361 | + </nut-form-item> | ||
| 362 | + </nut-form> | ||
| 363 | + </nut-popup> | ||
| 364 | +</template> | ||
| 365 | +``` | ||
| 366 | + | ||
| 367 | +## 样式开发规范 | ||
| 368 | + | ||
| 369 | +### 1. TailwindCSS + Less结合使用 | ||
| 370 | + | ||
| 371 | +```vue | ||
| 372 | +<template> | ||
| 373 | + <view class="container"> | ||
| 374 | + <view class="flex justify-between items-center p-4"> | ||
| 375 | + <text class="title">标题</text> | ||
| 376 | + </view> | ||
| 377 | + </view> | ||
| 378 | +</template> | ||
| 379 | + | ||
| 380 | +<style lang="less" scoped> | ||
| 381 | +.container { | ||
| 382 | + background: #f5f5f5; | ||
| 383 | + | ||
| 384 | + .title { | ||
| 385 | + font-size: 32rpx; | ||
| 386 | + font-weight: bold; | ||
| 387 | + color: #333; | ||
| 388 | + } | ||
| 389 | +} | ||
| 390 | +</style> | ||
| 391 | +``` | ||
| 392 | + | ||
| 393 | +### 2. 响应式单位使用 | ||
| 394 | + | ||
| 395 | +- 使用 `rpx` 作为主要单位(小程序自适应) | ||
| 396 | +- 字体大小:`28rpx`、`32rpx`、`36rpx` | ||
| 397 | +- 间距:`16rpx`、`24rpx`、`32rpx` | ||
| 398 | + | ||
| 399 | +## 注意事项 | ||
| 400 | + | ||
| 401 | +### 1. 开发环境 | ||
| 402 | +- 推荐使用 pnpm 作为包管理器 | ||
| 403 | +- Node.js 版本要求:>= 16.0.0 | ||
| 404 | +- 微信开发者工具版本:>= 1.06.0 | ||
| 405 | + | ||
| 406 | +### 2. 代码规范 | ||
| 407 | +- 使用 ESLint 进行代码检查 | ||
| 408 | +- 组件名使用 PascalCase | ||
| 409 | +- 文件名使用 kebab-case | ||
| 410 | +- 变量名使用 camelCase | ||
| 411 | + | ||
| 412 | +### 3. 性能优化 | ||
| 413 | +- 合理使用 `computed` 和 `watch` | ||
| 414 | +- 避免在模板中使用复杂表达式 | ||
| 415 | +- 大列表使用虚拟滚动 | ||
| 416 | +- 图片使用懒加载 | ||
| 417 | + | ||
| 418 | +### 4. 调试技巧 | ||
| 419 | +- 使用 `console.log` 进行调试 | ||
| 420 | +- 利用微信开发者工具的调试功能 | ||
| 421 | +- 网络请求在 Network 面板查看 | ||
| 422 | + | ||
| 423 | +## 功能模块说明 | ||
| 424 | + | ||
| 425 | +### 已屏蔽功能 | ||
| 426 | +- **用户认证功能**:移除了我的认证选项,清理了不再使用的视图模式切换选项 | ||
| 427 | +- **认证相关显示**:在"我卖的车"页面移除了认证按钮和认证状态文字 | ||
| 428 | +- **认证菜单项**:屏蔽了首页认证入口、个人页面认证菜单、订单页面认证列表等3个地方的认证功能 | ||
| 429 | + | ||
| 430 | +### 核心功能模块 | ||
| 431 | +1. **用户管理**:注册、登录、个人信息管理 | ||
| 432 | +2. **车辆交易**:发布车辆、浏览车辆、车辆详情 | ||
| 433 | +3. **订单系统**:下单、支付、订单管理 | ||
| 434 | +4. **消息通知**:系统消息、聊天消息 | ||
| 435 | +5. **收款设置**:银行卡绑定、收款账户管理 | ||
| 436 | + | ||
| 437 | +## 部署说明 | ||
| 438 | + | ||
| 439 | +### 1. 微信小程序部署 | ||
| 440 | +1. 运行 `npm run build:weapp` 构建项目 | ||
| 441 | +2. 使用微信开发者工具打开 `dist` 目录 | ||
| 442 | +3. 点击"上传"按钮上传代码 | ||
| 443 | +4. 在微信公众平台提交审核 | ||
| 444 | + | ||
| 445 | +### 2. H5部署 | ||
| 446 | +1. 运行 `npm run build:h5` 构建项目 | ||
| 447 | +2. 将 `dist` 目录部署到服务器 | ||
| 448 | +3. 配置 nginx 或其他 web 服务器 | ||
| 449 | + | ||
| 450 | +--- | ||
| 451 | + | ||
| 452 | +## 更新日志 | ||
| 50 | - refactor(订单管理): 移除我的认证选项, 清理不再使用的视图模式切换选项,简化界面 | 453 | - refactor(订单管理): 移除我的认证选项, 清理不再使用的视图模式切换选项,简化界面 |
| 51 | -- 我卖的车, 移除认证相关显示和功能,认证按钮和认证状态文字都屏蔽了 | 454 | +- 我卖的车: 移除认证相关显示和功能,认证按钮和认证状态文字都屏蔽了 |
| 52 | - refactor(profile): 移除我的认证菜单项, 屏蔽了首页认证入口,我的页面列表上菜单,我的订单上我的认证列表,3个地方 | 455 | - refactor(profile): 移除我的认证菜单项, 屏蔽了首页认证入口,我的页面列表上菜单,我的订单上我的认证列表,3个地方 | ... | ... |
-
Please register or login to post a comment