### README (README.md)
CRMEB高品质开源商城系统(PHP版)
用心做开源,我们也很需要你的鼓励!右上角Star🌟,等你点亮
####
[](https://zread.ai/crmeb/CRMEB)
[官网](https://www.crmeb.com/?from=githubphp) | [在线体验](http://v6.crmeb.net/admin/) | [帮助文档](https://doc.crmeb.com/single_open) | [应用市场](https://www.crmeb.com/market?from=githubphp) | [技术社区](https://www.crmeb.com/ask/thread/list/147) | [主题广场](https://www.crmeb.com/theme)
--- ### 📝 **项目介绍** **开源自由** CRMEB开源商城系统代码100%开源,基于 **Apache-2.0协议** 免费商用,无任何隐藏费用或功能限制,真正实现“零成本”部署与二次开发自由! **技术架构** 采用 **ThinkPHP 6 + ElementUI + UniApp** 技术栈,前后端分离设计,支持模块化开发与高效维护。前端适配微信小程序、H5、APP、PC等多端,后端统一管理全平台数据,保障流畅体验与高并发性能。 **全场景覆盖** 无缝对接公众号、小程序、H5、APP、PC端,数据实时互通,助力商家一站式运营多渠道业务,满足全场景电商需求。 **原生营销引擎** 内置 **20+核心营销模块**(拼团、砍价、秒杀、优惠券、积分体系、直播带货、付费会员、等级会员、用户充值、分销裂变、渠道码、新人礼等),支持零插件自定义活动规则。通过 **首页DIY功能** ,商家可拖拽式设计商城首页,无需技术背景即可快速搭建高转化场景,实现「所见即所得」的运营效率。 **社区共建计划** 我们致力于打造开发者友好生态,开放源码、持续更新功能模块,并新增主题市场,支持商家一键套用精美商城主题快速装修,开发者与设计师可上架原创主题供用户下载使用,实现创意共享与价值变现。同时欢迎开发者提交优化建议或贡献代码,通过共享技术成果,降低行业重复造轮子成本,推动开源电商系统的可持续发展。 --- ### 📝 **主题广场** **免费下载** 来CRMEB主题广场畅享海量精选模板,零成本打造个性化商城。无需具备专业设计能力,海量免费模版直接下载使用,多样化主题风格可精准匹配不同行业需求,快速提升店铺形象与用户体验,让您的商城在起步阶段就赢在视觉起跑线上。 **一键导入** 化繁为简,极速焕新商城界面。彻底告别过去繁琐的手动DIY配置流程,一键导入主题包,即可将整套主题(包含页面布局与全局配色)无缝融合至您的系统中。系统自动完成组件匹配与数据挂载,无需编写任何代码,即时预览生效。让商城改版升级像换手机壁纸一样轻松,极大节省了运营与开发的时间成本。 **上架主题广场** 不仅随心用,更能轻松赚。您可以利用系统强大的DIY功能,基于原有模块自由组合配色、布局与组件,打造出独具特色的专属主题,并直接上架至主题广场。当其他用户付费下载您的作品时,您将获得相应的收益分成。这不仅为您的设计能力与技术沉淀提供了直接的变现渠道,更助力共建繁荣的开源商城生态,实现创意与价值的双赢。 主题广场:主题广场 主题广场 🔗 功能列表 | 🔗 主题广场 --- ### docker一键体验 ``` # 拉取并运行CRMEB Docker镜像 docker run -d --name crmeb -p 8080:80 ccr.ccs.tencentyun.com/crmebky_php/crmebky:latest ``` #### 访问服务 - **网站**: http://localhost:8080 - **后台**: http://localhost:8080/admin (账号: admin,密码: crmeb.com) - **MySQL**: localhost:3306(账号: root,密码: 123456) - **Redis**: localhost:6379 > 详细说明点击查看 [帮助文档](/help/docker/docker.md)。 --- ### 🫧 技术特点 ~~~ 关于二开: 1.代码规范:遵循PSR-2命名规范、Restful标准接口、代码严格分层、注释齐全、统一错误码; 2.权限管理:内置强大灵活的权限管理,可以控制到每一个菜单; 3.开发配置:低代码增加配置、系统组合数据模块; 4.代码生成:快速生成后台菜单、页面,快速实现增删改查; 5.定时任务:系统内置10中定时任务,还有自定义任务,可以自行设置执行周期,执行代码,完美兼容; 6.系统事件:埋入30+系统事件锚点,可在后台页面进行事件添加; 7.在线编辑:可以在后台对系统的代码进行编辑修改操作,不用登录服务器去修改代码文件,方便快捷; 8.接口管理:后台页面可以看到系统中所有的接口数据,并且可以在线调试接口; 9.二开效率:应用form-builder PHP可以快速生成表单; 10.快速上手:后台接口管理、后台数据库字典、系统文件管理备注、代码注释、一键安装; ~~~ ~~~ 性能与拓展: 1.系统安全:系统操作日志、系统生产日志、文件校验、数据备份; 2.高性能:支持Redis缓存、队列、长连接、多种云储存、支持集群部署; 3.多语言:支持自动识别浏览器多语言展示; 4.驱动扩展:支持多种支付方式、多种短信、多种云储存等; 5.云存储:云存储支持图片和视频的远程云存储,支持阿里云,腾讯云,七牛云,京东云,天翼云,华为云 6.一号通:通用的第三方扩展,支持短信,物流查询,电子面单,电子发票,商品采集,商家寄件 ~~~ --- ### 📖 系统功能 核心功能 --- ### 📖 UI界面展示 PHP_06 --- ### 📖 后台界面展示 PHP_05 --- ### 📱 系统演示 contact2 管理后台: http://v6.crmeb.net/admin 账号:demo 密码:crmeb.com H5端:http://v6.crmeb.net/ (移动端打开) PC端:http://v6.crmeb.net/ (电脑端打开) APP下载:http://app.crmeb.cn/bzv (苹果手机直接在APP Store里搜索CRMEB下载) 主题:https://www.crmeb.com/theme (电脑端打开) > 听说,大神你想看看CRMEB开源项目的完整框架?戳这儿,轻松获取! --- ### 🔐 **运行环境** | **运行环境** | **要求** | |------------------|------------------------------------------------------------------------| | **操作系统** | Linux / Windows | | **WEB 服务** | Nginx / Apache / IIS | | **PHP 版本** | PHP 7.1 ~ 7.4 | | **数据库** | MySQL 5.7 ~ 8.0(引擎:InnoDB) | | **缓存** | Redis(可选,不安装则使用文件缓存) | | **管理器** | Supervisor(用于管理消息队列) | | **推荐工具** | 宝塔面板(简单易用) | | **云服务器** | 阿里云 ECS / 腾讯云 CVM / 京东云ECS | | **开放端口** | 80, 21, 8888, 888, 443, 3306, 6379(授权对象:`0.0.0.0/0`) | | **PHP 扩展** | fileinfo(可选)、redis(可选) | | **禁用函数** | `proc_open`, `pcntl_signal`, `pcntl_signal_dispatch`, `pcntl_fork`, `pcntl_wait`, `pcntl_alarm` | | **消息队列** | 运行命令:`php think queue:listen --queue` (使用Supervisor) | | **长连接** | 运行命令:`sudo -u www php think workerman start --d` (命令行执行) | | **定时任务** | 运行命令:`php think timer start --d` (命令行执行) | > 温馨提示:虚拟空间不支持,推荐使用bt宝塔面板,服务器推荐京东云服务器:注册即享6.5折专属优惠,点我领取! --- ### 📺 **开发环境及使用技术** ### **开发环境:** | 工具 | 版本 | 下载链接 | |--------------|--------------------|-------------------------------------------------------------------------| | **PHP** | 7.1-7.4 | [PHP 官方下载](https://www.php.net/downloads.php) | | **MySQL** | 5.7 | [MySQL 官网](https://www.mysql.com/) | | **Redis** | 7.0 | [Redis 官网](https://redis.io/download) | | **Nginx** | 1.22 | [Nginx 官网](http://nginx.org/en/download.html) | | **Apache** | 2.4 | [Apache HTTP Server](https://httpd.apache.org/download.cgi) | | **Node.js** | 14/18 | [Node.js LTS 版本](https://nodejs.org/en/download/releases/) | ### 后端技术栈 | **技术** | **名称** | **网址** | |---------------------|-----------------------------------------------------------------------------|-------------------------------------------------------------------------| | php扩展库 | PHP 基础运行环境,JSON 数据处理,高精度数学计算等 | https://www.php.net/ | | topthink | ThinkPHP 视图模板引擎,验证码生成组件,队列任务支持,数据库迁移工具 | https://www.thinkphp.cn/ | | overtrue | 微信生态开发(公众号/小程序/支付) | https://github.com/w7corp/easywechat | | php-jwt | JWT 令牌生成与验证 | https://github.com/firebase/php-jwt | | var-dumper | 调试输出工具(格式化变量) | https://symfony.com/doc/current/components/var_dumper.html | | phpoffice | 文件处理 | https://github.com/PHPOffice/PhpSpreadsheet | | guzzlehttp|psr7 | HTTP 客户端库,PSR-7 HTTP 消息接口实现 | https://guzzle-cn.readthedocs.io/zh-cn/latest | | form-builder | 快速构建表单的 UI 工具 | https://form-create.com | | workerman | 高性能 Socket 服务器框架,定时任务调度 | https://www.workerman.net | ### 移动端技术栈 | **技术** | **名称** | **官网** | | --- | --- | --- | | uniapp | 跨端框架 | https://uniapp.dcloud.net.cn/ | | vuex | 状态管理库 | https://vuex.vuejs.org/ | | socket | WebSocket通信 | https://socket.io/ | | dayjs | 时间处理库 | https://day.js.org/ | | animate | CSS动画库 | https://animate.style/ | | easy-loadimage | 图片懒加载 | https://github.com/TSjianjiao/easy-loadimage | ### Admin端技术栈 | **技术** | **名称** | **官网** | | --- | --- | --- | | vue2 | Vue框架 | https://v2.vuejs.org/ | | vuex | 状态管理库 | https://vuex.vuejs.org/ | | element-ui | UI框架 | https://element.eleme.io/ | | axios | HTTP客户端 | https://axios-http.com/ | | vxe-table | 高级表格组件 | https://vxetable.cn/ | | wangeditor | 富文本编辑器 | https://www.wangeditor.com/ | | qs | 查询字符串解析 | https://github.com/ljharb/qs | | xlsx | Excel处理库 | https://sheetjs.com/ | | sass | CSS预处理器 | https://sass-lang.com/ | | prettier | 代码格式化 | https://prettier.io/ | | v-viewer | 图片查看器 | https://github.com/mirari/v-viewer | ### PC端技术栈 | **技术** | **名称** | **官网** | | --- | --- | --- | | nuxt | Vue服务端渲染框架 | https://nuxtjs.org/ | | element | UI框架 | https://element.eleme.io/ | | axios | HTTP客户端 | https://axios-http.com/ | | sass | CSS预处理器 | https://sass-lang.com/ | | cookie-universal-nuxt | Nuxt Cookie处理 | https://github.com/microcipcip/cookie-universal | | postcss | CSS转换工具 | https://postcss.org/ | | qs | 查询字符串解析 | https://github.com/ljharb/qs | ### 想要快速安装,教程来助攻! 快速一键安装部署:https://doc.crmeb.com/single_open/open_v54/20366 手动配置安装:https://doc.crmeb.com/single_open/open_v54/20389 docker-compose一键部署:https://doc.crmeb.com/single_open/open_v54/20145 宝塔环境一键安装:https://doc.crmeb.com/single_open/open_v54/19892 ### 二开支持: 使用文档:https://doc.crmeb.com/single_open/open_v54/19849 接口文档:https://doc.crmeb.com/single_open/open_v54/21040 数据字典:https://doc.crmeb.com/single_open/open_v54/20136 代码生成:https://doc.crmeb.com/single_open/open_v54/20135 二开文档:https://doc.crmeb.com/single_open/open_v54/19851 视频教程:https://www.bilibili.com/video/BV1kh4y1872K/ 技术社区:https://www.crmeb.com/ask/thread/list/147 --- ### 📞 CRMEB互动 #### CRMEB开源技术交流群(扫码进群可领取开源版接口文档、产品功能清单、思维脑图!) 开源群php #### 技术社区!找方法、提bug、看官方消息、拿活跃大奖!都在 CRMEB 技术社区 应有尽有 ### 📕 CRMEB 多商户版 duoshanghu2 --- --- ### Crmeb/Composer.Json (crmeb/composer.json) { "name": "topthink/think", "description": "the new thinkphp framework", "type": "project", "keywords": [ "framework", "thinkphp", "ORM" ], "homepage": "http://thinkphp.cn/", "license": "Apache-2.0", "authors": [ { "name": "liu21st", "email": "liu21st@gmail.com" } ], "require": { "php": ">=7.1.0", "ext-json": "*", "ext-curl": "*", "ext-bcmath": "*", "ext-mbstring": "*", "topthink/think-view": "^1.0", "symfony/var-dumper":"^4.2", "overtrue/wechat": "^3.3", "topthink/think-captcha": "^3.0", "topthink/think-image": "^1.0", "xaboy/form-builder": "2.0.17", "firebase/php-jwt": "^5.0", "aliyuncs/oss-sdk-php": "^2.3", "qcloud/cos-sdk-v5": "v1.3.5", "qiniu/php-sdk": "^7.2", "workerman/workerman": "^3.5", "workerman/channel": "^1.0", "topthink/think-queue": "^3.0", "spatie/macroable": "^1.0", "dh2y/think-qrcode": "^2.0", "topthink/think-multi-app": "^1.0", "topthink/think-template": "^2.0", "phpoffice/phpspreadsheet": "^1.12", "godruoyi/php-snowflake": "^1.0", "qcloud_sts/qcloud-sts-sdk": "^3.0", "guzzlehttp/psr7": "^1.7", "guzzlehttp/guzzle": "6.5.5", "alipaysdk/easysdk": "2.0", "lizhichao/word": "^2.1", "alibabacloud/dysmsapi-20170525": "2.0.16", "fastknife/ajcaptcha": "^1.1", "volcengine/volc-sdk-php": "^1.0", "workerman/crontab": "^1.0", "topthink/think-migration": "^3.0", "topthink/think-filesystem": "^2.0", "aws/aws-sdk-php": "^3.173", "ext-zip": "*", "ext-simplexml": "*", "crmeb/easypay": "^1.0" }, "autoload": { "psr-4": { "app\\": "app", "crmeb\\": "crmeb" }, "psr-0": { "": "extend/" } }, "config": { "preferred-install": "dist", "platform-check": false }, "scripts": { "post-autoload-dump": [ "@php think service:discover", "@php think vendor:publish" ] }, "minimum-stability": "dev", "prefer-stable": true } --- ### Crmeb/FILE GUIDE (crmeb/FILE_GUIDE.md) # crmeb 目录文件说明 ## 目录结构概览 ``` crmeb/ ├── app/ # 应用程序核心代码(控制器、模型、服务等) ├── backup/ # 数据备份文件 ├── config/ # 配置文件(数据库、缓存、接口等) ├── crmeb/ # 项目内部公共模块或扩展库 ├── public/ # Web 可访问入口(静态资源、index.php) ├── route/ # 路由定义 ├── runtime/ # 运行时缓存、日志、Session 等(需忽略版本控制) │ ├── .constant # 常量定义文件(需忽略版本控制) ├── .dockerignore # Docker 构建忽略规则 ├── .env # 环境变量配置(敏感信息)(需忽略版本控制) ├── .env.example # 环境变量示例文件 ├── .htaccess # Apache 重写规则 ├── .phpstorm.meta.php # PhpStorm 元数据 ├── .travis.yml # Travis CI 配置 ├── .version # 版本信息 ├── Dockerfile # Docker 镜像构建文件 ├── LICENSE.txt # 开源许可协议 ├── README.md # 项目说明 ├── build.example.php # 构建示例脚本 ├── composer.json # Composer 依赖配置 ├── composer.lock # Composer 锁定版本 ├── filetree.txt # 文件树结构快照 ├── index.html # 默认首页(防访问目录) ├── my.cnf # MySQL 自定义配置(需忽略版本控制) ├── nginx.conf # Nginx 配置(需忽略版本控制) ├── php-fpm.conf # PHP-FPM 配置(需忽略版本控制) ├── php-ini-overrides.ini# PHP 自定义 ini 覆盖(需忽略版本控制) ├── redis.conf # Redis 配置(需忽略版本控制) ├── start.sh # 项目启动脚本(需忽略版本控制) ├── supervisord.conf # Supervisor 进程管理配置(需忽略版本控制) ├── think # ThinkPHP 框架入口文件 ├── vhost.conf # 虚拟主机配置(需忽略版本控制) └── workerman.bat # Windows 下 Workerman 启动脚本 ``` ## 主要目录说明 - **app/** 存放业务逻辑的核心代码,包括控制器(Controller)、模型(Model)、服务层(Service)等,遵循 MVC 或类似分层架构。 - **backup/** 用于存放数据库或重要数据的备份文件,建议定期清理旧备份。 - **config/** 各种环境与应用配置文件,如数据库、缓存、队列、接口认证等。 - **crmeb/** 项目内部的公共模块或第三方 SDK 集成,可能包含一些工具类或扩展功能。 - **public/** Web 服务器根目录,放置可直接通过浏览器访问的资源(如图片、JS、CSS)以及入口文件 `index.php`。 - **route/** 路由定义文件,用于映射 URL 请求到具体的控制器方法。 - **runtime/** 存放运行时生成的缓存、日志、Session 等临时数据;此目录应在 `.gitignore` 中忽略。 ## 主要文件说明 - **.env / .env.example** 环境变量配置与示例,`.env` 含敏感信息,不要提交到代码库。 - **composer.json / composer.lock** PHP 项目依赖管理配置与锁定文件。 - **Dockerfile / docker-compose 相关** 用于容器化部署的配置。 - **my.cnf / redis.conf / nginx.conf** 各类服务的自定义配置。 - **start.sh** 项目本地或服务器启动入口脚本。 - **think** ThinkPHP 框架的统一入口文件,负责初始化框架并分发请求。 --- ### Crmeb/Filetree (crmeb/filetree.txt) . ├── app 程序主目录 ├── backup 数据库/程序升级备份目录 ├── config 系统配置 ├── crmeb crmeb核心文件目录 ├── public 程序入口目录 ├── route 程序入口路由配置 ├── runtime 缓存目录 ├── temp docker临时文件目录 ├── vendor 扩展包compose 安装目录 ├── LICENSE.txt 开源协议 ├── README.md 系统说明 ├── baota.sh 宝塔快速配置环境文件 ├── build.example.php ├── composer.json ├── composer.lock ├── filetree.txt ├── think tp命令文件入口 ├── timer.pid 定时任务生成文件 ├── updatesql.sql ├── workerman.bat windows 启动workerman命令文件 └── workerman.pid workerman生成文件 9 directories, 12 files --- ### Crmeb/.Travis.Yml (crmeb/.travis.yml) sudo: false language: php branches: only: - stable cache: directories: - $HOME/.composer/cache before_install: - composer self-update install: - composer install --no-dev --no-interaction --ignore-platform-reqs - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip . - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0" - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0" - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0" - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0" - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0" - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0" - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0" - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0" - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0" - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip . script: - php think unit deploy: provider: releases api_key: secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw= file: - ThinkPHP_Core.zip - ThinkPHP_Full.zip skip_cleanup: true on: tags: true --- ### Crmeb/App/README (crmeb/app/README.md) ### 系统目录介绍优化方案 #### 1. 引言 在优化系统目录介绍时,我们的目标是使目录结构更加清晰、易于理解,并突出每个目录的核心功能和作用。 #### 2. 目录结构优化概述 我们将通过以下几个步骤来优化目录介绍: - **明确目录层级**:清晰展示主目录与子目录的关系。 - **突出核心功能**:简要概括每个目录的主要作用和包含的文件类型。 - **增加示例或用途说明**:对于关键目录,提供简短的示例或用途描述,帮助开发者快速理解。 #### 3. 优化后的目录介绍 ## 目录结构 ``` . ├── adminapi/ # 后台管理端API接口 ├── api/ # 移动端API接口 ├── dao/ # DAO层(数据访问对象) ├── http/ # HTTP中间件 ├── jobs/ # 队列任务 ├── kefuapi/ # 客服端API接口 ├── lang/ # 语言包 ├── listener/ # 事件监听器目录 ├── model/ # Model层 ├── services/ # Services层 ├── subscribes/ # 事件订阅 ├── AppService.php # 应用服务类 ├── ExceptionHandle.php # 异常处理器 ├── Request.php # 封装Request类 ├── build.php # 构建配置 ├── common.php # 公共方法 ├── event.php # 事件配置 ├── middleware.php # 中间件配置 ├── provider.php # 容器Provider定义文件 └── service.php # 服务配置 ``` ##### app/ - **核心目录**:存放应用程序的核心代码和资源。 - **包含内容**:业务逻辑、控制器、模型、视图等。 ###### app/adminapi/ - **功能**:管理端应用控制器。 - **用途**:处理管理端用户请求、业务逻辑和数据交互。 - **示例**:管理员登录、权限管理等。 ###### app/api/ - **功能**:用户端应用控制器。 - **用途**:处理用户端请求、业务逻辑和数据交互。 - **示例**:用户注册、商品浏览等。 ###### app/dao/ - **功能**:数据访问对象(DAO)。 - **用途**:封装数据访问操作,提供统一接口。 - **文件类型**:类文件。 ###### app/http/ - **功能**:HTTP请求和响应跨域中间键。 - **用途**:处理跨域请求,确保前后端通信顺畅。 ###### app/jobs/ - **功能**:消息队列任务。 - **用途**:处理异步任务,如邮件发送、数据同步等。 ###### app/kefuapi/ - **功能**:客服端应用控制器。 - **用途**:处理客服端请求、业务逻辑和数据交互。 - **示例**:客服聊天、工单处理等。 ###### app/lang/ - **功能**:语言包。 - **用途**:支持多语言功能,提供不同语言的文本资源。 ###### app/listener/ - **功能**:事件监听器。 - **用途**:监听和处理系统事件,如用户登录、订单生成等。 ###### app/model/ - **功能**:模型类。 - **用途**:封装数据访问操作,提供统一接口。 - **与dao区别**:模型类更侧重于业务逻辑层面的数据操作。 ###### app/outapi/ - **功能**:对外接口应用控制器。 - **用途**:处理外部系统请求、业务逻辑和数据交互。 - **示例**:第三方支付回调、API对接等。 ###### app/service/ - **功能**:服务类。 - **用途**:封装业务逻辑和数据交互操作,提供统一服务接口。 - **示例**:用户服务、订单服务等。 #### 4. 结语 通过上述优化,我们使`app`目录及其子目录的介绍更加清晰、条理分明。每个目录的核心功能和用途都得到了突出展示,有助于开发者快速理解和定位代码。同时,增加的示例和用途说明也进一步降低了理解门槛,提升了开发效率。 --- ### Crmeb/App/Filetree (crmeb/app/filetree.txt) . ├── adminapi //后台管理端API接口 ├── api //移动端API接口 ├── dao //dao层 ├── http //中间件 ├── jobs //队列 ├── kefuapi //客服端API接口 ├── lang //语言包 ├── listener //事件目录 ├── model //model层 ├── services //services层 ├── subscribes //订阅事件 ├── AppService.php // ├── ExceptionHandle.php //异常处理 ├── Request.php //封装request类 ├── build.php // ├── common.php //公共方法 ├── event.php //事件配置 ├── middleware.php //中间件 ├── provider.php //容器Provider定义文件 ├── service.php └── filetree.txt //目录说明 11 directories, 12 files --- ### Crmeb/App/Adminapi/README (crmeb/app/adminapi/README.md) crmeb/app/adminapi这个目录主要是后台管理系统的API接口文件。 具体来说: - adminapi目录下的文件都是后台管理系统的控制器(Controller)文件,这些控制器被用来处理后台系统的各种请求。 - 每一个控制器文件对应后台管理系统某个功能模块,比如AuthController处理认证模块请求,StoreProduct处理商品模块请求等。 - 控制器内有各种方法,这些方法就相当于API接口,可以处理GET、POST请求,返回JSON数据。 - 浏览器或APP在调用这些API接口时,会发送请求到相应的控制器方法,例如登录接口请求到Login文件的login方法。 - 控制器处理完请求后,通过返回Response对象返回处理结果给浏览器或APP。 所以简单来说,adminapi目录负责后台管理系统的所有API接口,这些接口被APP或前端调用来完成各种管理操作,如查询数据、添加修改删除等。开发者在新增后台功能时,也需要在此目录增加对应的控制器和接口。 它实际上负责后台系统的通信交互层,解耦了后端逻辑和前端展示,采用 RESTful规范设计。 # adminapi 目录结构说明 ## 目录结构 ``` . ├── config/ # 配置目录 ├── controller/ # 控制器目录 ├── lang/ # 语言包目录 ├── middleware/ # 中间件目录 ├── route/ # 路由配置目录 ├── validate/ # 验证器目录 ├── AdminApiExceptionHandle.php # 异常处理器 ├── common.php # 公共方法 ├── event.php # 事件配置 └── provider.php # 服务提供者 ``` ## 目录说明 - **config/** - 后台管理端专用配置 - **controller/** - 后台管理控制器,处理管理端业务逻辑 - **lang/** - 后台管理端多语言文件 - **middleware/** - 后台管理中间件,如权限验证、日志记录等 - **route/** - 后台管理路由配置 - **validate/** - 后台管理数据验证器 ## 功能说明 adminapi模块专门用于处理后台管理系统的API接口,包括: - 用户权限管理 - 商品管理 - 订单处理 - 数据统计 - 系统设置等后台管理功能 --- ### Crmeb/App/Adminapi/Filetree (crmeb/app/adminapi/filetree.txt) . ├── config ├── controller ├── lang ├── middleware ├── route ├── validate ├── AdminApiExceptionHandle.php ├── common.php ├── event.php ├── filetree.txt └── provider.php 6 directories, 5 files --- ### Crmeb/App/Api/Filetree (crmeb/app/api/filetree.txt) . ├── config ├── controller ├── lang ├── middleware ├── route ├── validate ├── ApiExceptionHandle.php ├── common.php ├── event.php ├── filetree.txt └── provider.php 6 directories, 5 files --- ### Crmeb/App/Dao/README (crmeb/app/dao/README.md) crmeb/app/dao目录是项目数据访问对象(DAO)层的代码目录。 DAO层主要职责和作用如下: 1. 实现数据持久层访问,对数据库进行CURD操作。 2. 依赖数据库连接,实现对表的基本增删改查功能。 3. 封装数据库操作原语(查询,插入,更新等),简化开发难度。 4. 与数据库解藕,提供统一接口,便于扩展和维护。 具体来说: - dao目录下每个文件对应一个数据表或业务模块 - 文件内封装了对表基本操作的方法,如查找,插入,更新等 - 方法的参数和返回值类型为模型对象(Model),实现数据和业务的解耦 - 提供丰富的查询条件以方便调用 - 底层利用ThinkPHP的ActiveRecord实现数据操作 使用DAO层的好处: - 提供对象化的数据操作接口 - 屏蔽数据库差异,提高移植性 - 方便测试和扩展 - 实现业务和数据层的分离 所以该目录负责项目的底层数据操作,其他业务需要调用它来操作数据库。 --- ### Crmeb/App/Dao/Filetree (crmeb/app/dao/filetree.txt) . ├── activity │   ├── advance │   ├── bargain │   ├── combination │   ├── coupon │   ├── integral │   ├── live │   ├── lottery │   └── seckill ├── agent │   ├── AgentLevelDao.php │   ├── AgentLevelTaskDao.php │   ├── AgentLevelTaskRecordDao.php │   └── DivisionAgentApplyDao.php ├── article │   ├── ArticleCategoryDao.php │   ├── ArticleContentDao.php │   └── ArticleDao.php ├── diy │   ├── DiyDao.php │   ├── PageCategoryDao.php │   └── PageLinkDao.php ├── order │   ├── DeliveryServiceDao.php │   ├── OtherOrderDao.php │   ├── OtherOrderStatusDao.php │   ├── StoreCartDao.php │   ├── StoreOrderCartInfoDao.php │   ├── StoreOrderDao.php │   ├── StoreOrderEconomizeDao.php │   ├── StoreOrderInvoiceDao.php │   ├── StoreOrderRefundDao.php │   ├── StoreOrderStatusDao.php │   ├── StoreOrderStoreOrderCartInfoDao.php │   └── StoreOrderStoreOrderStatusDao.php ├── other │   ├── AgreementDao.php │   ├── AuxiliaryDao.php │   ├── CacheDao.php │   ├── CategoryDao.php │   ├── QrcodeDao.php │   └── TemplateMessageDao.php ├── product │   ├── product │   └── sku ├── service │   ├── StoreServiceAuxiliaryDao.php │   ├── StoreServiceDao.php │   ├── StoreServiceFeedbackDao.php │   ├── StoreServiceLogDao.php │   ├── StoreServiceRecordDao.php │   └── StoreServiceSpeechcraftDao.php ├── shipping │   ├── ExpressDao.php │   ├── ShippingTemplatesDao.php │   ├── ShippingTemplatesFreeCityDao.php │   ├── ShippingTemplatesFreeDao.php │   ├── ShippingTemplatesNoDeliveryCityDao.php │   ├── ShippingTemplatesNoDeliveryDao.php │   ├── ShippingTemplatesRegionCityDao.php │   ├── ShippingTemplatesRegionDao.php │   └── SystemCityDao.php ├── sms │   ├── SmsAdminDao.php │   └── SmsRecordDao.php ├── system │   ├── admin │   ├── attachment │   ├── config │   ├── log │   ├── statistics │   ├── store │   ├── AppVersionDao.php │   ├── MessageSystemDao.php │   ├── SystemMenusDao.php │   ├── SystemNotificationDao.php │   └── SystemUserLevelDao.php ├── user │   ├── MemberCardBatchDao.php │   ├── MemberCardDao.php │   ├── MemberRightDao.php │   ├── MemberShipDao.php │   ├── UserAddressDao.php │   ├── UserAuthDao.php │   ├── UserBillDao.php │   ├── UserBillStoreOrderDao.php │   ├── UserBrokerageDao.php │   ├── UserBrokerageFrozenDao.php │   ├── UserCancelDao.php │   ├── UserDao.php │   ├── UserExtractDao.php │   ├── UserFriendsDao.php │   ├── UserGroupDao.php │   ├── UserInvoiceDao.php │   ├── UserLabelCateDao.php │   ├── UserLabelDao.php │   ├── UserLabelRelationDao.php │   ├── UserLevelDao.php │   ├── UserMoneyDao.php │   ├── UserRechargeDao.php │   ├── UserSearchDao.php │   ├── UserSignDao.php │   ├── UserSpreadDao.php │   ├── UserStoreOrderDao.php │   ├── UserTaskFinishDao.php │   ├── UserUserBillDao.php │   ├── UserUserBrokerageDao.php │   ├── UserVisitDao.php │   └── UserWechatUserDao.php ├── wechat │   ├── WechatKeyDao.php │   ├── WechatMediaDao.php │   ├── WechatMenuDao.php │   ├── WechatMessageDao.php │   ├── WechatNewsCategoryDao.php │   ├── WechatQrcodeCateDao.php │   ├── WechatQrcodeDao.php │   ├── WechatQrcodeRecordDao.php │   ├── WechatReplyDao.php │   ├── WechatReplyKeyDao.php │   └── WechatUserDao.php ├── BaseDao.php └── filetree.txt 29 directories, 95 files --- ### Crmeb/App/Jobs/README (crmeb/app/jobs/README.md) crmeb/app/jobs目录是CRMEB项目队列任务类的代码目录。 队列任务在项目开发中有以下几个重要作用: 1. 异步处理。可以将一些耗时较长的任务放入队列以异步处理,不阻塞主线程。 2. 延迟处理。可以指定队列任务在一定时间后异步执行,比如发送短信或邮件。 3. 分布处理。可以将队列任务分布到不同服务器进行处理,提高服务器使用效率。 此目录下主要包含以下内容: - 每个任务类对应一个业务任务,实现Job接口。 - 任务类内定义具体任务业务逻辑,如发送短信/邮件等。 - 通过Broker进行任务的发送和异步处理。 - 支持任务延时、失败重试等功能。 使用队列可以使得项目性能更优: - 阻塞任务剥离出来异步执行。 - 分布式下每个任务独立运行,不阻塞其他进程。 - 通过Broker复用同一服务,且伸缩性好。 所以此目录负责项目中所有异步任务的编写和调度,起到优化系统性能和扩展能力的重要作用。 --- ### Crmeb/App/Jobs/Filetree (crmeb/app/jobs/filetree.txt) . ├── notice │   ├── EnterpriseWechatJob.php │   ├── PrintJob.php │   └── SmsJob.php ├── AgentJob.php ├── AutoCommentJob.php ├── LiveJob.php ├── OrderCreateAfterJob.php ├── OrderJob.php ├── OtherOrderJob.php ├── PinkJob.php ├── PosterJob.php ├── ProductCopyJob.php ├── ProductLogJob.php ├── RoutineTemplateJob.php ├── TakeOrderJob.php ├── TaskJob.php ├── TemplateJob.php ├── UnpaidOrderCancelJob.php ├── UnpaidOrderSend.php ├── UserJob.php ├── WechatTemplateJob.php └── filetree.txt 1 directory, 22 files --- ### Crmeb/App/Kefuapi/README (crmeb/app/kefuapi/README.md) crmeb/app/kefuapi这个目录是用来放置客服相关接口的。 主要作用和特征: 1. 提供客服系统与商城前后端交互的API接口。 2. 接口主要用于聊天记录的增删改查以及发送消息等功能。 3. 使用ThinkPHP的Restful风格定义接口请求方式和参数。 4. 接口供移动端APP和PC网站调用实现客服聊天功能。 5. 后台也可以调用相关接口对客服记录进行管理。 具体包含: - 控制器定义各API接口方法接受请求。 - 业务处理逻辑以及与数据库的交互。 - 数据验证和结果输出。 使用这个目录定义的客服API,可以: - 商城各端实现在线客服功能。 - 查看历史记录。 - 服务端管理客服信息。 - 第三方也可以实现其它客服系统对接。 所以总之,此目录主要对客服系统开放API接口,便于商城多端整合用户支持体系。 --- ### Crmeb/App/Listener/README (crmeb/app/listener/README.md) crmeb/app/listener目录用来定义项目的事件监听器。 在ThinkPHP框架中,事件监听器是一个重要的机制。它可以用于: - 项目运行过程中的各个时间点自动调用指定的监听方法。 - 监听特定事物(如请求、响应等)发生后自动执行回调。 - 监听其它模块触发的事件,实现扩展钩子函数。 具体来说: - 监听器类实现接口定义监听方法。 - 方法内可以完成业务逻辑,也可以触发下一个监听器。 - 监听器在配置中注册,在特定点自动调用定义的回调方法。 - 常见监听点有请求开始、响应结束等生命周期点。 这种设计可以: - 实现跨模块调用无需依赖。 - 解耦业务和基础模块。 - 让第三方功能易于插拔扩展。 所以此目录定义的就是项目各种事件监听回调,起到系统级的扩展与定制作用。 --- ### Crmeb/App/Listener/Filetree (crmeb/app/listener/filetree.txt) . ├── http │   └── HttpEnd.php ├── notice │   └── Notice.php ├── order │   ├── OrderCreateAfter.php │   ├── OrderDelivery.php │   ├── OrderPaySuccess.php │   ├── OrderRefund.php │   └── OrderTake.php ├── user │   ├── Login.php │   ├── Register.php │   ├── UserLevel.php │   └── UserVisit.php ├── wechat │   └── Auth.php └── filetree.txt 5 directories, 13 files --- ### Crmeb/App/Model/README (crmeb/app/model/README.md) crmeb/app/model目录用于定义项目的数据模型类。 数据模型类的主要作用和特征有: 1. 每个模型类对应数据库中的一张表。 2. 类属性定义表结构,与表结构一一对应。 3. 包含读写数据相关方法,通过ActiveRecord实现。 4. 提供数据与数据库层解耦,统一的数据访问接口。 5. 数据验证机制,保证数据完整性和一致性。 具体包含: - 定义模型属性,字段名称对应表结构。 - 自动返回属性值和赋值属性值。 - 实现基础的CRUD方法操作数据库。 - 可扩展自定义数据逻辑和验证规则。 使用模型类可以: - 减少直接操作数据库带来的复杂性。 - 跨项目重用数据层逻辑。 - 提高项目的可扩展性与复用性。 所以该目录定义的数据模型层,统一封装了项目运用的数据表模型和操作方式。 --- ### Crmeb/App/Model/Filetree (crmeb/app/model/filetree.txt) . ├── activity │   ├── advance │   ├── bargain │   ├── combination │   ├── coupon │   ├── integral │   ├── live │   ├── lottery │   └── seckill ├── agent │   ├── AgentLevel.php │   ├── AgentLevelTask.php │   ├── AgentLevelTaskRecord.php │   └── DivisionAgentApply.php ├── article │   ├── Article.php │   ├── ArticleCategory.php │   └── ArticleContent.php ├── diy │   ├── Diy.php │   ├── PageCategory.php │   └── PageLink.php ├── order │   ├── DeliveryService.php │   ├── OtherOrder.php │   ├── OtherOrderStatus.php │   ├── StoreCart.php │   ├── StoreOrder.php │   ├── StoreOrderCartInfo.php │   ├── StoreOrderEconomize.php │   ├── StoreOrderInvoice.php │   ├── StoreOrderRefund.php │   ├── StoreOrderStatus.php │   └── StorePink.php ├── other │   ├── Agreement.php │   ├── Auxiliary.php │   ├── Cache.php │   ├── Category.php │   ├── Express.php │   ├── Qrcode.php │   └── TemplateMessage.php ├── product │   ├── product │   └── sku ├── service │   ├── StoreService.php │   ├── StoreServiceFeedback.php │   ├── StoreServiceLog.php │   ├── StoreServiceRecord.php │   └── StoreServiceSpeechcraft.php ├── shipping │   ├── ShippingTemplates.php │   ├── ShippingTemplatesFree.php │   ├── ShippingTemplatesNoDelivery.php │   ├── ShippingTemplatesRegion.php │   └── SystemCity.php ├── sms │   └── SmsRecord.php ├── system │   ├── admin │   ├── attachment │   ├── config │   ├── log │   ├── statistics │   ├── store │   ├── AppVersion.php │   ├── MessageSystem.php │   ├── SystemMenus.php │   ├── SystemNotification.php │   ├── SystemUserLevel.php │   └── SystemUserTask.php ├── user │   ├── MemberCard.php │   ├── MemberCardBatch.php │   ├── MemberRight.php │   ├── MemberShip.php │   ├── User.php │   ├── UserAddress.php │   ├── UserBill.php │   ├── UserBrokerage.php │   ├── UserBrokerageFrozen.php │   ├── UserCancel.php │   ├── UserExtract.php │   ├── UserFriends.php │   ├── UserGroup.php │   ├── UserInvoice.php │   ├── UserLabel.php │   ├── UserLabelCate.php │   ├── UserLabelRelation.php │   ├── UserLevel.php │   ├── UserMoney.php │   ├── UserRecharge.php │   ├── UserSearch.php │   ├── UserSign.php │   ├── UserSpread.php │   ├── UserTaskFinish.php │   └── UserVisit.php ├── wechat │   ├── WechatKey.php │   ├── WechatMedia.php │   ├── WechatMessage.php │   ├── WechatNewsCategory.php │   ├── WechatQrcode.php │   ├── WechatQrcodeCate.php │   ├── WechatQrcodeRecord.php │   ├── WechatReply.php │   └── WechatUser.php └── filetree.txt 29 directories, 80 files --- ### Crmeb/App/Outapi/README (crmeb/app/outapi/README.md) crmeb/app/outapi目录用于定义项目对外开放的接口。 具体来说: - 是项目对合作第三方开放的API接口定义目录 - 这里的接口可以被第三方直接调用来获取数据或完成相关业务 - 这类API接口与内部使用的API有区别: - 对外开放,不需要登录授权 - 安全限制较严,只提供必要接口 - 接口规范遵循RESTful原则 - 常见场景: - 第方小程序/APP直接获取商品数据 - 第方商户后台系统同步订单信息 - 小程序支付回调通知接口 使用这个目录定义外部接口可以: - 实现与其他系统的深度集成 - 让更多场景能够使用CRMEB提供的能力 - 降低对第方的侵入性,仅开放必要接口 所以总结来说,outapi用于项目对外部开放的公开API,扩展第三方接入能力。 --- ### Crmeb/App/Outapi/Mcp (crmeb/app/outapi/mcp.md) # CRMEB MCP Server 基于 Model Context Protocol (MCP) 的 CRMEB API 工具服务器,已集成到 CRMEB outapi 模块中,允许 AI 助手通过标准协议调用 CRMEB 对外开放接口。 ## 功能特性 - 🔗 集成到 CRMEB outapi 模块,无需额外部署 - 📦 商品管理(列表、详情、创建) - 📂 分类管理(列表、详情、创建) - 🛒 订单管理(列表、详情、发货) - 💰 售后管理(列表、详情、同意/拒绝退款) - 🎫 优惠券管理 - 👥 用户管理(列表、详情、赠送余额/积分) ## 环境要求 - CRMEB 系统 - PHP >= 7.4 ## 快速开始 ### 1. 创建开放接口账号 1. 登录 CRMEB 管理后台 2. 进入 **设置** -> **系统设置** -> **开放接口** 3. 创建应用获取账号和密码 ### 2. 配置到 Claude Desktop 编辑配置文件: **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "crmeb": { "url": "http://your-domain/outapi/mcp", "headers": { "account": "your_account", "password": "your_password", "Content-Type": "application/json" }, "disabled": false } } } ``` **配置示例(演示环境):** ```json { "mcpServers": { "crmebdemo": { "url": "https://v5.crmeb.net/outapi/mcp", "headers": { "account": "ceshi", "password": "ceshiceshi", "Content-Type": "application/json" }, "disabled": false } } } ``` ### 3. 配置到 Cursor 在 Cursor 设置中添加: ```json { "mcp.servers": { "crmeb": { "url": "http://your-domain/outapi/mcp", "headers": { "account": "your_account", "password": "your_password", "Content-Type": "application/json" }, "disabled": false } } } ``` **参数说明:** | 参数 | 说明 | 获取方式 | |------|------|---------| | `url` | CRMEB MCP 接口地址 | 固定值:`http://域名/outapi/mcp` | | `account` | 开放接口账号 | CRMEB 后台 -> 设置 -> 开放接口 | | `password` | 开放接口密码 | CRMEB 后台 -> 设置 -> 开放接口 | | `disabled` | 是否禁用该服务 | 可选,默认为 false | > 注意:直接配置 account 和 password 即可,系统会自动完成认证 ## 支持的 MCP 客户端应用 以下是目前主流的支持 MCP 协议的应用程序,您可以在这些应用中配置和使用 CRMEB MCP 服务。 ### 1. Claude Desktop Anthropic 官方桌面应用,首个原生支持 MCP 的客户端。 **配置步骤:** 1. 下载并安装 [Claude Desktop](https://claude.ai/download) 2. 找到配置文件: - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` 3. 添加 CRMEB MCP 配置: ```json { "mcpServers": { "crmeb": { "url": "http://your-domain/outapi/mcp", "headers": { "account": "your_account", "password": "your_password", "Content-Type": "application/json" }, "disabled": false } } } ``` 4. 重启 Claude Desktop **使用方法:** 在对话中直接询问,例如: ``` 帮我查询 CRMEB 中的商品分类列表 ``` ### 2. Cursor AI 驱动的代码编辑器,内置 MCP 支持。 **配置步骤:** 1. 下载并安装 [Cursor](https://cursor.sh/) 2. 打开设置(Settings -> Features -> Model Context Protocol) 3. 添加 MCP 服务器配置: ```json { "mcp.servers": { "crmeb": { "url": "http://your-domain/outapi/mcp", "headers": { "account": "your_account", "password": "your_password", "Content-Type": "application/json" }, "disabled": false } } } ``` 4. 或者直接编辑配置文件: - **macOS/Linux**: `~/.cursor/mcp.json` - **Windows**: `%APPDATA%\Cursor\mcp.json` **使用方法:** 在 Cursor 的 AI 聊天窗口中直接使用: ``` 查询 CRMEB 中的订单列表 ``` ### 3. Cline (VS Code 扩展) VS Code 中的自主 AI 编程助手扩展。 **配置步骤:** 1. 在 VS Code 中安装 [Cline 扩展](https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev) 2. 打开 VS Code 设置 3. 搜索 "Cline MCP" 或在 Cline 面板中找到 MCP 配置 4. 添加 MCP 服务器: ```json { "mcpServers": { "crmeb": { "url": "http://your-domain/outapi/mcp", "headers": { "account": "your_account", "password": "your_password", "Content-Type": "application/json" }, "disabled": false } } } ``` **使用方法:** 在 Cline 面板中输入指令: ``` 获取 CRMEB 商品 ID 为 1 的详情 ``` ### 4. Windsurf Codeium 推出的 AI 原生 IDE。 **配置步骤:** 1. 下载并安装 [Windsurf](https://codeium.com/windsurf) 2. 打开设置 -> Developer Settings -> MCP Servers 3. 添加配置: ```json { "mcpServers": { "crmeb": { "url": "http://your-domain/outapi/mcp", "headers": { "account": "your_account", "password": "your_password", "Content-Type": "application/json" } } } } ``` ### 5. Continue (VS Code/JetBrains 扩展) 开源的 AI 代码助手扩展。 **配置步骤:** 1. 安装 Continue 扩展 - [VS Code](https://marketplace.visualstudio.com/items?itemName=Continue.continue) - [JetBrains](https://plugins.jetbrains.com/plugin/22707-continue) 2. 打开 Continue 配置文件(`~/.continue/config.json`) 3. 添加 MCP 配置: ```json { "models": [...], "mcpServers": { "crmeb": { "url": "http://your-domain/outapi/mcp", "headers": { "account": "your_account", "password": "your_password", "Content-Type": "application/json" } } } } ``` ### 6. Zed 高性能代码编辑器,支持 MCP 协议。 **配置步骤:** 1. 下载并安装 [Zed](https://zed.dev/) 2. 打开配置文件(`~/.zed/settings.json`) 3. 添加 MCP 服务器配置: ```json { "mcp_servers": { "crmeb": { "url": "http://your-domain/outapi/mcp", "headers": { "account": "your_account", "password": "your_password", "Content-Type": "application/json" } } } } ``` ### 7. 其他支持 MCP 的应用 以下应用也在逐步支持 MCP 协议: - **Codeium**:AI 代码补全工具 - **Tabnine**:AI 代码助手 - **Sourcegraph Cody**:代码智能助手 > 💡 **提示**:MCP 是一个开放协议,越来越多的 AI 应用正在支持。如果您的应用支持 MCP,通常可以在设置中找到 MCP 或 Model Context Protocol 相关配置项。 ## 可用工具 ### 分类管理 | 工具名称 | 描述 | 必需参数 | 可选参数 | |---------|------|---------|---------| | `crmeb_category_list` | 获取分类列表 | - | page, limit | | `crmeb_category_detail` | 获取分类详情 | id | - | | `crmeb_category_create` | 创建分类 | name | pid, sort | ### 商品管理 | 工具名称 | 描述 | 必需参数 | 可选参数 | |---------|------|---------|---------| | `crmeb_product_list` | 获取商品列表 | - | page, limit, cate_id, keyword, stock_min, stock_max | | `crmeb_product_detail` | 获取商品详情 | id | - | | `crmeb_product_create` | 创建商品 | name, cate_id, price, stock | image, unit | ### 订单管理 | 工具名称 | 描述 | 必需参数 | 可选参数 | |---------|------|---------|---------| | `crmeb_order_list` | 获取订单列表 | - | page, limit, status, keyword | | `crmeb_order_detail` | 获取订单详情 | order_id | - | | `crmeb_order_delivery` | 订单发货 | order_id, delivery_type | delivery_name, delivery_id | | `crmeb_order_express_list` | 获取物流公司列表 | - | - | ### 售后管理 | 工具名称 | 描述 | 必需参数 | 可选参数 | |---------|------|---------|---------| | `crmeb_refund_list` | 获取售后列表 | - | page, limit | | `crmeb_refund_detail` | 获取售后详情 | order_id | - | | `crmeb_refund_agree` | 同意退款 | order_id | - | | `crmeb_refund_refuse` | 拒绝退款 | order_id, refuse_reason | - | ### 优惠券管理 | 工具名称 | 描述 | 必需参数 | 可选参数 | |---------|------|---------|---------| | `crmeb_coupon_list` | 获取优惠券列表 | - | page, limit | ### 用户管理 | 工具名称 | 描述 | 必需参数 | 可选参数 | |---------|------|---------|---------| | `crmeb_user_list` | 获取用户列表 | - | page, limit, keyword | | `crmeb_user_detail` | 获取用户详情 | uid | - | | `crmeb_user_give_balance` | 赠送余额 | uid, balance | title | | `crmeb_user_give_point` | 赠送积分 | uid, point | title | ## 使用示例 在 Claude 或 Cursor 中,您可以这样使用: ``` 帮我查询 CRMEB 中的商品列表 ``` ``` 创建一个新商品:名称"测试商品",分类ID 1,价格 99.00,库存 100 ``` ``` 查询订单号 202403130001 的详情 ``` ``` 给用户 ID 为 1 的用户赠送 100 积分 ``` ## 接口测试 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 项目结构 ``` crmeb/app/outapi/ ├── controller/ │ ├── Mcp.php # MCP 控制器 │ ├── Login.php # 认证控制器 │ ├── StoreProduct.php # 商品控制器 │ ├── StoreCategory.php # 分类控制器 │ ├── StoreOrder.php # 订单控制器 │ ├── RefundOrder.php # 售后控制器 │ ├── StoreCoupon.php # 优惠券控制器 │ ├── User.php # 用户控制器 │ └── ... ├── route/ │ └── route.php # 路由配置 ├── middleware/ │ └── AuthTokenMiddleware.php ├── mcp.md # 本文档 └── README.md # outapi 模块说明 ``` ## 协议说明 ### MCP 协议版本 - 支持版本:`2024-11-05` ### JSON-RPC 2.0 格式 **请求格式:** ```json { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "工具名称", "arguments": { "参数": "值" } } } ``` **成功响应:** ```json { "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "{...结果数据...}" } ] } } ``` **错误响应:** ```json { "jsonrpc": "2.0", "id": 1, "error": { "code": -32603, "message": "错误信息" } } ``` ## 错误码说明 | 错误码 | 说明 | |-------|------| | -32700 | JSON 解析错误 | | -32600 | 请求无效(认证失败等) | | -32601 | 方法不存在 | | -32603 | 内部错误 | ## 相关链接 - [Model Context Protocol 文档](https://modelcontextprotocol.io/) - [CRMEB 开放接口](./README.md) --- ### Crmeb/App/Services/README (crmeb/app/services/README.md) crmeb/app/services目录用于定义项目的业务服务类。 服务类的主要特征和作用包括: 1. 服务类封装具体的业务逻辑和规则。 2. 完成功能模块的抽象,提供统一的业务接口。 3. 解耦项目各部分,降低他们之间的耦合度。 4. 提供给上下文的整个环境使用。 具体来说: - 每个服务类对应一个独立的业务功能或规则集合。 - 类内部可以调用其它模块完成业务需求。 - 对外提供简单的业务接口,隐藏内部实现细节。 - 服务类存在依赖关系,可以互相调用实现聚合服务。 使用服务层设计可以: - 松耦合各个模块,提高扩展和重用能力。 - 同一个业务规则在多个场景复用。 - 加强项目的可测试性与维护性。 所以此目录定义了项目核心业务服务模块,对外提供可复用的核心能力。 --- ### Crmeb/Backup/Readme (crmeb/backup/readme.md) crmeb/backup目录在CRMEB项目中的主要作用是用于保存项目的数据备份文件。 该目录用于存储系统运行过程中生成的各类备份数据,保障数据安全和灾难恢复能力。 具体来说: - 数据库备份文件,用于数据恢复和迁移 - 系统配置文件备份,防止配置丢失 - 重要业务数据的历史归档 - 升级前的数据快照,便于回滚操作 - 定时任务自动生成的备份文件 使用这个目录有以下优点: - 实现数据的定期备份与版本管理 - 与运行数据隔离,确保备份数据安全 - 便于快速恢复系统到指定时间点 - 支持手动和自动化的备份策略 - 方便进行数据迁移和系统升级 总体来说,它承担了项目数据安全保护和灾难恢复的核心职责。 通过合理利用这个目录,可以有效降低数据丢失风险,提升系统的可靠性和可维护性。 --- ### Crmeb/Config/README (crmeb/config/README.md) crmeb/config目录用来存放项目的配置文件。 在PHP项目开发中,配置文件扮演着非常重要的角色: - 放置各种系统级参数和设置,如数据库连接信息等 - 分离软件代码和运行环境设置,方便部署 - 运行时根据配置加载系统服务和组件 - 参数可在不修改代码的情况下进行变更 CRMEB项目中config目录负责: - 放置如数据库、本地缓存、第三方开放API等系统配置 - 定义项目组件自动加载机制 - 路由和URL重写规则 - 错误和日志输出级别 - 各环境参数差异配置隔离 项目在运行时会加载并解析这些配置: - 初始化系统服务如数据库连接 - 注册组件到容器 - 根据配置加载运行环境 - 提供参数和变量给其它模块 所以该目录定义了项目的系统架构和运行环境,对项目有重要影响。 它通过配置实现项目的可配置性和扩展性。 --- ### Crmeb/Config/Filetree (crmeb/config/filetree.txt) . ├── app.php // ├── cache.php //缓存配置 ├── captcha.php //验证码配置 ├── console.php //命令行配置 ├── cookie.php //cookie配置 ├── database.php //数据库配置 ├── filesystem.php //系统文件目录配置 ├── lang.php //多语言配置 ├── log.php //日志配置 ├── pay.php //支付配置 ├── plat.php //对接平台配置 ├── printer.php //小票打印机配置 ├── qrcode.php //二维码配置 ├── queue.php //队列配置 ├── route.php //路由配置 ├── session.php //session配置 ├── sms.php //短信发送配置 ├── template.php //微信模版消息配置 ├── trace.php //调试配置 ├── upload.php //上传配置 ├── view.php //模版配置 ├── workerman.php //workerman配置 └── filetree.txt //目录文件说明 0 directories, 23 files --- ### Crmeb/Crmeb/README (crmeb/crmeb/README.md) crmeb目录在CRMEB项目中的作用是一个特殊目录 - crmeb目录实际上是整个项目的核心库目录 - 它包含项目的核心类、traits、异常定义等 - 这些核心文件提供给整个项目 reused - 例如请求处理类、响应处理类等 - 它实现了项目特定的封装和扩展 - 使项目各部分能够在一套框架体系下开发 简而言之,crmeb目录: - 包含项目的各种核心基础支持类 - 为整个项目提供基础功能定定义 - 使项目具备一致性和可扩展性 - 是项目最核心和基础的代码库 --- ### Crmeb/Crmeb/Filetree (crmeb/crmeb/filetree.txt) . ├── basic │   ├── BaseController.php //控制器基类 │   ├── BaseJobs.php //队列基类 │   ├── BaseManager.php //驱动管理基类 │   ├── BaseModel.php //model基类 │   └── BaseStorage.php //驱动基类 ├── command │   ├── stubs //命令模版 │   ├── Dao.php //创建Dao类命令 │   ├── Service.php //创建Service类命令 │   ├── Timer.php //定时任务命令类 │   └── Workerman.php //workman命令类 ├── exceptions │   ├── AdminException.php //后台管理端异常处理 │   ├── ApiException.php //移动端接口异常处理 │   ├── AuthException.php //用户授权异常处理 │   ├── PayException.php //支付异常处理 │   ├── SmsException.php //短信异常处理 │   ├── TemplateException.php //微信模版消息异常处理 │   ├── UploadException.php //上传异常处理 │   └── WechatReplyException.php //微信自动回复异常处理 ├── interfaces │   ├── JobInterface.php //队列任务 │   ├── ListenerInterface.php //事件 │   ├── MiddlewareInterface.php //中间件 │   └── ProviderInterface.php //容器 ├── services │   ├── app //应用端 │   ├── easywechat //easywechat │   ├── express //物流查询 │   ├── pay //支付 │   ├── printer //打印机 │   ├── copyproduct //采集商品 │   ├── serve //服务平台 │   ├── sms //短信 │   ├── template //模版消息 │   ├── upload //上传 │   ├── workerman //workerman │   ├── AccessTokenServeService.php //获取token │   ├── AliPayService.php │   ├── CacheService.php //缓存类 │   ├── FileService.php //文件处理类 │   ├── FormBuilder.php //自动生成表单类 │   ├── GroupDataService.php //组合数据类 │   ├── HttpService.php //curl 请求处理类 │   ├── MysqlBackupService.php //数据库备份管理类 │   ├── SpreadsheetExcelService.php //excel处理类 │   ├── SystemConfigService.php //系统配置获取类 │   ├── UpgradeService.php //系统更新类 │   └── UploadService.php //文件上传类 ├── traits │   ├── ErrorTrait.php //错误处理扩展类 │   ├── JwtAuthModelTrait.php //Jwt鉴权扩展类 │   ├── ModelTrait.php //model扩展类 │   ├── QueueTrait.php //队列扩展累 │   ├── SearchDaoTrait.php //dao扩展类 │   └── ServicesTrait.php //Services扩展类 ├── utils │   ├── Arr.php //操作数组帮助类 │   ├── Canvas.php //图片处理类 │   ├── Captcha.php //验证码类 │   ├── DownloadImage.php //远程图片下载类 │   ├── ErrorCode.php //错误码处理类 │   ├── Hook.php //钩子类 │   ├── Json.php //Json处理类 │   ├── JwtAuth.php //Jwt鉴权类 │   ├── QRcode.php //二维码获取类 TODO │   ├── Queue.php //队列类 │   └── Str.php //字符处理类 └── filetree.txt 17 directories, 70 files --- ### Crmeb/Public/Admin/Manifest.Json (crmeb/public/admin/manifest.json) { "name":"CRMEB", "display":"standalone", "start_url":".", "id": "index.html", "background_color": "#999", "theme_color":"#292d3e", "icons":[{ "src":"./image/logo-small.png", "sizes":"144x144", "type":"image/png" }] } --- ### Crmeb/Public/Statics/Mp View/App.Json (crmeb/public/statics/mp_view/app.json) { "pages": [ "pages/guide/index", "pages/index/index", "pages/order_addcart/order_addcart", "pages/user/index", "pages/goods_cate/goods_cate" ], "subPackages": [ { "root": "pages/goods_details", "pages": [ "index" ], "name": "goods_details" }, { "root": "pages/extension", "pages": [ "customer_list/chat", "news_list/index", "news_details/index" ], "name": "extension" }, { "root": "pages/goods", "pages": [ "goods_list/index", "goods_search/index", "order_pay_status/index", "admin_order_detail/index", "goods_comment_con/index", "goods_comment_con/lottery_comment", "goods_comment_list/index", "goods_details_store/index", "goods_logistics/index", "goods_return/index", "goods_return_list/index", "lottery/grids/index", "lottery/grids/record", "order_confirm/index", "order_details/index", "order_list/index", "order_refund_goods/index", "receive_gifts_status/index", "receive_gift/index", "cashier/index" ], "name": "goods" }, { "root": "pages/users", "pages": [ "user_vip_areer/index", "privacy/index", "user_cancellation/index", "message_center/index", "message_center/messageDetail", "user_invoice_order/index", "scan_login/index", "user_invoice_list/index", "user_invoice_form/index", "wechat_login/index", "binding_phone/index", "retrievePassword/index", "user_info/index", "user_get_coupon/index", "visit_list/index", "user_goods_collection/index", "user_sgin/index", "user_sgin_list/index", "user_money/index", "user_bill/index", "user_integral/index", "user_coupon/index", "user_spread_user/index", "user_spread_code/index", "user_spread_money/index", "user_spread_money/receiving", "user_cash/index", "user_vip/index", "user_distribution_level/index", "user_address_list/index", "user_address/index", "user_phone/index", "user_payment/index", "user_pwd_edit/index", "promoter-list/index", "promoter-order/index", "promoter_rank/index", "commission_rank/index", "user_return_list/index", "login/index", "payment_on_behalf/index", "payment_on_behalf/pay_status", "staff_list/index" ], "name": "users", "plugins": { "live-player-plugin": { "version": "1.3.5", "provider": "wx2b03c6e691cd7370" } } }, { "root": "pages/activity", "pages": [ "goods_bargain/index", "goods_bargain_details/index", "goods_combination/index", "goods_combination_details/index", "goods_combination_status/index", "goods_seckill/index", "goods_seckill_details/index", "poster-poster/index", "bargain/index", "presell/index" ], "name": "activity" }, { "root": "pages/admin", "pages": [ "distribution/index", "distribution/scanning/index", "distribution/scanning/detail/index", "distribution/orderDetail/index", "custom_date/index", "order/index", "orderList/index", "orderDetail/index", "delivery/index", "refund/index", "logistics/index", "refund_order_list/index", "refund_order_detail/index", "goods/index", "goods/specs", "goods/addGoods", "user/list", "user/index", "statistics/index", "order_cancellation/index" ], "name": "adminOrder" }, { "root": "pages/columnGoods", "pages": [ "HotNewGoods/index", "HotNewGoods/feedback", "live_list/index" ], "name": "columnGoods" }, { "root": "pages/annex", "pages": [ "web_view/index", "vip_paid/index", "vip_coupon/index", "vip_clause/index", "vip_active/index", "offline_pay/index", "offline_result/index", "special/index", "settled/index" ] }, { "root": "pages/points_mall", "pages": [ "index", "integral_goods_list", "integral_goods_details", "exchange_record", "integral_order", "user_address", "integral_order_status", "integral_order_details", "logistics_details" ] }, { "root": "subpackage/diyComponents", "pages": [ "pages/placeholder" ], "name": "diyComponents" } ], "window": { "navigationBarTextStyle": "black", "navigationBarTitleText": "加载中", "navigationBarBackgroundColor": "#fff", "backgroundColor": "#F8F8F8", "titleNView": false, "pageOrientation": "portrait" }, "tabBar": { "color": "#282828", "selectedColor": "#ff3366", "borderStyle": "white", "backgroundColor": "#ffffff", "list": [ { "pagePath": "pages/index/index", "iconPath": "static/images/1-001.png", "selectedIconPath": "static/images/1-002.png", "text": "首页" }, { "pagePath": "pages/goods_cate/goods_cate", "iconPath": "static/images/2-001.png", "selectedIconPath": "static/images/2-002.png", "text": "分类" }, { "pagePath": "pages/order_addcart/order_addcart", "iconPath": "static/images/3-001.png", "selectedIconPath": "static/images/3-002.png", "text": "购物车" }, { "pagePath": "pages/user/index", "iconPath": "static/images/4-001.png", "selectedIconPath": "static/images/4-002.png", "text": "我的" } ] }, "permission": { "scope.userLocation": { "desc": "你的位置信息将用于查看与门店的距离" } }, "requiredPrivateInfos": [ "getLocation", "onLocationChange", "startLocationUpdateBackground", "chooseAddress" ], "__usePrivacyCheck__": true, "usingComponents": { "skeleton": "/components/skeleton/index", "page-loading": "/components/pageLoading", "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "base-money": "/components/BaseMoney", "base-tag": "/components/BaseTag", "base-drawer": "/components/tuiDrawer/tui-drawer" }, "sitemapLocation": "sitemap.json" } --- ### Crmeb/Public/Statics/Mp View/Project.Config.Json (crmeb/public/statics/mp_view/project.config.json) { "description": "项目配置文件。", "packOptions": { "ignore": [], "include": [] }, "setting": { "urlCheck": false, "es6": true, "postcss": true, "minified": true, "newFeature": true, "bigPackageSizeSupport": true, "babelSetting": { "ignore": [], "disablePlugins": [], "outputPath": "" } }, "compileType": "miniprogram", "libVersion": "3.15.2", "appid": "wx3b82801238ca1b57", "projectname": "CRMEB标准版", "condition": {}, "editorSetting": { "tabIndent": "insertSpaces", "tabSize": 2 } } --- ### Crmeb/Public/Statics/Mp View/Project.Private.Config.Json (crmeb/public/statics/mp_view/project.private.config.json) { "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", "projectname": "CRMEB标准版", "setting": { "compileHotReLoad": true } } --- ### Crmeb/Public/Statics/Mp View/Sitemap.Json (crmeb/public/statics/mp_view/sitemap.json) { "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", "rules": [{ "action": "allow", "page": "*" }] } --- ### Crmeb/Public/Statics/Mp View/Components/Jyf Parser/Jyf Parser.Json (crmeb/public/statics/mp_view/components/jyf-parser/jyf-parser.json) { "component": true, "usingComponents": { "trees": "/components/jyf-parser/libs/trees" } } --- ### Crmeb/Public/Statics/Mp View/Components/Jyf Parser/Libs/Trees.Json (crmeb/public/statics/mp_view/components/jyf-parser/libs/trees.json) { "component": true, "usingComponents": { "trees": "/components/jyf-parser/libs/trees" } } --- ### Crmeb/Public/Statics/Mp View/Components/PageFooter/Index.Json (crmeb/public/statics/mp_view/components/pageFooter/index.json) { "component": true, "usingComponents": { "base-badge": "/components/BaseBadge/index" } } --- ### Crmeb/Public/Statics/Mp View/Components/Recommend/Index.Json (crmeb/public/statics/mp_view/components/recommend/index.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage" } } --- ### Crmeb/Public/Statics/Mp View/Components/WaterfallsFlow/WaterfallsFlow.Json (crmeb/public/statics/mp_view/components/WaterfallsFlow/WaterfallsFlow.json) { "component": true, "usingComponents": { "waterfalls-flow-item": "/components/WaterfallsFlow/WaterfallsFlowItem" } } --- ### Crmeb/Public/Statics/Mp View/Components/WaterfallsFlow/WaterfallsFlowItem.Json (crmeb/public/statics/mp_view/components/WaterfallsFlow/WaterfallsFlowItem.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Bargain/Index.Json (crmeb/public/statics/mp_view/pages/activity/bargain/index.json) { "navigationBarTitleText": "砍价记录", "usingComponents": { "count-down": "/components/countDown/index", "loading": "/components/Loading/index", "empty-page": "/components/emptyPage", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Goods Bargain/Index.Json (crmeb/public/statics/mp_view/pages/activity/goods_bargain/index.json) { "navigationBarTitleText": "砍价列表", "usingComponents": { "home": "/components/home/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Goods Bargain Details/Index.Json (crmeb/public/statics/mp_view/pages/activity/goods_bargain_details/index.json) { "navigationBarTitleText": "砍价活动", "usingComponents": { "jyf-parser": "/components/jyf-parser/jyf-parser", "count-down": "/components/countDown/index", "authorize": "/components/Authorize", "home": "/components/home/index", "bargain-poster": "/pages/activity/poster-poster/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Goods Combination/Index.Json (crmeb/public/statics/mp_view/pages/activity/goods_combination/index.json) { "navigationBarTitleText": "拼团活动", "usingComponents": { "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Goods Combination Details/Index.Json (crmeb/public/statics/mp_view/pages/activity/goods_combination_details/index.json) { "navigationStyle": "custom", "usingComponents": { "product-con-swiper": "/components/productConSwiper/index", "kefu-icon": "/components/kefuIcon/index", "authorize": "/components/Authorize", "product-window": "/components/productWindow/index", "user-evaluation": "/components/userEvaluation/index", "count-down": "/components/countDown/index", "cus-preview-img": "/components/cusPreviewImg/index", "parser": "/components/jyf-parser/jyf-parser", "menu-icon": "/components/menuIcon", "home-list": "/components/homeList/index", "swiper-previe": "/components/cusPreviewImg/swiperPrevie" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Goods Combination Status/Index.Json (crmeb/public/statics/mp_view/pages/activity/goods_combination_status/index.json) { "navigationBarTitleText": "拼团", "usingComponents": { "count-down": "/components/countDown/index", "product-window": "/components/productWindow/index", "home": "/components/home/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Goods Seckill/Index.Json (crmeb/public/statics/mp_view/pages/activity/goods_seckill/index.json) { "navigationBarTitleText": "限时秒杀", "usingComponents": { "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Goods Seckill Details/Index.Json (crmeb/public/statics/mp_view/pages/activity/goods_seckill_details/index.json) { "navigationStyle": "custom", "navigationBarTextStyle": "white", "usingComponents": { "product-con-swiper": "/components/productConSwiper/index", "product-window": "/components/productWindow/index", "user-evaluation": "/components/userEvaluation/index", "kefu-icon": "/components/kefuIcon/index", "menu-icon": "/components/menuIcon", "count-down": "/components/countDown/index", "cus-preview-img": "/components/cusPreviewImg/index", "swiper-previe": "/components/cusPreviewImg/swiperPrevie", "parser": "/components/jyf-parser/jyf-parser", "home-list": "/components/homeList/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Poster Poster/Index.Json (crmeb/public/statics/mp_view/pages/activity/poster-poster/index.json) { "navigationBarTitleText": "砍价海报", "usingComponents": { "zb-code": "/components/zb-code/zb-code" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Activity/Presell/Index.Json (crmeb/public/statics/mp_view/pages/activity/presell/index.json) { "navigationBarTitleText": "预售列表", "usingComponents": { "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Components/Uni Calendar/Uni Calendar.Json (crmeb/public/statics/mp_view/pages/admin/components/uni-calendar/uni-calendar.json) { "component": true, "usingComponents": { "uni-calendar-item": "/pages/admin/components/uni-calendar/uni-calendar-item" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Custom Date/Index.Json (crmeb/public/statics/mp_view/pages/admin/custom_date/index.json) { "navigationBarTitleText": "选择日期", "usingComponents": { "uni-calendar": "/pages/admin/components/uni-calendar/uni-calendar" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Delivery/Index.Json (crmeb/public/statics/mp_view/pages/admin/delivery/index.json) { "navigationBarTitleText": "订单发货", "usingComponents": { "split-order": "/pages/admin/components/splitOrder/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Distribution/Index.Json (crmeb/public/statics/mp_view/pages/admin/distribution/index.json) { "navigationStyle": "custom", "usingComponents": { "loading": "/components/Loading/index", "empty-page": "/components/emptyPage", "nav-bar": "/components/NavBar" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Distribution/OrderDetail/Index.Json (crmeb/public/statics/mp_view/pages/admin/distribution/orderDetail/index.json) { "navigationStyle": "custom", "usingComponents": { "custom-form": "/pages/admin/components/customForm/index", "nav-bar": "/components/NavBar" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Distribution/Scanning/Index.Json (crmeb/public/statics/mp_view/pages/admin/distribution/scanning/index.json) { "navigationBarTitleText": "订单核销", "usingComponents": { "write-off-list": "/pages/admin/components/writeOffList/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Distribution/Scanning/Detail/Index.Json (crmeb/public/statics/mp_view/pages/admin/distribution/scanning/detail/index.json) { "navigationBarTitleText": "订单核销", "usingComponents": { "write-off-switching": "/pages/admin/components/writeOffSwitching/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Goods/AddGoods.Json (crmeb/public/statics/mp_view/pages/admin/goods/addGoods.json) { "navigationBarTitleText": "添加商品", "usingComponents": { "nav-bar": "/components/NavBar", "classify": "/pages/admin/goods/components/classify/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Goods/Index.Json (crmeb/public/statics/mp_view/pages/admin/goods/index.json) { "navigationStyle": "custom", "navigationBarTitleText": "商品管理", "usingComponents": { "edit-price": "/pages/admin/goods/components/editPrice/index", "edit-lable": "/pages/admin/goods/components/label/index", "classify": "/pages/admin/goods/components/classify/index", "footer-page": "/pages/admin/components/footerPage/index", "empty-page": "/components/emptyPage", "loading": "/components/Loading/index", "base-drawer": "/components/tuiDrawer/tui-drawer" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Goods/Specs.Json (crmeb/public/statics/mp_view/pages/admin/goods/specs.json) { "navigationBarTitleText": "修改价格/库存", "navigationBarBackgroundColor": "#F5F5F5", "usingComponents": { "edit-price": "/pages/admin/goods/components/editPrice/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Goods/Components/Classify/Index.Json (crmeb/public/statics/mp_view/pages/admin/goods/components/classify/index.json) { "component": true, "usingComponents": { "empty-page": "/components/emptyPage", "base-drawer": "/components/tuiDrawer/tui-drawer" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Goods/Components/EditPrice/Index.Json (crmeb/public/statics/mp_view/pages/admin/goods/components/editPrice/index.json) { "component": true, "usingComponents": { "base-drawer": "/components/tuiDrawer/tui-drawer" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Goods/Components/Label/Index.Json (crmeb/public/statics/mp_view/pages/admin/goods/components/label/index.json) { "component": true, "usingComponents": { "empty-page": "/components/emptyPage", "base-drawer": "/components/tuiDrawer/tui-drawer" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Logistics/Index.Json (crmeb/public/statics/mp_view/pages/admin/logistics/index.json) { "navigationBarTitleText": "物流信息", "navigationStyle": "custom", "usingComponents": { "nav-bar": "/components/NavBar", "empty-page": "/components/emptyPage" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Order/Index.Json (crmeb/public/statics/mp_view/pages/admin/order/index.json) { "navigationBarTitleText": "订单统计", "usingComponents": { "loading": "/components/Loading/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Order Cancellation/Index.Json (crmeb/public/statics/mp_view/pages/admin/order_cancellation/index.json) { "navigationBarTitleText": "订单核销", "usingComponents": { "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/OrderDetail/Index.Json (crmeb/public/statics/mp_view/pages/admin/orderDetail/index.json) { "navigationBarTitleText": "订单详情", "usingComponents": { "price-change": "/pages/admin/components/PriceChange/index", "custom-form": "/pages/admin/components/customForm/index", "count-down": "/components/countDown/index", "nav-bar": "/components/NavBar" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/OrderList/Index.Json (crmeb/public/statics/mp_view/pages/admin/orderList/index.json) { "navigationBarTitleText": "订单列表", "usingComponents": { "loading": "/components/Loading/index", "price-change": "/pages/admin/components/PriceChange/index", "footer-page": "/pages/admin/components/footerPage/index", "count-down": "/components/countDown/index", "empty-page": "/components/emptyPage", "nav-bar": "/components/NavBar" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Refund/Index.Json (crmeb/public/statics/mp_view/pages/admin/refund/index.json) { "navigationBarTitleText": "售后退款", "navigationStyle": "custom", "usingComponents": { "split-order": "/pages/admin/components/splitOrder/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Refund Order Detail/Index.Json (crmeb/public/statics/mp_view/pages/admin/refund_order_detail/index.json) { "navigationBarTitleText": "售后订单详情", "navigationStyle": "custom", "usingComponents": { "price-change": "/pages/admin/components/PriceChange/index", "custom-form": "/pages/admin/components/customForm/index", "nav-bar": "/components/NavBar" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Refund Order List/Index.Json (crmeb/public/statics/mp_view/pages/admin/refund_order_list/index.json) { "navigationBarTitleText": "售后订单列表", "navigationStyle": "custom", "usingComponents": { "loading": "/components/Loading/index", "price-change": "/pages/admin/components/PriceChange/index", "empty-page": "/components/emptyPage", "nav-bar": "/components/NavBar", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/Statistics/Index.Json (crmeb/public/statics/mp_view/pages/admin/statistics/index.json) { "navigationBarTitleText": "订单数据统计", "usingComponents": { "uni-calendar": "/pages/admin/components/uni-calendar/uni-calendar" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/User/Index.Json (crmeb/public/statics/mp_view/pages/admin/user/index.json) { "navigationStyle": "custom", "navigationBarTitleText": "用户详情", "usingComponents": { "edit-lable": "/pages/admin/user/components/userLable/index", "edit-balance": "/pages/admin/user/components/editBalance/index", "member": "/pages/admin/user/components/member/index", "coupon": "/pages/admin/user/components/coupon/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/User/List.Json (crmeb/public/statics/mp_view/pages/admin/user/list.json) { "navigationStyle": "custom", "navigationBarTitleText": "用户管理", "usingComponents": { "edit-lable": "/pages/admin/user/components/userLable/index", "edit-balance": "/pages/admin/user/components/editBalance/index", "member": "/pages/admin/user/components/member/index", "coupon": "/pages/admin/user/components/coupon/index", "user-filter": "/pages/admin/user/components/filter/index", "footer-page": "/pages/admin/components/footerPage/index", "empty-page": "/components/emptyPage", "loading": "/components/Loading/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/User/Components/Coupon/Index.Json (crmeb/public/statics/mp_view/pages/admin/user/components/coupon/index.json) { "component": true, "usingComponents": { "empty-page": "/components/emptyPage" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Admin/User/Components/UserLable/Index.Json (crmeb/public/statics/mp_view/pages/admin/user/components/userLable/index.json) { "component": true, "usingComponents": { "empty-page": "/components/emptyPage" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Components/Verify/Verify.Json (crmeb/public/statics/mp_view/pages/annex/components/verify/verify.json) { "component": true, "usingComponents": { "verify-slide": "/pages/annex/components/verify/verifySlider/verifySlider", "verify-point": "/pages/annex/components/verify/verifyPoint/verifyPoint", "verify-slider-pc": "/pages/annex/components/verify/verifySlider/verifySliderPc" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Offline Pay/Index.Json (crmeb/public/statics/mp_view/pages/annex/offline_pay/index.json) { "navigationBarTitleText": "支付", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Offline Result/Index.Json (crmeb/public/statics/mp_view/pages/annex/offline_result/index.json) { "navigationBarTitleText": "支付结果", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Settled/Index.Json (crmeb/public/statics/mp_view/pages/annex/settled/index.json) { "navigationBarTitleText": "分销申请", "usingComponents": { "jyf-parser": "/components/jyf-parser/jyf-parser", "verify": "/pages/annex/components/verify/verify", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Special/Index.Json (crmeb/public/statics/mp_view/pages/annex/special/index.json) { "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#333333", "navigationBarTitleText": "专题页", "componentPlaceholder": { "page-design": "view" }, "usingComponents": { "page-design": "/subpackage/diyComponents/pageDesign", "loading": "/components/Loading/index", "page-footer": "/components/pageFooter/index", "coupon-window": "/components/couponWindow/index", "waterfalls-flow": "/components/WaterfallsFlow/WaterfallsFlow", "empty-page": "/components/emptyPage" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Vip Active/Index.Json (crmeb/public/statics/mp_view/pages/annex/vip_active/index.json) { "navigationBarTitleText": "激活会员", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Vip Clause/Index.Json (crmeb/public/statics/mp_view/pages/annex/vip_clause/index.json) { "navigationBarTitleText": "会员协议", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Vip Coupon/Index.Json (crmeb/public/statics/mp_view/pages/annex/vip_coupon/index.json) { "navigationBarTitleText": "会员优惠券", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Annex/Vip Paid/Index.Json (crmeb/public/statics/mp_view/pages/annex/vip_paid/index.json) { "navigationBarTitleText": "SVIP会员", "usingComponents": { "home": "/components/home/index", "payment": "/components/payment/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/ColumnGoods/HotNewGoods/Feedback.Json (crmeb/public/statics/mp_view/pages/columnGoods/HotNewGoods/feedback.json) { "navigationBarTitleText": "我的客服", "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#3A3A3A", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/ColumnGoods/HotNewGoods/Index.Json (crmeb/public/statics/mp_view/pages/columnGoods/HotNewGoods/index.json) { "navigationBarTitleText": "精品推荐", "usingComponents": { "good-list": "/components/goodList/index", "empty-page": "/components/emptyPage", "home": "/components/home/index", "page-footer": "/components/pageFooter/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/ColumnGoods/Live List/Index.Json (crmeb/public/statics/mp_view/pages/columnGoods/live_list/index.json) { "navigationBarTitleText": "精彩内容", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Extension/Customer List/Chat.Json (crmeb/public/statics/mp_view/pages/extension/customer_list/chat.json) { "navigationBarTitleText": "对话详情", "navigationBarBackgroundColor": "#3875EA", "navigationBarTextStyle": "white", "usingComponents": { "loading": "/components/Loading/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Extension/News Details/Index.Json (crmeb/public/statics/mp_view/pages/extension/news_details/index.json) { "navigationBarTitleText": "资讯详情", "usingComponents": { "share-info": "/pages/extension/components/shareInfo/index", "home": "/components/home/index", "parser": "/components/jyf-parser/jyf-parser" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Extension/News List/Index.Json (crmeb/public/statics/mp_view/pages/extension/news_list/index.json) { "navigationBarTitleText": "资讯", "usingComponents": { "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Admin Order Detail/Index.Json (crmeb/public/statics/mp_view/pages/goods/admin_order_detail/index.json) { "navigationBarTitleText": "订单详情", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Cashier/Index.Json (crmeb/public/statics/mp_view/pages/goods/cashier/index.json) { "navigationBarTitleText": "收银台", "usingComponents": { "count-down": "/components/countDown/index", "number-scroll": "/components/numberScroll" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Comment Con/Index.Json (crmeb/public/statics/mp_view/pages/goods/goods_comment_con/index.json) { "navigationBarTitleText": "商品评价", "usingComponents": { "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Comment Con/Lottery Comment.Json (crmeb/public/statics/mp_view/pages/goods/goods_comment_con/lottery_comment.json) { "navigationBarTitleText": "订单评价", "usingComponents": { "authorize": "/components/Authorize", "grids-lottery": "/pages/goods/components/lottery/index", "lottery-aleart": "/pages/goods/goods_comment_con/components/lotteryAleart", "user-address": "/pages/goods/goods_comment_con/components/userAddress" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Comment Con/Components/UserAddress.Json (crmeb/public/statics/mp_view/pages/goods/goods_comment_con/components/userAddress.json) { "component": true, "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Comment List/Index.Json (crmeb/public/statics/mp_view/pages/goods/goods_comment_list/index.json) { "navigationBarTitleText": "商品评分", "usingComponents": { "user-evaluation": "/components/userEvaluation/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Details Store/Index.Json (crmeb/public/statics/mp_view/pages/goods/goods_details_store/index.json) { "navigationBarTitleText": "门店列表", "usingComponents": { "loading": "/components/Loading/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods List/Index.Json (crmeb/public/statics/mp_view/pages/goods/goods_list/index.json) { "navigationBarTitleText": "商品列表", "usingComponents": { "recommend": "/components/recommend/index", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Logistics/Index.Json (crmeb/public/statics/mp_view/pages/goods/goods_logistics/index.json) { "navigationBarTitleText": "物流信息", "usingComponents": { "recommend": "/components/recommend/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Return/Index.Json (crmeb/public/statics/mp_view/pages/goods/goods_return/index.json) { "navigationBarTitleText": "申请退货", "usingComponents": { "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Return List/Index.Json (crmeb/public/statics/mp_view/pages/goods/goods_return_list/index.json) { "navigationBarTitleText": "退货列表", "usingComponents": { "split-order": "/pages/goods/components/splitOrder/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Goods Search/Index.Json (crmeb/public/statics/mp_view/pages/goods/goods_search/index.json) { "navigationBarTitleText": "搜索商品", "usingComponents": { "good-list": "/components/goodList/index", "recommend": "/components/recommend/index", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Lottery/Components/UserAddress.Json (crmeb/public/statics/mp_view/pages/goods/lottery/components/userAddress.json) { "component": true, "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Lottery/Grids/Index.Json (crmeb/public/statics/mp_view/pages/goods/lottery/grids/index.json) { "navigationBarTitleText": "抽奖活动", "usingComponents": { "grids-lottery": "/pages/goods/components/lottery/index", "show-box": "/pages/goods/lottery/components/showbox", "notice-bar": "/pages/goods/lottery/components/noticeBar", "lottery-aleart": "/pages/goods/lottery/components/lotteryAleart", "user-address": "/pages/goods/lottery/components/userAddress", "zb-code": "/components/zb-code/zb-code", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Lottery/Grids/Record.Json (crmeb/public/statics/mp_view/pages/goods/lottery/grids/record.json) { "navigationBarTitleText": "中奖记录", "usingComponents": { "empty-page": "/components/emptyPage", "user-address": "/pages/goods/lottery/components/userAddress" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Order Confirm/Index.Json (crmeb/public/statics/mp_view/pages/goods/order_confirm/index.json) { "navigationBarTitleText": "提交订单", "usingComponents": { "payment": "/components/payment/index", "invoice-picker": "/pages/goods/components/invoicePicker/index", "coupon-list-window": "/components/couponListWindow/index", "address-window": "/components/addressWindow/index", "order-goods": "/components/orderGoods/index", "home": "/components/home/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Order Details/Index.Json (crmeb/public/statics/mp_view/pages/goods/order_details/index.json) { "navigationBarTitleText": "订单详情", "usingComponents": { "zb-code": "/components/zb-code/zb-code", "home": "/components/home/index", "invoice-picker": "/pages/goods/components/invoicePicker/index", "invoice-modal": "/pages/goods/components/invoiceModal/index", "order-goods": "/components/orderGoods/index", "gift-modal": "/pages/goods/order_pay_status/components/giftModal", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Order List/Index.Json (crmeb/public/statics/mp_view/pages/goods/order_list/index.json) { "navigationBarTitleText": "我的订单", "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "home": "/components/home/index", "empty-page": "/components/emptyPage", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Order Pay Status/Index.Json (crmeb/public/statics/mp_view/pages/goods/order_pay_status/index.json) { "navigationBarTitleText": "支付成功", "usingComponents": { "lottery-model": "/pages/goods/order_pay_status/payLottery", "gift-modal": "/pages/goods/order_pay_status/components/giftModal", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Order Pay Status/PayLottery.Json (crmeb/public/statics/mp_view/pages/goods/order_pay_status/payLottery.json) { "component": true, "usingComponents": { "authorize": "/components/Authorize", "grids-lottery": "/pages/goods/components/lottery/index", "lottery-aleart": "/pages/goods/order_pay_status/components/lotteryAleart", "user-address": "/pages/goods/order_pay_status/components/userAddress" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Order Pay Status/Components/UserAddress.Json (crmeb/public/statics/mp_view/pages/goods/order_pay_status/components/userAddress.json) { "component": true, "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Order Refund Goods/Index.Json (crmeb/public/statics/mp_view/pages/goods/order_refund_goods/index.json) { "navigationBarTitleText": "退回商品", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Receive Gift/Index.Json (crmeb/public/statics/mp_view/pages/goods/receive_gift/index.json) { "navigationBarTitleText": "领取礼物", "navigationBarBackgroundColor": "#e93323", "navigationBarTextStyle": "white", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods/Receive Gifts Status/Index.Json (crmeb/public/statics/mp_view/pages/goods/receive_gifts_status/index.json) { "navigationBarTitleText": "领取结果", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods Cate/Goods Cate.Json (crmeb/public/statics/mp_view/pages/goods_cate/goods_cate.json) { "navigationBarTitleText": "商品分类", "usingComponents": { "goods-cate1": "/pages/goods_cate/goods_cate1", "goods-cate2": "/pages/goods_cate/goods_cate2", "goods-cate3": "/pages/goods_cate/goods_cate3", "page-footer": "/components/pageFooter/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods Cate/Goods Cate1.Json (crmeb/public/statics/mp_view/pages/goods_cate/goods_cate1.json) { "component": true, "usingComponents": { "page-footer": "/components/pageFooter/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods Cate/Goods Cate2.Json (crmeb/public/statics/mp_view/pages/goods_cate/goods_cate2.json) { "component": true, "usingComponents": { "product-window": "/components/productWindow/index", "good-list": "/components/catGoodList/index", "cart-list": "/components/cartList/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods Cate/Goods Cate3.Json (crmeb/public/statics/mp_view/pages/goods_cate/goods_cate3.json) { "component": true, "usingComponents": { "product-window": "/components/productWindow/index", "good-class": "/components/goodClass/index", "cart-list": "/components/cartList/index", "parabala-ball": "/components/parabolaBall/ParabolaBall" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods Details/Index.Json (crmeb/public/statics/mp_view/pages/goods_details/index.json) { "navigationStyle": "custom", "transparentTitle": "auto", "componentPlaceholder": { "page-design": "view", "product-bottom": "view" }, "usingComponents": { "coupon-list-window": "/components/couponListWindow/index", "product-window": "/components/productWindow/index", "share-red-packets": "/components/shareRedPackets/index", "kefu-icon": "/components/kefuIcon/index", "menu-icon": "/components/menuIcon", "cus-preview-img": "/components/cusPreviewImg/index", "swiper-previe": "/components/cusPreviewImg/swiperPrevie", "authorize": "/components/Authorize", "home-list": "/components/homeList/index", "specs": "/pages/goods_details/components/specs/index", "service-modal": "/pages/goods_details/components/serviceModal/index", "page-design": "/subpackage/diyComponents/pageDesign", "product-bottom": "/subpackage/diyComponents/productBottom" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods Details/Components/ServiceModal/Index.Json (crmeb/public/statics/mp_view/pages/goods_details/components/serviceModal/index.json) { "component": true, "usingComponents": { "base-drawer": "/components/tuiDrawer/tui-drawer" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Goods Details/Components/Specs/Index.Json (crmeb/public/statics/mp_view/pages/goods_details/components/specs/index.json) { "component": true, "usingComponents": { "base-drawer": "/components/tuiDrawer/tui-drawer" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Guide/Index.Json (crmeb/public/statics/mp_view/pages/guide/index.json) { "usingComponents": { "guide": "/components/guide/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Index/Index.Json (crmeb/public/statics/mp_view/pages/index/index.json) { "navigationBarTitleText": "", "navigationStyle": "custom", "navigationBarTextStyle": "black", "componentPlaceholder": { "page-design": "view" }, "usingComponents": { "page-design": "/subpackage/diyComponents/pageDesign", "loading": "/components/Loading/index", "coupon-window": "/components/couponWindow/index", "waterfalls-flow": "/components/WaterfallsFlow/WaterfallsFlow", "empty-page": "/components/emptyPage" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Order Addcart/Order Addcart.Json (crmeb/public/statics/mp_view/pages/order_addcart/order_addcart.json) { "navigationBarTitleText": "购物车", "usingComponents": { "page-footer": "/components/pageFooter/index", "recommend": "/components/recommend/index", "product-window": "/components/productWindow/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/Exchange Record.Json (crmeb/public/statics/mp_view/pages/points_mall/exchange_record.json) { "navigationBarTitleText": "兑换记录", "usingComponents": { "count-down": "/components/countDown/index", "loading": "/components/Loading/index", "empty-page": "/components/emptyPage", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/Index.Json (crmeb/public/statics/mp_view/pages/points_mall/index.json) { "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#333333", "navigationBarTitleText": "积分商城", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/Integral Goods Details.Json (crmeb/public/statics/mp_view/pages/points_mall/integral_goods_details.json) { "navigationStyle": "custom", "usingComponents": { "jyf-parser": "/components/jyf-parser/jyf-parser", "product-con-swiper": "/components/productConSwiper/index", "product-window": "/pages/points_mall/component/productWindow", "user-evaluation": "/components/userEvaluation/index", "kefu-icon": "/components/kefuIcon/index", "count-down": "/components/countDown/index", "cus-preview-img": "/components/cusPreviewImg/index", "home-list": "/components/homeList/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/Integral Goods List.Json (crmeb/public/statics/mp_view/pages/points_mall/integral_goods_list.json) { "navigationBarTitleText": "商品列表", "usingComponents": { "recommend": "/components/recommend/index", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/Integral Order.Json (crmeb/public/statics/mp_view/pages/points_mall/integral_order.json) { "navigationBarTitleText": "积分订单", "usingComponents": { "coupon-list-window": "/components/couponListWindow/index", "address-window": "/components/addressWindow/index", "order-goods": "/components/orderGoods/index", "home": "/components/home/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/Integral Order Details.Json (crmeb/public/statics/mp_view/pages/points_mall/integral_order_details.json) { "navigationBarTitleText": "兑换订单详情", "usingComponents": { "home": "/components/home/index", "order-goods": "/components/orderGoods/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/Integral Order Status.Json (crmeb/public/statics/mp_view/pages/points_mall/integral_order_status.json) { "navigationBarTitleText": "兑换成功", "usingComponents": { "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/Logistics Details.Json (crmeb/public/statics/mp_view/pages/points_mall/logistics_details.json) { "navigationBarTitleText": "兑换物流详情", "usingComponents": { "recommend": "/components/recommend/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Points Mall/User Address.Json (crmeb/public/statics/mp_view/pages/points_mall/user_address.json) { "navigationBarTitleText": "选择地址", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/User/Index.Json (crmeb/public/statics/mp_view/pages/user/index.json) { "navigationBarTitleText": "个人中心", "enablePullDownRefresh": true, "navigationStyle": "custom", "navigationBarTextStyle": "black", "componentPlaceholder": { "page-design": "view" }, "usingComponents": { "page-footer": "/components/pageFooter/index", "edit-user-modal": "/components/eidtUserModal/index", "page-design": "/subpackage/diyComponents/pageDesign", "coupon-window": "/components/couponWindow/index", "waterfalls-flow": "/components/WaterfallsFlow/WaterfallsFlow", "empty-page": "/components/emptyPage", "loading": "/components/Loading/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Binding Phone/Index.Json (crmeb/public/statics/mp_view/pages/users/binding_phone/index.json) { "navigationBarTitleText": "", "navigationStyle": "custom", "usingComponents": { "verify": "/pages/users/components/verify/index", "edit-user-modal": "/components/eidtUserModal/index", "privacy-agreement-popup": "/components/privacyAgreementPopup/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Commission Rank/Index.Json (crmeb/public/statics/mp_view/pages/users/commission_rank/index.json) { "navigationBarTitleText": "佣金排行", "navigationBarBackgroundColor": "#FFFFFF", "navigationBarTextStyle": "black", "usingComponents": { "authorize": "/components/Authorize", "empty-page": "/components/emptyPage" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Components/Login Mobile/Index.Json (crmeb/public/statics/mp_view/pages/users/components/login_mobile/index.json) { "component": true, "usingComponents": { "verify": "/pages/users/components/verify/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Components/Verify/Index.Json (crmeb/public/statics/mp_view/pages/users/components/verify/index.json) { "component": true, "usingComponents": { "verify-slide": "/pages/users/components/verify/verifySlider/index", "verify-point": "/pages/users/components/verify/verifyPoint/verifyPoint", "verify-slider-pc": "/pages/users/components/verify/verifySlider/verifySliderPc" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Login/Index.Json (crmeb/public/statics/mp_view/pages/users/login/index.json) { "navigationBarTitleText": "登录", "usingComponents": { "verify": "/pages/users/components/verify/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Message Center/Index.Json (crmeb/public/statics/mp_view/pages/users/message_center/index.json) { "navigationBarTitleText": "消息中心", "enablePullDownRefresh": true, "usingComponents": { "home": "/components/home/index", "tui-drawer": "/components/tuiDrawer/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Message Center/MessageDetail.Json (crmeb/public/statics/mp_view/pages/users/message_center/messageDetail.json) { "navigationBarTitleText": "消息详情", "usingComponents": { "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Payment On Behalf/Index.Json (crmeb/public/statics/mp_view/pages/users/payment_on_behalf/index.json) { "navigationBarTitleText": "好友代付", "usingComponents": { "order-goods": "/components/orderGoods/index", "payment": "/components/payment/index", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Payment On Behalf/Pay Status.Json (crmeb/public/statics/mp_view/pages/users/payment_on_behalf/pay_status.json) { "navigationBarTitleText": "代付成功", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Privacy/Index.Json (crmeb/public/statics/mp_view/pages/users/privacy/index.json) { "navigationBarTitleText": "隐私协议", "usingComponents": { "jyf-parser": "/components/jyf-parser/jyf-parser" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Promoter List/Index.Json (crmeb/public/statics/mp_view/pages/users/promoter-list/index.json) { "navigationBarTitleText": "推广人列表", "navigationBarBackgroundColor": "#FFFFFF", "navigationBarTextStyle": "black", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Promoter Order/Index.Json (crmeb/public/statics/mp_view/pages/users/promoter-order/index.json) { "navigationBarTitleText": "推广人订单", "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF", "usingComponents": { "authorize": "/components/Authorize", "empty-page": "/components/emptyPage", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Promoter Rank/Index.Json (crmeb/public/statics/mp_view/pages/users/promoter_rank/index.json) { "navigationBarTitleText": "推广人排行", "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/RetrievePassword/Index.Json (crmeb/public/statics/mp_view/pages/users/retrievePassword/index.json) { "navigationBarTitleText": "忘记密码", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Scan Login/Index.Json (crmeb/public/statics/mp_view/pages/users/scan_login/index.json) { "navigationBarTitleText": "授权登录", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Staff List/Index.Json (crmeb/public/statics/mp_view/pages/users/staff_list/index.json) { "navigationBarTitleText": "员工列表", "navigationBarBackgroundColor": "#e93323", "navigationBarTextStyle": "white", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index", "zb-code": "/components/zb-code/zb-code" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Address/Index.Json (crmeb/public/statics/mp_view/pages/users/user_address/index.json) { "navigationBarTitleText": "添加地址", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Address List/Index.Json (crmeb/public/statics/mp_view/pages/users/user_address_list/index.json) { "navigationBarTitleText": "地址管理", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Bill/Index.Json (crmeb/public/statics/mp_view/pages/users/user_bill/index.json) { "navigationBarTitleText": "账单明细", "usingComponents": { "authorize": "/components/Authorize", "empty-page": "/components/emptyPage", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Cancellation/Index.Json (crmeb/public/statics/mp_view/pages/users/user_cancellation/index.json) { "navigationBarTitleText": "注销协议", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Cash/Index.Json (crmeb/public/statics/mp_view/pages/users/user_cash/index.json) { "navigationBarTitleText": "提现", "navigationBarBackgroundColor": "#FFFFFF", "navigationBarTextStyle": "black", "usingComponents": { "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Coupon/Index.Json (crmeb/public/statics/mp_view/pages/users/user_coupon/index.json) { "navigationBarTitleText": "我的优惠券", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Distribution Level/Index.Json (crmeb/public/statics/mp_view/pages/users/user_distribution_level/index.json) { "navigationBarTitleText": "分销等级", "navigationBarBackgroundColor": "#232323", "navigationBarTextStyle": "white", "usingComponents": { "recommend": "/components/recommend/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Get Coupon/Index.Json (crmeb/public/statics/mp_view/pages/users/user_get_coupon/index.json) { "navigationBarTitleText": "领取优惠券", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Goods Collection/Index.Json (crmeb/public/statics/mp_view/pages/users/user_goods_collection/index.json) { "navigationBarTitleText": "收藏商品", "usingComponents": { "recommend": "/components/recommend/index", "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Info/Index.Json (crmeb/public/statics/mp_view/pages/users/user_info/index.json) { "navigationBarTitleText": "设置", "usingComponents": { "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Integral/Index.Json (crmeb/public/statics/mp_view/pages/users/user_integral/index.json) { "navigationBarTitleText": "积分详情", "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF", "usingComponents": { "authorize": "/components/Authorize", "empty-page": "/components/emptyPage" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Invoice Form/Index.Json (crmeb/public/statics/mp_view/pages/users/user_invoice_form/index.json) { "navigationBarTitleText": "添加新发票", "usingComponents": { "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Invoice List/Index.Json (crmeb/public/statics/mp_view/pages/users/user_invoice_list/index.json) { "navigationBarTitleText": "发票管理", "usingComponents": { "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Invoice Order/Index.Json (crmeb/public/statics/mp_view/pages/users/user_invoice_order/index.json) { "navigationBarTitleText": "发票详情", "usingComponents": { "payment": "/components/payment/index", "home": "/components/home/index", "order-goods": "/components/orderGoods/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Money/Index.Json (crmeb/public/statics/mp_view/pages/users/user_money/index.json) { "navigationBarTitleText": "我的账户", "usingComponents": { "recommend": "/components/recommend/index", "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Payment/Index.Json (crmeb/public/statics/mp_view/pages/users/user_payment/index.json) { "navigationBarTitleText": "余额充值", "usingComponents": { "payment": "/components/payment/index", "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Phone/Index.Json (crmeb/public/statics/mp_view/pages/users/user_phone/index.json) { "navigationBarTitleText": "绑定手机", "usingComponents": { "authorize": "/components/Authorize", "verify": "/pages/users/components/verify/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Pwd Edit/Index.Json (crmeb/public/statics/mp_view/pages/users/user_pwd_edit/index.json) { "navigationBarTitleText": "修改密码", "usingComponents": { "authorize": "/components/Authorize", "verify": "/pages/users/components/verify/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Return List/Index.Json (crmeb/public/statics/mp_view/pages/users/user_return_list/index.json) { "navigationBarTitleText": "退货列表", "usingComponents": { "home": "/components/home/index", "empty-page": "/components/emptyPage", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Sgin/Index.Json (crmeb/public/statics/mp_view/pages/users/user_sgin/index.json) { "navigationBarTitleText": "签到", "usingComponents": { "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Sgin List/Index.Json (crmeb/public/statics/mp_view/pages/users/user_sgin_list/index.json) { "navigationBarTitleText": "签到记录", "usingComponents": { "empty-page": "/components/emptyPage", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Spread Code/Index.Json (crmeb/public/statics/mp_view/pages/users/user_spread_code/index.json) { "navigationBarTitleText": "分销海报", "usingComponents": { "zb-code": "/components/zb-code/zb-code", "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Spread Money/Index.Json (crmeb/public/statics/mp_view/pages/users/user_spread_money/index.json) { "navigationBarTitleText": "佣金记录", "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF", "usingComponents": { "authorize": "/components/Authorize", "empty-page": "/components/emptyPage", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Spread Money/Receiving.Json (crmeb/public/statics/mp_view/pages/users/user_spread_money/receiving.json) { "navigationBarTitleText": "收款", "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Spread User/Index.Json (crmeb/public/statics/mp_view/pages/users/user_spread_user/index.json) { "navigationBarTitleText": "我的推广", "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF", "usingComponents": { "authorize": "/components/Authorize", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Vip/Index.Json (crmeb/public/statics/mp_view/pages/users/user_vip/index.json) { "navigationBarTitleText": "我的等级", "navigationBarBackgroundColor": "#232323", "navigationBarTextStyle": "white", "usingComponents": { "recommend": "/components/recommend/index", "authorize": "/components/Authorize" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/User Vip Areer/Index.Json (crmeb/public/statics/mp_view/pages/users/user_vip_areer/index.json) { "navigationBarTitleText": "经验记录", "usingComponents": {} } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Visit List/Index.Json (crmeb/public/statics/mp_view/pages/users/visit_list/index.json) { "navigationBarTitleText": "浏览记录", "usingComponents": { "recommend": "/components/recommend/index", "home": "/components/home/index" } } --- ### Crmeb/Public/Statics/Mp View/Pages/Users/Wechat Login/Index.Json (crmeb/public/statics/mp_view/pages/users/wechat_login/index.json) { "navigationBarTitleText": "", "navigationStyle": "custom", "usingComponents": { "mobile-login": "/pages/users/components/login_mobile/index", "routine-phone": "/pages/users/components/login_mobile/routine_phone", "edit-user-modal": "/components/eidtUserModal/index", "privacy-agreement-popup": "/components/privacyAgreementPopup/index" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/ArticleList.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/articleList.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Bargain.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/bargain.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/BlankPage.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/blankPage.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Combination.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/combination.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Coupon.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/coupon.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/CustomComponent.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/customComponent.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Follow.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/follow.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/GoodList.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/goodList.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "product-window": "/components/productWindow/index", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Guide.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/guide.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/HeaderSerch.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/headerSerch.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/HomeComb.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/homeComb.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/HomePaidVip.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/homePaidVip.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/HomeProductService.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/homeProductService.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/HomeReviews.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/homeReviews.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/HomeUserInfor.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/homeUserInfor.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Hotspot.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/hotspot.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/LiveBroadcast.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/liveBroadcast.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Menus.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/menus.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/News.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/news.json) { "component": true, "usingComponents": { "uni-notice-bar": "/components/uniNoticeBar/uni-notice-bar", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/NewVip.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/newVip.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/PageDesign.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/pageDesign.json) { "component": true, "usingComponents": { "page-footer": "/components/pageFooter/index", "home-comb": "/subpackage/diyComponents/homeComb", "header-serch": "/subpackage/diyComponents/headerSerch", "tab-nav": "/subpackage/diyComponents/tabNav", "user-infor": "/subpackage/diyComponents/userInfor", "home-user-infor": "/subpackage/diyComponents/homeUserInfor", "new-vip": "/subpackage/diyComponents/newVip", "article-list": "/subpackage/diyComponents/articleList", "bargain": "/subpackage/diyComponents/bargain", "blank-page": "/subpackage/diyComponents/blankPage", "combination": "/subpackage/diyComponents/combination", "coupon": "/subpackage/diyComponents/coupon", "customer-service": "/subpackage/diyComponents/customerService", "good-list": "/subpackage/diyComponents/goodList", "guide": "/subpackage/diyComponents/guide", "live-broadcast": "/subpackage/diyComponents/liveBroadcast", "menus": "/subpackage/diyComponents/menus", "news": "/subpackage/diyComponents/news", "picture-cube": "/subpackage/diyComponents/pictureCube", "promotion-list": "/subpackage/diyComponents/promotionList", "seckill": "/subpackage/diyComponents/seckill", "swiper-bg": "/subpackage/diyComponents/swiperBg", "swipers": "/subpackage/diyComponents/swipers", "titles": "/subpackage/diyComponents/titles", "presale": "/subpackage/diyComponents/presale", "points-mall": "/subpackage/diyComponents/pointsMall", "rich-text": "/subpackage/diyComponents/richText", "videos": "/subpackage/diyComponents/videos", "sign-in": "/subpackage/diyComponents/signIn", "hotspot": "/subpackage/diyComponents/hotspot", "follow": "/subpackage/diyComponents/follow", "product-info": "/subpackage/diyComponents/productInfo", "home-paid-vip": "/subpackage/diyComponents/homePaidVip", "home-product-service": "/subpackage/diyComponents/homeProductService", "home-reviews": "/subpackage/diyComponents/homeReviews", "product-desc": "/subpackage/diyComponents/productDesc", "custom-component": "/subpackage/diyComponents/customComponent" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/PictureCube.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/pictureCube.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/PointsMall.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/pointsMall.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Presale.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/presale.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/ProductBottom.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/productBottom.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/ProductDesc.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/productDesc.json) { "component": true, "usingComponents": { "parser": "/components/jyf-parser/jyf-parser", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/ProductInfo.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/productInfo.json) { "component": true, "usingComponents": { "base-tag": "/components/BaseTag", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/PromotionList.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/promotionList.json) { "component": true, "usingComponents": { "good-list": "/subpackage/diyComponents/goodList", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/RichText.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/richText.json) { "component": true, "usingComponents": { "jyf-parser": "/components/jyf-parser/jyf-parser", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Seckill.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/seckill.json) { "component": true, "usingComponents": { "easy-loadimage": "/components/easy-loadimage/easy-loadimage", "count-down": "/components/countDown/index", "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/SignIn.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/signIn.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/SwiperBg.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/swiperBg.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Swipers.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/swipers.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/TabNav.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/tabNav.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Titles.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/titles.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/UserInfor.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/userInfor.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Public/Statics/Mp View/Subpackage/DiyComponents/Videos.Json (crmeb/public/statics/mp_view/subpackage/diyComponents/videos.json) { "component": true, "usingComponents": { "common-wrapper": "/subpackage/diyComponents/commonWrapper" } } --- ### Crmeb/Route/README (crmeb/route/README.md) crmeb/route目录在CRMEB项目中的主要作用是用于定义项目的路由规则。 1. 定义一个 Route::miss 方法处理路由未匹配的情况 2. 根据请求路径获取应用名称(如 admin、app 等) 3. 根据应用名称返回不同的视图文件 - admin前台后台分别返回不同入口 - app/kefu定义了对应的视图 - home覆盖移动端和PC入口 - 其它情况判断是否移动端返回不同视图 4. 完整定义了项目所有可能的路由入口 5. 根据请求信息智能匹配视图资源文件 主要作用: - 统一处理所有路由匹配 - 隐藏实际控制器入口 - 根据应用名分发页面 - 实现PC端和移动端自动切换 这种设计可以: - 完整覆盖所有路由情况 - 隐藏实际路由层次结构 - 实现智能的页面分发 是动态路由设计的一个很好范例。 --- ### Crmeb/Runtime/Readme (crmeb/runtime/readme.md) # runtime目录说明 此目录用于存储CRMEB系统运行期间生成的各种临时文件和运行时数据。包含以下子目录: - `cache/` - 系统缓存文件 - `log/` - 系统日志文件 - `session/` - 用户会话数据 - `temp/` - 临时文件 请勿手动删除此目录下的文件,除非明确知道其用途。 --- ### Crmeb/Upgrade/Versions/README (crmeb/upgrade/versions/README.md) crmeb/upgrade/versions目录在CRMEB项目中的主要作用是用于存放系统升级相关的版本文件和升级脚本。 CRMEB系统在迭代更新过程中,需要一套完整的升级机制来保证数据迁移和版本兼容。这个目录就承担了集中管理各版本升级资源的职责。 具体来说: - 存放各版本的升级说明文档,记录版本变更内容 - 放置数据库迁移脚本,处理表结构变更和数据迁移 - 存储升级所需的静态资源文件 - 记录版本依赖关系和升级顺序 - 保存版本检测和升级状态标识文件 使用这个目录有以下优点: - 实现版本升级的模块化管理,便于追溯和回滚 - 与核心业务代码隔离,降低升级风险 - 支持多版本增量升级,灵活适配不同起始版本 - 便于自动化部署工具识别和执行升级流程 总体来说,它承担了系统版本迭代和数据库迁移的协调工作。 通过规范使用这个目录,可以确保升级过程的安全可控和可追溯。 --- ### Help/Dev Docs/错误码说明文档 (help/dev-docs/错误码说明文档.md) # CRMEB 错误码说明文档 ## 1. 引言 ### 1.1 文档目的 - 规范 CRMEB 系统中的错误码使用 - 提供错误码的分类和定义标准 - 为开发人员提供错误处理的参考指南 - 确保系统错误信息的一致性和可维护性 ### 1.2 适用范围 - CRMEB 系统所有模块的开发和维护 - API 接口错误处理 - 后台管理系统错误处理 - 移动端应用错误处理 ### 1.3 术语定义 - **错误码**:系统中用于标识特定错误类型的数字编码 - **异常类**:用于处理和抛出错误的类 - **多语言**:系统支持的不同语言错误信息 ## 2. 错误码设计规范 ### 2.1 错误码格式 - **格式**:纯数字,长度为 3-6 位 - **示例**:400, 401, 400001, 400086 ### 2.2 错误码分类 | 范围 | 分类 | 说明 | 示例 | |------|------|------|------| | 100-199 | 信息提示 | 一般性信息提示 | 100 | | 200-299 | 成功响应 | 请求处理成功 | 200 | | 300-399 | 重定向 | 需要重定向 | 301, 302 | | 400-499 | 客户端错误 | 客户端请求错误 | 400, 401, 403, 404 | | 500-599 | 服务器错误 | 服务器内部错误 | 500, 501, 503 | | 400000-499999 | 业务错误 | 具体业务逻辑错误 | 400086, 400087 | | 600000-699999 | 系统错误 | 系统级错误 | 600001 | | 700000-799999 | 第三方错误 | 第三方服务错误 | 700001 | ### 2.3 错误码命名规则 - 错误码应具有语义化,便于理解和记忆 - 同一模块的错误码应集中在一个范围内 - 错误码应保持唯一性,避免重复 ## 3. 错误处理机制 ### 3.1 异常类体系 CRMEB 系统使用以下异常类处理错误: | 异常类 | 命名空间 | 用途 | |--------|----------|------| | ApiException | crmeb\exceptions | API 接口错误 | | AuthException | crmeb\exceptions | 认证授权错误 | | AdminException | crmeb\exceptions | 后台管理错误 | | PayException | crmeb\exceptions | 支付相关错误 | | CrudException | crmeb\exceptions | CRUD 操作错误 | | ApiStatusException | crmeb\exceptions | 带状态码的 API 错误 | | OAuthException | crmeb\services\oauth | OAuth 认证错误 | ### 3.2 错误抛出方式 #### 3.2.1 直接抛出异常 ```php // 使用错误信息 throw new ApiException('参数错误'); // 使用错误码 throw new ApiException(400086); // 使用错误码和替换参数 throw new ApiException(400086, ['name' => '用户名']); // 使用数组形式 throw new ApiException([400086, '参数错误']); ``` #### 3.2.2 在验证器中使用 ```php protected $message = [ 'name.require' => '400086', 'sort.require' => '400087', 'sort.number' => '400088' ]; ``` ### 3.3 错误信息获取 系统使用 `getLang()` 函数获取错误信息,支持多语言: ```php // 获取错误信息 $message = getLang($code, $replace); ``` ## 4. 常见错误码列表 ### 4.1 基础错误码 | 错误码 | 错误信息 | 说明 | 分类 | |--------|----------|------|------| | 200 | 操作成功 | 请求处理成功 | 成功响应 | | 400 | 参数错误 | 请求参数格式错误 | 客户端错误 | | 401 | 未授权 | 未登录或登录已过期 | 客户端错误 | | 403 | 禁止访问 | 没有权限执行此操作 | 客户端错误 | | 404 | 资源不存在 | 请求的资源不存在 | 客户端错误 | | 500 | 服务器内部错误 | 服务器处理请求时发生错误 | 服务器错误 | | 501 | 功能未实现 | 请求的功能尚未实现 | 服务器错误 | | 503 | 服务不可用 | 服务器暂时无法处理请求 | 服务器错误 | ### 4.2 业务错误码 #### 4.2.1 用户相关 | 错误码 | 错误信息 | 说明 | |--------|----------|------| | 400001 | 用户名已存在 | 注册时用户名已被使用 | | 400002 | 手机号已被注册 | 注册时手机号已被使用 | | 400003 | 邮箱已被注册 | 注册时邮箱已被使用 | | 400004 | 用户名或密码错误 | 登录时用户名或密码不正确 | | 400005 | 用户不存在 | 请求的用户不存在 | | 400006 | 账号已被禁用 | 用户账号被管理员禁用 | | 400007 | 验证码错误 | 验证码不正确 | | 400008 | 验证码已过期 | 验证码已超过有效期 | #### 4.2.2 商品相关 | 错误码 | 错误信息 | 说明 | |--------|----------|------| | 400101 | 商品不存在 | 请求的商品不存在 | | 400102 | 商品已下架 | 商品已被下架 | | 400103 | 商品库存不足 | 商品库存不足 | | 400104 | 商品价格异常 | 商品价格不符合要求 | | 400105 | 商品分类不存在 | 请求的商品分类不存在 | #### 4.2.3 订单相关 | 错误码 | 错误信息 | 说明 | |--------|----------|------| | 400201 | 订单不存在 | 请求的订单不存在 | | 400202 | 订单状态错误 | 订单状态不符合操作要求 | | 400203 | 订单金额错误 | 订单金额计算错误 | | 400204 | 支付失败 | 支付过程中发生错误 | | 400205 | 退款失败 | 退款过程中发生错误 | | 400206 | 地址信息错误 | 收货地址信息不正确 | #### 4.2.4 权限相关 | 错误码 | 错误信息 | 说明 | |--------|----------|------| | 400301 | 无权限操作 | 用户没有权限执行此操作 | | 400302 | 角色不存在 | 请求的角色不存在 | | 400303 | 菜单不存在 | 请求的菜单不存在 | | 400304 | 权限不足 | 用户权限不足 | #### 4.2.5 系统相关 | 错误码 | 错误信息 | 说明 | |--------|----------|------| | 400401 | 配置错误 | 系统配置错误 | | 400402 | 网络错误 | 网络连接失败 | | 400403 | 文件上传失败 | 文件上传过程中发生错误 | | 400404 | 数据库错误 | 数据库操作失败 | | 400405 | 缓存错误 | 缓存操作失败 | ### 4.3 验证器错误码 | 错误码 | 错误信息 | 说明 | |--------|----------|------| | 400086 | 名称不能为空 | 验证名称字段必填 | | 400087 | 排序不能为空 | 验证排序字段必填 | | 400088 | 排序必须为数字 | 验证排序字段必须为数字 | ## 5. 错误码管理 ### 5.1 错误码定义 错误码应在语言文件中统一定义,便于管理和多语言支持: ```php // 语言文件示例 return [ 400001 => '用户名已存在', 400002 => '手机号已被注册', // 更多错误码... ]; ``` ### 5.2 错误码分配 - 错误码应按模块分配不同的范围 - 新增错误码时应避免与现有错误码冲突 - 错误码分配应记录在文档中,便于查阅 ### 5.3 错误码维护 - 定期检查错误码使用情况 - 清理不再使用的错误码 - 统一错误码的命名和描述规范 ## 6. 错误处理最佳实践 ### 6.1 前端错误处理 1. **统一错误提示**:使用统一的错误提示组件 2. **错误码映射**:根据错误码显示相应的错误信息 3. **用户友好**:错误信息应简洁明了,便于用户理解 4. **错误日志**:记录前端错误日志,便于排查问题 ### 6.2 后端错误处理 1. **分层处理**:不同层次使用不同的异常类 2. **详细日志**:记录详细的错误日志,包括错误码、错误信息、请求参数等 3. **错误码规范**:严格按照错误码规范使用错误码 4. **异常捕获**:合理捕获异常,避免系统崩溃 5. **错误信息国际化**:支持多语言错误信息 ### 6.3 错误码使用建议 1. **语义化**:错误码应具有语义,便于理解 2. **一致性**:相同类型的错误应使用相同范围的错误码 3. **可扩展性**:预留足够的错误码空间,便于后续扩展 4. **文档化**:及时更新错误码文档,确保文档与代码一致 ## 7. 错误码扩展 ### 7.1 自定义错误码 开发人员可以根据业务需求自定义错误码,遵循以下步骤: 1. 确定错误码的范围和分类 2. 在语言文件中定义错误信息 3. 在代码中使用错误码 4. 更新错误码文档 ### 7.2 错误码版本管理 当系统版本升级时,错误码的管理应注意: 1. 保持向后兼容:避免修改现有错误码的含义 2. 新增错误码:在预留范围内新增错误码 3. 废弃错误码:标记不再使用的错误码 ## 8. 常见问题 ### 8.1 错误码重复 **问题**:不同模块使用了相同的错误码 **解决方案**: - 按模块分配错误码范围 - 建立错误码管理机制 - 定期检查错误码使用情况 ### 8.2 错误信息不明确 **问题**:错误信息不够明确,难以理解 **解决方案**: - 错误信息应简洁明了 - 错误信息应包含具体的错误原因 - 错误信息应便于用户理解 ### 8.3 错误处理不一致 **问题**:不同模块的错误处理方式不一致 **解决方案**: - 统一错误处理机制 - 使用统一的异常类 - 遵循错误处理最佳实践 ## 9. 总结 错误码是系统中重要的组成部分,合理的错误码设计和使用可以提高系统的可维护性和用户体验。本文档提供了 CRMEB 系统错误码的设计规范、使用方法和最佳实践,希望能够帮助开发人员更好地理解和使用错误码。 在实际开发中,开发人员应严格遵循本文档的规范,确保错误码的一致性和可维护性。同时,应根据业务需求不断完善和扩展错误码体系,以适应系统的发展和变化。 > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Admin/后台管理前端架构说明 (help/dev-docs/admin/后台管理前端架构说明.md) # CRMEB 后台管理前端架构说明 ## 📋 技术栈概览 | 技术 | 版本 | 说明 | |------|------|------| | Vue.js | 2.x | 前端核心框架 | | Element UI | 2.x | UI组件库 | | Vuex | 3.x | 状态管理 | | Axios | 0.x | HTTP客户端 | | VXE-Table | 高级表格组件 | | | WangEditor | 富文本编辑器 | | | Sass | CSS预处理器 | | | Prettier | 代码格式化工具 | | | Vue-Viewer | 图片查看器 | | ## ??️ 整体架构 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 📂 目录结构 ### 标准后台管理前端目录结构 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 🔧 核心模块详解 ### 1. 路由模块 (Router) #### 路由配置结构 ```javascript // src/router/index.js import Vue from 'vue' import VueRouter from 'vue-router' import { constantRoutes } from './modules' Vue.use(VueRouter) // 创建路由实例 export const createRouter = () => new VueRouter({ routes: constantRoutes, mode: 'history', scrollBehavior: () => ({ y: 0 }) }) // 静态路由 export const constantRoutes = [ { path: '/login', component: () => import('@/views/login/index'), meta: { title: '登录' } }, { path: '/404', component: () => import('@/views/error/404') }, { path: '/', component: Layout, redirect: '/dashboard', children: [ { path: 'dashboard', name: 'Dashboard', component: () => import('@/views/dashboard/index'), meta: { title: '控制台', icon: 'dashboard' } } ] } ] ``` #### 动态路由(权限控制) ```javascript // src/router/modules/permission.js export const asyncRoutes = [ { path: '/user', component: Layout, meta: { title: '用户管理', icon: 'user', roles: ['admin', 'manager'] }, children: [ { path: 'list', name: 'UserList', component: () => import('@/views/user/list'), meta: { title: '用户列表', roles: ['admin'] } } ] } ] ``` ### 2. 状态管理 (Vuex) #### Store结构 ```javascript // src/store/index.js import Vue from 'vue' import Vuex from 'vuex' import user from './modules/user' import app from './modules/app' import permission from './modules/permission' Vue.use(Vuex) export default new Vuex.Store({ modules: { user, app, permission }, getters: { token: state => state.user.token, roles: state => state.user.roles, sidebarOpened: state => app.sidebarOpened, permissionRoutes: state => permission.routes } }) ``` #### 用户状态模块 ```javascript // src/store/modules/user.js const state = { token: localStorage.getItem('token') || '', userInfo: {}, roles: [] } const mutations = { SET_TOKEN(state, token) { state.token = token localStorage.setItem('token', token) }, SET_USER_INFO(state, userInfo) { state.userInfo = userInfo }, SET_ROLES(state, roles) { state.roles = roles } } const actions = { // 登录 async login({ commit }, userInfo) { const res = await login(userInfo) commit('SET_TOKEN', res.data.token) return res }, // 获取用户信息 async getInfo({ commit }) { const res = await getUserInfo() commit('SET_USER_INFO', res.data) commit('SET_ROLES', res.data.roles) return res }, // 退出登录 async logout({ commit }) { await logout() commit('SET_TOKEN', '') commit('SET_USER_INFO', {}) } } export default { namespaced: true, state, mutations, actions } ``` ### 3. API服务层 #### Axios封装 ```javascript // src/utils/request.js import axios from 'axios' import { Message, MessageBox } from 'element-ui' import store from '@/store' import router from '@/router' // 创建axios实例 const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, timeout: 30000 }) // 请求拦截器 service.interceptors.request.use( config => { // 添加token if (store.getters.token) { config.headers['Authorization'] = `Bearer ${store.getters.token}` } return config }, error => { return Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( response => { const res = response.data if (res.code === 200) { return res } Message.error(res.msg || '请求失败') return Promise.reject(new Error(res.msg || '请求失败')) }, error => { if (error.response) { const { status } = error.response if (status === 401) { MessageBox.confirm('登录状态已过期,请重新登录', '确认登录', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { store.dispatch('user/logout') router.push('/login') }) } } return Promise.reject(error) } ) export default service ``` #### API接口定义 ```javascript // src/api/user.js import request from '@/utils/request' // 获取用户列表 export function getUserList(params) { return request({ url: '/adminapi/v1/user/list', method: 'get', params }) } // 获取用户详情 export function getUserDetail(id) { return request({ url: `/adminapi/v1/user/${id}`, method: 'get' }) } // 编辑用户 export function editUser(data) { return request({ url: '/adminapi/v1/user/edit', method: 'post', data }) } // 删除用户 export function deleteUser(id) { return request({ url: `/adminapi/v1/user/${id}`, method: 'delete' }) } ``` ### 4. 布局组件 (Layout) #### 主布局组件 ```vue ``` #### 侧边栏组件 ```vue ``` ### 5. 列表页面组件 #### 通用列表页面模板 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 6. 表单页面组件 #### 通用表单页面模板 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 🎨 样式规范 ### SCSS 变量定义 ```scss // src/assets/styles/variables.scss // 主题色 $primary-color: #409EFF; $success-color: #67C23A; $warning-color: #E6A23C; $danger-color: #F56C6C; $info-color: #909399; // 背景色 $bg-color: #f0f2f5; $white: #ffffff; // 文字颜色 $text-primary: #303133; $text-regular: #606266; $text-secondary: #909399; $text-placeholder: #c0c4cc; // 边框颜色 $border-color: #dcdfe6; $border-color-light: #e4e7ed; $border-color-lighter: #ebeef5; // 字体 $font-size-base: 14px; $font-size-small: 12px; $font-size-large: 16px; ``` ### 通用样式 ```scss // src/assets/styles/common.scss // 通用页面容器 .app-container { padding: 20px; } // 卡片样式 .card-header { display: flex; justify-content: space-between; align-items: center; } // 表格操作按钮 .table-action-btn { margin: 0 5px; } // 表单样式 .form-container { max-width: 600px; margin: 0 auto; } ``` ## 🔐 权限控制 ### 权限指令 ```javascript // src/directive/permission.js import Vue from 'vue' // v-permission 指令 Vue.directive('permission', { inserted: function(el, binding) { const { value } = binding const permissions = Vue.prototype.$store.getters.permissions if (value && value instanceof Array) { const hasPermission = value.some(permission => { return permissions.includes(permission) }) if (!hasPermission) { el.parentNode && el.parentNode.removeChild(el) } } else { throw new Error('v-permission value must be array') } } }) ``` ### 使用示例 ```vue ``` ## 📊 常用组件使用 ### 表格组件 (VXE-Table) ```vue ``` ### 富文本编辑器 (WangEditor) ```vue ``` ## 🧪 测试配置 ### Jest 测试配置 ```javascript // jest.config.js module.exports = { testURL: 'http://localhost', moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], transform: { '^.+\\.vue$': 'vue-jest', '^.+\\.js$': 'babel-jest' }, moduleNameMapper: { '^@/(.*)$': '/src/$1' }, testMatch: ['/tests/**/*.spec.js'], collectCoverageFrom: [ 'src/**/*.{js,vue}', '!src/main.js' ] } ``` ### 测试示例 ```javascript // tests/unit/user.spec.js import { shallowMount } from '@vue/test-utils' import UserList from '@/views/user/list.vue' describe('UserList', () => { it('renders user list correctly', () => { const wrapper = shallowMount(UserList, { mocks: { $route: { path: '/user/list' }, $store: { getters: { roles: ['admin'] } } } }) expect(wrapper.find('.el-table').exists()).toBe(true) expect(wrapper.find('.pagination').exists()).toBe(true) }) }) ``` ## 🚀 构建部署 ### 环境配置 ```bash # .env.development VUE_APP_BASE_API = 'http://localhost:8000' VUE_APP_WS_API = 'ws://localhost:8000' # .env.production VUE_APP_BASE_API = 'https://api.crmeb.com' VUE_APP_WS_API = 'wss://api.crmeb.com' ``` ### 构建命令 ```bash # 安装依赖 npm install # 开发环境 npm run dev # 生产环境构建 npm run build:prod # 代码检查 npm run lint # 单元测试 npm run test ``` ### Nginx 配置 ```nginx server { listen 80; server_name admin.crmeb.com; # 前端静态资源 location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } # API代理 location /adminapi/ { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # WebSocket代理 location /ws/ { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } ``` ## 📝 开发规范 ### 代码风格 - 使用 ESLint + Prettier 进行代码格式化 - Vue组件使用单文件组件 (.vue) - 组件名使用 PascalCase 命名 - 样式使用 SCSS 预处理器 ### Git 提交规范 ``` feat: 新增用户管理功能 fix: 修复订单列表分页问题 docs: 更新接口文档 style: 代码格式调整 refactor: 重构用户模块代码 test: 添加单元测试 chore: 更新构建配置 ``` --- **文档版本**: v1.0 **最后更新**: 2024-01-17 **适用版本**: CRMEB 5.6.4+ **维护团队**: 前端开发组 💡 提示:后台管理前端采用 Element UI 组件库,配合 Vuex 进行状态管理,通过 Axios 封装统一处理 HTTP 请求,实现了完整的权限控制和数据交互功能。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/API接口文档 (help/dev-docs/phpapi/API接口文档.md) # CRMEB API 接口文档 ## 📍 API 入口划分 - **后台管理**: `/adminapi/controller/v1/` (需要管理员权限) - **前端用户**: `/api/controller/v1/` (需要用户登录) - **公共接口**: `/api/controller/publics/` (无需登录) ## 🔐 认证机制 ```php // JWT Token 认证 'middleware' => [ AuthTokenMiddleware::class, // 用户token验证 AdminAuthTokenMiddleware::class // 管理员token验证 ] ``` ## 📋 核心接口示例 ### 用户管理接口 ``` GET /adminapi/v1/user/list # 用户列表 POST /adminapi/v1/user/edit # 编辑用户 GET /api/v1/user/info # 获取用户信息 ``` ### 订单管理接口 ``` GET /adminapi/v1/order/list # 订单列表 POST /api/v1/order/create # 创建订单 GET /api/v1/order/detail # 订单详情 ``` ## 🏷️ 统一响应格式 ```json { "status": 200, "msg": "success", "data": {...}, "time": "2024-01-01 10:00:00" } ``` ## ⚠️ 错误码规范 - 200: 成功 - 400: 参数错误 - 401: 未授权 - 403: 权限不足 - 500: 服务器错误 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/业务流程说明 (help/dev-docs/phpapi/业务流程说明.md) # 业务流程说明 ## 📋 核心业务流程 ### 🛒 订单创建流程 1. 用户选择商品 → 加入购物车 → 生成订单 2. 订单验证(库存、价格、优惠券) 3. 创建订单数据 4. 扣减库存 5. 发送订单通知 ### 💳 支付处理流程 1. 用户选择支付方式 2. 调用支付接口 3. 支付结果回调 4. 更新订单状态 5. 记录支付流水 ### 📦 发货流程 1. 订单状态检查(已支付) 2. 生成发货单 3. 调用物流接口 4. 更新发货状态 5. 通知用户物流信息 ### 🔄 售后流程 1. 用户提交售后申请 2. 审核售后请求 3. 处理退款/换货 4. 更新库存和财务 5. 完成售后流程 ## ⏱️ 异步任务流程 - 消息队列处理订单相关任务 - 定时任务处理数据统计 - 后台任务处理批量操作 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/会员管理开发文档 (help/dev-docs/phpapi/会员管理开发文档.md) # 会员管理开发文档 ## 1. 文档概述 ### 1.1 文档目的 本文档旨在详细说明CRMEB系统中会员管理模块的设计架构、核心功能、代码实现及开发规范,为系统开发人员提供完整的开发参考。 ### 1.2 适用范围 本文档适用于CRMEB系统开发人员、维护人员及二次开发人员,用于指导会员管理模块的开发、扩展和维护工作。 ### 1.3 术语定义 | 术语 | 解释 | |------|------| | 会员等级 | 基于用户经验值划分的等级体系,不同等级享有不同权益 | | 经验值 | 用户通过各种行为获得的数值,用于提升会员等级 | | 会员权益 | 不同会员等级享有的专属福利,如折扣、优惠券等 | | 会员卡片 | 展示会员等级、有效期、权益等信息的可视化卡片 | | 积分 | 用户通过各种行为获得的可用于消费的数值 | | 积分商城 | 用于兑换商品或服务的积分兑换平台 | | 会员有效期 | 会员等级的有效期限,过期后可能降级或失效 | ## 2. 核心功能模块 ### 2.1 会员等级管理 - **等级列表**:展示系统配置的会员等级,支持搜索、分页 - **等级添加**:添加新的会员等级,设置等级名称、折扣、经验值要求等 - **等级编辑**:修改会员等级信息,包括名称、折扣、经验值要求等 - **等级删除**:删除会员等级 - **等级状态管理**:启用/禁用会员等级 - **等级排序**:调整会员等级的显示顺序 ### 2.2 用户等级管理 - **用户等级列表**:展示用户当前等级信息,支持搜索、分页 - **等级赠送**:手动为用户赠送会员等级 - **等级清除**:清除用户的会员等级 - **等级有效期管理**:设置和修改会员等级的有效期 - **等级自动检测**:定期检测用户是否达到升级条件,自动升级 ### 2.3 经验值管理 - **经验值配置**:配置各种行为获得的经验值数量 - **经验值记录**:记录用户经验值的变动情况 - **经验值查询**:查询用户经验值的获取和使用记录 - **经验值统计**:统计用户经验值的来源分布 ### 2.4 积分管理 - **积分配置**:配置各种行为获得的积分数量 - **积分增加**:手动为用户增加积分 - **积分扣除**:手动为用户扣除积分 - **积分记录**:记录用户积分的变动情况 - **积分查询**:查询用户积分的获取和使用记录 - **积分统计**:统计用户积分的来源和使用分布 ### 2.5 会员权益管理 - **折扣权益**:配置不同等级的商品折扣比例 - **等级图标**:配置各等级的专属图标和背景图 - **会员卡片**:生成和管理会员卡片 - **权益规则**:配置会员享有的其他权益,如专属客服、优先发货等 ### 2.6 会员等级升级机制 - **经验值累积**:通过签到、下单、邀请等行为累积经验值 - **升级条件检测**:定期检测用户是否达到升级条件 - **自动升级**:达到升级条件后自动更新会员等级 - **升级通知**:发送等级升级通知给用户 ## 3. 代码结构与设计 ### 3.1 架构设计 系统采用分层架构设计,严格遵循MVC设计模式: ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Models │ │ Daos │ │ Services │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └───────────────────────┼───────────────────────┘ │ ┌─────────────────┐ │ Controllers │ └─────────────────┘ │ ┌─────────────────┐ │ Routes │ └─────────────────┘ ``` ### 3.2 核心文件结构 #### 3.2.1 模型层(Model) **会员相关模型**: - `UserLevel.php` - 用户实际会员等级信息模型 - `SystemUserLevel.php` - 系统会员等级配置模型 - `User.php` - 用户基本信息模型,包含经验值、积分等字段 #### 3.2.2 服务层(Services) **会员管理Services**: - `UserLevelServices.php` - 会员等级设置与管理,自动检测用户升级条件 - `UserBillServices.php` - 积分增加与扣除,积分记录管理 - `UserServices.php` - 用户基本信息管理,包括等级、经验值、积分等 #### 3.2.3 控制器层(Controller) **会员控制器**: - `UserLevel.php` - 会员等级管理控制器 - `User.php` - 用户管理控制器,包含等级、经验值、积分等管理功能 #### 3.2.4 路由配置 **会员路由**: - `user.php` - 包含会员管理相关的API路由 ## 4. 数据库设计 ### 4.1 系统会员等级表(system_user_level) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 等级ID | | name | varchar(20) | 等级名称 | | icon | varchar(255) | 等级图标 | | bg | varchar(255) | 等级背景图 | | grade | int(10) | 等级 | | experience_min | int(10) | 最低经验值 | | experience_max | int(10) | 最高经验值 | | discount | decimal(10,2) | 折扣比例 | | status | tinyint(1) | 状态(0-禁用,1-启用) | | is_show | tinyint(1) | 是否显示(0-隐藏,1-显示) | | sort | int(10) | 排序 | | add_time | int(10) | 添加时间 | ### 4.2 用户等级表(user_level) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 记录ID | | uid | int(10) | 用户ID | | level_id | int(10) | 会员等级ID | | is_forever | tinyint(1) | 是否永久(0-否,1-是) | | start_time | int(10) | 开始时间 | | end_time | int(10) | 结束时间 | | status | tinyint(1) | 状态(0-过期,1-有效) | | add_time | int(10) | 添加时间 | ### 4.3 用户表(user) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | uid | int(10) unsigned | 用户ID | | user_level | int(10) | 当前会员等级ID | | experience | int(10) | 经验值 | | integral | int(10) | 积分 | | sign_num | int(10) | 连续签到天数 | | sign_integral | int(10) | 已领取签到积分 | | // 其他用户信息字段 | // 数据类型 | // 描述 | ### 4.4 用户账单表(user_bill) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 账单ID | | uid | int(10) | 用户ID | | category | varchar(20) | 资金类型(integral-积分,experience-经验值) | | type | varchar(20) | 变动类型(sign-签到,order-订单,invite-邀请) | | pm | tinyint(1) | 收支方向(1-收入,0-支出) | | number | varchar(50) | 流水号 | | money | decimal(10,2) | 变动金额 | | balance | decimal(10,2) | 变动后余额/积分/经验值 | | mark | varchar(255) | 备注 | | add_time | int(10) | 添加时间 | ## 5. API接口说明 ### 5.1 会员等级管理 #### 5.1.1 获取系统会员等级列表 - **请求URL**:`/adminapi/v1/user/level/list` - **请求方法**:GET - **权限要求**:user/user_level/list - **返回结果**:系统会员等级列表数据 #### 5.1.2 添加系统会员等级 - **请求URL**:`/adminapi/v1/user/level/create` - **请求方法**:POST - **权限要求**:user/user_level/create - **请求参数**: - name:等级名称 - grade:等级 - experience_min:最低经验值 - experience_max:最高经验值 - discount:折扣比例 - icon:等级图标 - bg:等级背景图 - **返回结果**:操作结果 #### 5.1.3 获取用户等级列表 - **请求URL**:`/adminapi/v1/user/user_level/list` - **请求方法**:GET - **权限要求**:user/user/user_level_list - **请求参数**: - page:页码 - limit:每页数量 - keyword:搜索关键词 - **返回结果**:用户等级列表数据 #### 5.1.4 为用户赠送会员等级 - **请求URL**:`/adminapi/v1/user/user_level/give/{uid}` - **请求方法**:POST - **权限要求**:user/user/user_level_give - **请求参数**: - level_id:会员等级ID - is_forever:是否永久(0-否,1-是) - days:有效期(天) - **返回结果**:操作结果 ### 5.2 积分管理 #### 5.2.1 获取积分记录列表 - **请求URL**:`/adminapi/v1/user/integral/list` - **请求方法**:GET - **权限要求**:user/integral/list - **请求参数**: - page:页码 - limit:每页数量 - uid:用户ID - type:变动类型 - **返回结果**:积分记录列表数据 #### 5.2.2 为用户增加积分 - **请求URL**:`/adminapi/v1/user/integral/add/{uid}` - **请求方法**:POST - **权限要求**:user/integral/add - **请求参数**: - integral:积分数量 - mark:备注 - **返回结果**:操作结果 #### 5.2.3 为用户扣除积分 - **请求URL**:`/adminapi/v1/user/integral/sub/{uid}` - **请求方法**:POST - **权限要求**:user/integral/sub - **请求参数**: - integral:积分数量 - mark:备注 - **返回结果**:操作结果 ### 5.3 用户端接口 #### 5.3.1 获取会员等级列表 - **请求URL**:`/api/v1/user/level/list` - **请求方法**:GET - **权限要求**:登录用户 - **返回结果**:会员等级列表数据 #### 5.3.2 获取用户等级信息 - **请求URL**:`/api/v1/user/level/info` - **请求方法**:GET - **权限要求**:登录用户 - **返回结果**:当前用户的等级信息 #### 5.3.3 获取积分记录 - **请求URL**:`/api/v1/user/integral/list` - **请求方法**:GET - **权限要求**:登录用户 - **请求参数**: - page:页码 - limit:每页数量 - **返回结果**:当前用户的积分记录 ## 5. 开发规范与流程 ### 5.1 代码规范 1. **命名规范**: - 类名采用大驼峰命名法,如 `UserLevelServices` - 方法名采用小驼峰命名法,如 `checkUpgradeCondition` - 变量名采用小驼峰命名法,如 `userExperience` - 常量名采用全大写,下划线分隔,如 `LEVEL_STATUS_ENABLE` 2. **代码结构**: - 严格遵循分层架构,禁止跨层调用 - 每个方法职责单一,代码行数控制在50行以内 - 适当添加注释,说明方法功能、参数含义和返回值 - 经验值和积分变动必须记录变动原因和相关业务ID 3. **数据一致性**: - 所有经验值和积分变动都必须通过事务确保数据一致性 - 会员等级变动必须同步更新相关表的数据 - 必须记录完整的变动日志,便于追溯 ### 5.2 开发流程 1. **需求分析**:明确会员管理的功能需求和业务逻辑 2. **设计阶段**:设计数据结构、API接口和业务流程 3. **编码实现**:按照分层架构编写代码 4. **单元测试**:编写单元测试,确保功能正确性 5. **集成测试**:进行模块集成测试,测试会员与其他模块的交互 6. **性能测试**:对经验值和积分变动等高频操作进行性能测试 7. **代码审查**:提交代码审查,确保代码质量 8. **部署上线**:部署到生产环境 ## 6. 常见问题与解决方案 ### 6.1 会员等级升级不及时 **问题**:用户达到升级条件后,等级没有自动升级 **解决方案**: 1. 检查自动检测任务是否正常运行 2. 检查升级条件配置是否正确 3. 检查升级逻辑是否存在bug 4. 考虑添加手动触发升级的功能 ### 6.2 积分计算不准确 **问题**:用户积分的计算与预期不符 **解决方案**: 1. 检查积分配置是否正确 2. 检查积分变动记录,找出问题所在 3. 确保所有积分变动都通过统一的接口处理 4. 添加积分对账功能,定期检查积分一致性 ### 6.3 会员权益不生效 **问题**:用户享有某等级权益,但实际未生效 **解决方案**: 1. 检查会员等级是否正确 2. 检查权益配置是否正确 3. 检查权益生效逻辑是否存在bug 4. 添加权益生效日志,便于排查问题 ### 6.4 大量用户同时升级导致性能问题 **问题**:系统中有大量用户同时达到升级条件,导致系统性能下降 **解决方案**: 1. 优化升级检测算法,减少数据库查询 2. 使用异步处理方式,避免阻塞主流程 3. 考虑分级处理,先处理活跃用户 4. 增加系统资源,提高并发处理能力 ## 7. 扩展与定制 ### 7.1 添加新的经验值获取渠道 1. **配置经验值**:在系统配置中添加新的经验值获取渠道和数量 2. **修改代码**: - 在相关业务逻辑中添加经验值增加的调用 - 在UserBillServices中添加对应的经验值记录类型 3. **前端修改**:在前端添加对应的经验值获取入口和说明 ### 7.2 添加新的积分使用方式 1. **配置积分**:在系统配置中添加新的积分使用方式和消耗规则 2. **修改代码**: - 在相关业务逻辑中添加积分扣除的调用 - 在UserBillServices中添加对应的积分记录类型 3. **前端修改**:在前端添加对应的积分使用入口和说明 ### 7.3 扩展会员权益 1. **数据库修改**:在system_user_level表中添加新的权益字段 2. **代码修改**: - 修改会员等级配置和管理功能 - 在相关业务逻辑中添加权益判断和生效代码 3. **前端修改**:在前端添加对应的权益展示和使用入口 ## 8. 文档更新记录 | 版本 | 更新日期 | 更新内容 | 更新人 | |------|----------|----------|--------| | 1.0 | 2026-01-19 | 初始版本,包含会员等级管理、用户等级管理、经验值管理、积分管理、会员权益管理、会员等级升级机制等核心功能 | AI Assistant | ## 9. 附录 ### 9.1 核心类关系图 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Models │ │ Daos │ │ Services │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └───────────────────────┼───────────────────────┘ │ ┌─────────────────┐ │ Controllers │ └─────────────────┘ │ ┌─────────────────┐ │ Routes │ └─────────────────┘ ``` ### 9.2 会员等级升级流程图 ``` 会员等级升级流程: 1. 用户执行获取经验值的行为(签到、下单、邀请等) 2. 系统增加用户经验值,记录经验值变动 3. 检查用户当前经验值是否达到下一级别要求 4. 达到要求,更新用户等级 5. 记录等级变动日志 6. 发送等级升级通知给用户 7. 更新用户享有的权益 ``` ### 9.3 积分获取与使用流程图 ``` 积分获取与使用流程: ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 积分获取 │ │ 积分管理 │ │ 积分使用 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 签到获得积分 │ │ 积分增加 │ │ 抵扣商品金额 │ │ 下单获得积分 │ │ 积分扣除 │ │ 积分商城兑换 │ │ 邀请获得积分 │ │ 积分记录 │ │ 参与活动消耗 │ │ 活动获得积分 │ │ 积分统计 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ ``` ### 9.4 会员权益列表 | 权益名称 | 描述 | |----------|------| | 折扣优惠 | 不同等级享受不同的商品折扣 | | 等级图标 | 每个等级拥有专属图标和背景图 | | 经验值加速 | 高级会员获得经验值的速度更快 | | 专属客服 | 高级会员享受专属客服服务 | | 优先发货 | 高级会员订单优先发货 | | 生日福利 | 会员生日获得专属福利 | | 专属活动 | 高级会员参与专属活动 | | 积分翻倍 | 高级会员获得积分的倍数更高 | --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/分销系统说明文档 (help/dev-docs/phpapi/分销系统说明文档.md) ## 💳 佣金提现流程 ### 提现申请处理 ```php public function handleWithdraw($id, $status, $rejectReason = '') { $withdraw = $this->dao->get($id); if (!$withdraw) { throw new AdminException('提现记录不存在'); } if ($withdraw['status'] != 0) { throw new AdminException('提现已处理'); } // 更新状态 $updateData = [ 'status' => $status, 'handle_time' => time() ]; if ($status == 2) { // 拒绝 $updateData['reject_reason'] = $rejectReason; $this->dao->update($id, $updateData); // 返还金额到用户余额 $this->returnAmountToUser($withdraw); } else { // 通过 $this->dao->update($id, $updateData); // 实际打款操作 $this->transferToUser($withdraw); } // 发送通知 $this->sendWithdrawResultNotify($withdraw['uid'], $status, $rejectReason); } ``` ### 提现打款方式 1. **手动打款** - 管理员后台手动转账 - 记录转账凭证 2. **自动打款(需配置)** - 微信企业付款 - 支付宝转账 - 银行卡转账 ## 📊 数据统计与分析 ### 分销业绩报表 ```sql SELECT a.uid, u.nickname, COUNT(DISTINCT o.order_id) AS order_count, SUM(o.pay_price) AS order_amount, SUM(c.commission_amount) AS total_commission, COUNT(DISTINCT s.uid) AS spread_count FROM eb_user_agent a LEFT JOIN eb_user u ON a.uid = u.uid LEFT JOIN eb_store_order o ON o.uid = a.uid AND o.paid = 1 LEFT JOIN eb_agent_commission c ON c.uid = a.uid AND c.status = 1 LEFT JOIN eb_user_spread s ON s.spread_uid = a.uid GROUP BY a.uid ORDER BY total_commission DESC ``` ### 团队业绩查询 ```php public function getTeamPerformance($uid, $startTime, $endTime) { // 获取团队用户ID $teamUids = $this->getTeamUids($uid); // 查询团队业绩 return $this->dao->getPerformanceByUids( $teamUids, $startTime, $endTime ); } ``` ## 🛠️ 分销系统API ### 核心API列表 | 接口名称 | 请求方式 | 路径 | 描述 | |---------|---------|------|------| | 申请成为分销商 | POST | /api/agent/apply | 提交分销申请 | | 获取分销信息 | GET | /api/agent/info | 获取分销商信息 | | 获取佣金明细 | GET | /api/agent/commission | 佣金记录查询 | | 提现申请 | POST | /api/agent/withdraw | 提交提现申请 | | 获取团队列表 | GET | /api/agent/team | 获取下级分销商 | ## 🔍 常见问题处理 ### 1. 分销关系未正确建立 - **检查点**: - 用户是否满足分销条件 - 分销功能是否开启 - 推广链接参数是否正确传递 ### 2. 佣金未计算 - **检查点**: - 订单是否已完成 - 分销商状态是否正常 - 佣金比例是否配置 ### 3. 提现失败 - **检查点**: - 余额是否充足 - 提现信息是否完整 - 风控规则是否触发 ## 📝 版本更新记录 | 版本 | 日期 | 更新内容 | |------|------|---------| | v1.0 | 2024-01-17 | 初版文档创建 | | v1.1 | 2024-01-18 | 增加多级分销配置 | --- **文档维护**:技术团队 **最后更新**:2024-01-17 💡 **提示**:分销系统涉及资金流转,请定期审核佣金计算和提现记录,确保财务数据准确。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/后端代码目录结构说明 (help/dev-docs/phpapi/后端代码目录结构说明.md) # CRMEB 后端代码目录结构说明 ## 项目概述 CRMEB 是一个基于 ThinkPHP 6.x 框架开发的电商系统,采用多应用架构模式,支持管理后台、用户端API、客服系统等多个应用模块。 ## 核心架构 ### 架构模式 - **框架**: ThinkPHP 6.x - **架构模式**: 多应用架构 (Multi-App) - **设计模式**: MVC + Service + DAO 分层架构 - **依赖注入**: 容器管理 - **数据库**: MySQL (支持主从分离) ### 目录结构总览 ``` crmeb/ ├── app/ # 应用目录 │ ├── adminapi/ # 管理后台API应用 │ ├── api/ # 用户端API应用 │ ├── kefuapi/ # 客服系统API应用 │ ├── outapi/ # 外部API应用 │ ├── dao/ # 数据访问层 (DAO) │ ├── http/ # HTTP相关类 │ ├── jobs/ # 队列任务 │ ├── lang/ # 多语言包 │ ├── listener/ # 事件监听器 │ ├── model/ # 数据模型层 │ └── services/ # 业务逻辑服务层 ├── config/ # 配置文件目录 ├── crmeb/ # 核心框架扩展 ├── public/ # 公共资源目录 ├── route/ # 路由定义 ├── runtime/ # 运行时文件 └── vendor/ # 第三方依赖 ``` ## 详细目录说明 ### 1. 应用目录 (app/) #### 1.1 管理后台API (app/adminapi/) ``` /* Detailed source-code truncated for AI context efficiency. */ ``` #### 1.2 用户端API (app/api/) ``` api/ ├── config/route.php # 用户端路由配置 ├── controller/ # 控制器层 │ ├── pc/ # PC端控制器 │ ├── v1/ # API版本1 │ │ ├── activity/ # 活动相关 │ │ ├── admin/ # 管理相关 │ │ ├── order/ # 订单相关 │ │ ├── publics/ # 公共接口 │ │ ├── store/ # 商店相关 │ │ ├── user/ # 用户相关 │ │ └── wechat/ # 微信相关 │ ├── v2/ # API版本2 │ ├── CrontabController.php # 定时任务控制器 │ ├── LoginController.php # 登录控制器 │ ├── PayController.php # 支付控制器 │ └── PublicController.php # 公共控制器 ├── middleware/ # 中间件 │ ├── AuthTokenMiddleware.php # Token验证中间件 │ ├── BlockerMiddleware.php # 访问限制中间件 │ ├── CustomerMiddleware.php # 客户中间件 │ └── StationOpenMiddleware.php # 站点开放中间件 ├── route/ # 路由定义 │ ├── pc.php # PC端路由 │ ├── v1.php # API v1路由 │ └── v2.php # API v2路由 └── validate/ # 验证器 └── user/ # 用户验证器 ``` #### 1.3 数据访问层 (app/dao/) ``` /* Detailed source-code truncated for AI context efficiency. */ ``` #### 1.4 服务层 (app/services/) ``` services/ ├── activity/ # 活动服务 ├── admin/ # 管理服务 ├── agent/ # 代理服务 ├── app/ # 应用服务 ├── clone/ # 克隆服务 ├ ├── community/ # 社区服务 ├── crud/ # CRUD代码生成服务 ├ ├── diy/ # DIY服务 ├ ├── export/ # 导出服务 ├ ├── file/ # 文件服务 ├ ├── goods/ # 商品服务 ├ ├── import/ # 导入服务 ├ ├── invoice/ # 发票服务 ├ ├── ka/ # 客服服务 ├ ├── lang/ # 多语言服务 ├ ├── live/ # 直播服务 ├ ├── message/ # 消息服务 ├ ├── ota/ # OTA服务 ├ ├── other/ # 其他服务 ├ ├── pay/ # 支付服务 ├ ├── phonestore/ # 手机商店服务 ├ ├── product/ # 商品服务 ├ ├── protect/ # 保护服务 ├ ├── queue/ # 队列服务 ├ ├── scan/ # 扫码服务 ├ ├── serve/ # 服务服务 ├ ├── setting/ # 设置服务 ├ ├── shipping/ # 物流服务 ├ ├── stat/ # 统计服务 ├ ├── store/ # 商店服务 ├ ├── system/ # 系统服务 ├ ├── template/ # 模板服务 ├ ├── user/ # 用户服务 ├ ├── utils/ # 工具服务 └── work/ # 工作服务 ``` #### 1.5 模型层 (app/model/) ``` model/ ├── activity/ # 活动模型 ├── card/ # 卡券模型 ├── community/ # 社区模型 ├── configure/ # 配置模型 ├── diy/ # DIY模型 ├── log/ # 日志模型 ├── message/ # 消息模型 ├── ota/ # OTA模型 ├── other/ # 其他模型 ├── pay/ # 支付模型 ├── product/ # 商品模型 ├── queue/ # 队列模型 ├── shipping/ # 物流模型 ├── store/ # 商店模型 ├── system/ # 系统模型 ├── user/ # 用户模型 └── work/ # 工作模型 ``` ### 2. 核心框架扩展 (crmeb/) #### 2.1 基础类 (crmeb/basic/) ``` basic/ ├── BaseController.php # 控制器基类 ├── BaseJobs.php # 任务基类 ├── BaseManager.php # 管理器基类 ├── BaseModel.php # 模型基类 └── BaseStorage.php # 存储基类 ``` #### 2.2 命令行 (crmeb/command/) ``` command/ ├── Npm.php # NPM命令 ├── Timer.php # 定时器命令 ├── Util.php # 工具命令 └── Workerman.php # Workerman命令 ``` #### 2.3 异常处理 (crmeb/exceptions/) ``` exceptions/ ├── AdminException.php # 管理异常 ├── ApiException.php # API异常 ├── ApiStatusException.php # API状态异常 ├── AuthException.php # 认证异常 ├── CrudException.php # CRUD异常 ├── PayException.php # 支付异常 └── UploadException.php # 上传异常 ``` #### 2.4 接口定义 (crmeb/interfaces/) ``` interfaces/ ├── JobInterface.php # 任务接口 ├── ListenerInterface.php # 监听器接口 ├── MiddlewareInterface.php # 中间件接口 └── ProviderInterface.php # 提供者接口 ``` #### 2.5 服务层 (crmeb/services/) ``` services/ ├── app/ # 应用服务 │ ├── MiniProgramService.php # 小程序服务 │ ├── WechatOpenService.php # 微信开放服务 │ └── WechatService.php # 微信服务 ├── copyproduct/ # 商品复制服务 ├── crud/ # CRUD代码生成服务 ├── easywechat/ # 微信SDK服务 ├── express/ # 快递服务 ├── invoice/ # 发票服务 ├── oauth/ # OAuth认证服务 ├── pay/ # 支付服务 ├── printer/ # 打印服务 ├── serve/ # 系统服务 ├── sms/ # 短信服务 ├── template/ # 模板消息服务 ├── upload/ # 上传服务 ├── workerman/ # Workerman服务 └── 核心服务文件... ``` #### 2.6 特性 (crmeb/traits/) ``` traits/ ├── JwtAuthModelTrait.php # JWT认证特性 ├── ModelTrait.php # 模型特性 └── QueueTrait.php # 队列特性 ``` #### 2.7 工具类 (crmeb/utils/) ``` utils/ ├── Arr.php # 数组工具 ├── Canvas.php # 画布工具 ├── Captcha.php # 验证码工具 ├── DownloadImage.php # 图片下载工具 ├── fileVerification.php # 文件验证工具 ├── Hook.php # 钩子工具 ├── Json.php # JSON工具 ├── JwtAuth.php # JWT认证工具 ├── Queue.php # 队列工具 ├── Rsa.php # RSA加密工具 ├── Str.php # 字符串工具 ├── Terminal.php # 终端工具 └── Translate.php # 翻译工具 ``` ### 3. 配置文件 (config/) ``` config/ ├── ajcaptcha.php # 验证码配置 ├── app.php # 应用配置 ├── cache.php # 缓存配置 ├── captcha.php # 图片验证码配置 ├── console.php # 控制台配置 ├── cookie.php # Cookie配置 ├── database.php # 数据库配置 ├── filesystem.php # 文件系统配置 ├── lang.php # 多语言配置 ├── log.php # 日志配置 ├── pay.php # 支付配置 ├── plat.php # 平台配置 ├── printer.php # 打印配置 ├── qrcode.php # 二维码配置 ├── queue.php # 队列配置 ├── route.php # 路由配置 ├── session.php # 会话配置 ├── sms.php # 短信配置 ├── trace.php # 调试跟踪配置 ├── upload.php # 上传配置 ├── view.php # 视图配置 └── workerman.php # Workerman配置 ``` ### 4. 公共资源 (public/) ``` public/ ├── admin/ # 管理后台前端 ├── assets/ # 静态资源 ├── install/ # 安装程序 ├── pages/ # 页面文件 ├── static/ # 静态文件 ├── statics/ # 系统静态文件 ├── upgrade/ # 升级程序 ├── .htaccess # Apache重写规则 ├── favicon.ico # 网站图标 ├── index.html # 默认首页 └── 入口文件... ``` ### 5. 路由定义 (route/) ``` route/ ├── README.md # 路由说明 └── route.php # 主路由文件 ``` ## 架构设计模式 ### 1. 分层架构 - **Controller层**: 处理HTTP请求,参数验证,调用Service - **Service层**: 业务逻辑处理,事务管理,调用DAO - **DAO层**: 数据访问,SQL操作,模型映射 - **Model层**: 数据模型定义,关联关系 ### 2. 依赖注入 - 使用ThinkPHP容器管理对象依赖 - 通过构造函数注入Service依赖 - 支持接口编程和面向切面编程 ### 3. 中间件机制 - 认证授权中间件 - 权限检查中间件 - 操作日志中间件 - 参数过滤中间件 ### 4. 事件监听 - 订单状态变更事件 - 用户注册事件 - 支付完成事件 - 商品库存变更事件 ## 核心功能模块 ### 1. 商品管理 - 商品分类、规格、属性管理 - 库存管理、价格策略 - 商品审核、上下架管理 - 商品导入导出功能 ### 2. 订单管理 - 订单创建、支付、发货流程 - 订单状态管理和追踪 - 退款、售后处理 - 订单统计分析 ### 3. 用户管理 - 用户注册、登录、认证 - 用户等级、会员体系 - 用户标签、分组管理 - 用户行为分析 ### 4. 营销活动 - 优惠券、满减活动 - 拼团、砍价、秒杀 - 积分商城、签到奖励 - 推广分销系统 ### 5. 支付系统 - 微信支付、支付宝支付 - 余额支付、积分支付 - 支付回调处理 - 退款对账功能 ### 6. 物流配送 - 快递公司对接 - 运费模板管理 - 物流信息查询 - 配送状态跟踪 ## 技术特性 ### 1. 多应用架构 - 管理后台、用户端、客服系统独立部署 - 统一的认证授权机制 - 模块化设计便于扩展 ### 2. 微服务支持 - 队列任务异步处理 - 缓存服务集成 - 分布式文件存储 - 多数据库支持 ### 3. 安全机制 - JWT Token认证 - 接口签名验证 - SQL注入防护 - XSS攻击防护 ### 4. 性能优化 - 数据库读写分离 - 缓存策略优化 - 静态资源CDN - 接口响应压缩 ## 开发规范 ### 1. 命名规范 - 类名: PascalCase (如 StoreProductServices) - 方法名: camelCase (如 getProductList) - 变量名: camelCase (如 productId) - 常量名: UPPER_CASE (如 API_VERSION) ### 2. 文件组织 - Controller按业务模块分组 - Service按功能领域划分 - DAO按数据实体组织 - Model对应数据库表结构 ### 3. 注释规范 - 类和方法的PHPDoc注释 - 复杂业务逻辑说明 - API接口文档注释 - 数据库字段说明 ### 4. 错误处理 - 统一异常处理机制 - 自定义业务异常类 - 错误日志记录 - 用户友好错误提示 ## 部署要求 ### 1. 环境要求 - PHP >= 7.4 - MySQL >= 5.7 - Redis >= 4.0 - Nginx/Apache ### 2. 扩展要求 - PDO MySQL - GD2/ImageMagick - Curl - OpenSSL - Fileinfo ### 3. 权限设置 - runtime目录可写 - public/uploads可写 - 日志目录可写 - 缓存目录可写 ## 维护建议 ### 1. 代码维护 - 定期代码审查 - 单元测试覆盖 - 性能监控分析 - 安全漏洞扫描 ### 2. 数据库维护 - 定期数据备份 - 索引优化调整 - 慢查询分析 - 数据清理归档 ### 3. 系统监控 - 服务器资源监控 - 应用性能监控 - 错误日志监控 - 用户行为分析 --- 本文档详细说明了CRMEB后端代码的目录结构、架构设计和开发规范,为开发团队提供完整的技术指导和参考。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/开发规范说明 (help/dev-docs/phpapi/开发规范说明.md) # 开发规范说明 ## 🎯 基于已有规范的扩展 ### 1. Service层命名和使用规范 ```php // ✅ 正确示例 class UserServices extends BaseServices { public function getUserInfo(int $uid) {} public function updateUserStatus(int $uid, int $status) {} } // ❌ 避免在Controller中直接操作数据库 // 不要这样写:Db::name('user')->where('id', $uid)->update($data) ``` ### 2. DAO层职责划分 ```php // ✅ DAO只负责基础CRUD class UserDao extends BaseDao { public function getById(int $id) {} public function updateById(int $id, array $data) {} } // Service调用DAO class UserServices { public function complexBusiness() { $user = $this->dao->getById($id); // 业务逻辑处理 $this->dao->updateById($id, $data); } } ``` ### 3. 异常处理标准 ```php // 使用项目特定异常类 throw new ApiException('错误信息', 400); throw new AdminException('管理端错误', 500); // 统一返回格式 return $this->success($data); return $this->fail('错误信息'); ``` ### 4. 参数验证位置 ```php // 验证放在validate目录下对应文件 // adminapi/validate/user/UserValidata.php class UserValidata extends Validate { protected $rule = [ 'nickname' => 'require|max:25', 'phone' => 'require|mobile' ]; } ``` ### 5. 注释标准补充 ```php /** * 获取用户信息(包含扩展信息) * @param int $uid 用户ID * @param array $with 关联查询 ['order', 'address'] * @return array * @throws ApiException */ public function getUserDetail(int $uid, array $with = []) { // 业务逻辑 } ``` ## 🔧 工具类使用规范 - 使用 `crmeb\utils\` 下的工具类 - 配置获取使用 `SystemConfigService` - 缓存操作使用 `CacheService` - 文件上传使用 `UploadService` ## 📝 代码提交规范 1. 提交前运行测试 2. 提交信息格式:`[类型] 描述` - `[feat] 新增用户积分功能` - `[fix] 修复订单状态更新问题` - `[docs] 更新API文档` - `[style] 调整代码格式` 3. 避免大块提交,每个提交专注于一个功能或修复 ## 🚧 分支管理 - `master` - 生产环境代码 - `develop` - 开发分支 - `feature/xxx` - 功能开发分支 - `hotfix/xxx` - 紧急修复分支 ## 🧪 测试规范 1. 单元测试覆盖核心业务逻辑 2. 集成测试覆盖API接口 3. 测试数据使用工厂模式生成 4. 测试用例命名:`testMethodNameWhenConditionThenResult` --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/支付开发流程文档 V2 (help/dev-docs/phpapi/支付开发流程文档-V2.md) # CRMEB 支付开发流程文档 ## 🎯 支付功能概述 基于CRMEB 5.6.4+版本的支付系统分析,项目采用统一的支付服务架构,支持多种支付方式集成。 ### 支持的支付方式 ```php // app/services/pay/PayServices.php const WEIXIN_PAY = 'weixin'; // 微信支付 const YUE_PAY = 'yue'; // 余额支付 const OFFLINE_PAY = 'offline'; // 线下支付 const ALIAPY_PAY = 'alipay'; // 支付宝 const ALLIN_PAY = 'allinpay'; // 通联支付 const FRIEND = 'friend'; // 好友代付 const BANK = 'bank'; // 银行转账 ``` ## 🏗️ 支付系统架构 ### 核心服务类结构 ``` app/services/pay/ ├── PayServices.php # 统一支付入口服务 ├── OrderPayServices.php # 订单支付服务 ├── PayNotifyServices.php # 支付回调服务 ├── YuePayServices.php # 余额支付服务 └── RechargeServices.php # 充值服务 crmeb/services/pay/ ├── Pay.php # 支付基础驱动 ├── storage/ │ ├── WechatPay.php # 微信支付驱动 │ ├── AliPay.php # 支付宝驱动 │ ├── AllinPay.php # 通联支付驱动 │ └── V3WechatPay.php # 微信支付V3驱动 ``` ### 支付流程 #### 1. 支付请求流程 ```mermaid graph TD A[客户端] --> B[支付控制器] B --> C[PayServices] C --> D[支付驱动 WechatPay/AliPay] D --> E[第三方支付平台] E --> F[返回支付参数] F --> A ``` #### 2. 支付回调流程 ```mermaid graph TD A[第三方支付] --> B[支付回调接口] B --> C[PayNotifyServices] C --> D[订单状态更新] C --> E[支付记录更新] D --> F[业务处理] ``` ## 🔧 核心代码解析 ### 统一支付入口 (PayServices.php) ```php public function pay(string $payType, string $orderId, string $price, string $successAction, string $body, array $options = []) { try { // 支付类型映射处理 if (in_array($payType, ['routine', 'weixinh5', 'weixin', 'pc', 'store'])) { $payType = 'wechat_pay'; // V3接口判断 if (sys_config('pay_wechat_type') == 1) { $payType = 'v3_wechat_pay'; } } elseif ($payType == 'alipay') { $payType = 'ali_pay'; } elseif ($payType == 'allinpay') { $payType = 'allin_pay'; } // 创建支付实例 $pay = app()->make(Pay::class, [$payType]); return $pay->create($orderId, $price, $successAction, $body, '', $options); } catch (\Exception $e) { throw new ApiException($e->getMessage()); } } ``` ### 微信支付驱动 (WechatPay.php) ```php public function create(string $orderId, string $totalFee, string $attach, string $body, string $detail, array $options = []) { $this->authSetPayType(); switch ($this->payType) { case Order::NATIVE: // 扫码支付 return WechatService::nativePay(null, $orderId, $totalFee, $attach, $body, $detail); case Order::APP: // APP支付 return WechatService::appPay($options['openid'], $orderId, $totalFee, $attach, $body, $detail); case Order::JSAPI: // 小程序/公众号支付 if (request()->isRoutine()) { // 小程序支付 if ($options['pay_new_weixin_open']) { return MiniProgramService::newJsPay($options['openid'], $orderId, $totalFee, $attach, $body, $detail, $options); } return MiniProgramService::jsPay($options['openid'], $orderId, $totalFee, $attach, $body, $detail); } return WechatService::jsPay($options['openid'], $orderId, $totalFee, $attach, $body, $detail); case 'h5': // H5支付 return WechatService::paymentPrepare(null, $orderId, $totalFee, $attach, $body, $detail, 'MWEB'); default: throw new PayException('微信支付:支付类型错误'); } } ``` ### 支付回调处理 (PayNotifyServices.php) ```php public function wechatProduct(string $order_id = null, string $trade_no = null, string $payType = PayServices::WEIXIN_PAY) { try { $services = app()->make(StoreOrderSuccessServices::class); $orderInfo = $services->getOne(['order_id' => $order_id]); if (!$orderInfo) return true; if ($orderInfo->paid) return true; return $services->paySuccess($orderInfo->toArray(), $payType, ['trade_no' => $trade_no]); } catch (\Exception $e) { return false; } } ``` ## 🛠️ 开发指南 ### 1. 支付配置设置 在后台管理系统配置: - 微信支付参数(APPID、商户号、API密钥、证书) - 支付宝配置 - 通联支付配置 - 支付方式开关 ### 2. 发起支付调用 ```php // 在控制器中调用 public function createPayment() { $params = $this->request->post(); // 参数验证 validate(PaymentValidate::class)->scene('create')->check($params); $payServices = app()->make(PayServices::class); $result = $payServices->pay( $params['pay_type'], $params['order_id'], $params['amount'], url('api/v1/payment/notify/wechat', [], true, true), '商品购买' ); return $this->success($result); } ``` ### 3. 支付回调配置 ```php // 路由配置 Route::post('api/v1/payment/notify/:type', 'api/v1/payment/notify'); // 回调控制器 public function notify($type) { $notifyService = app()->make(PayNotifyServices::class); switch ($type) { case 'wechat': return $notifyService->wechatProduct( $this->request->post('out_trade_no'), $this->request->post('transaction_id') ); case 'alipay': // 支付宝回调处理 break; } return response('SUCCESS'); } ``` ## 🧪 测试指南 ### 单元测试示例 ```php class PaymentTest extends TestCase { public function testWechatPaymentCreation() { $payService = new PayServices(); $result = $payService->pay( 'weixin', 'TEST20240117001', '100.00', 'https://domain.com/notify', '测试商品' ); $this->assertArrayHasKey('timeStamp', $result); $this->assertArrayHasKey('nonceStr', $result); $this->assertArrayHasKey('package', $result); } } ``` ### 沙箱环境配置 ```bash # 微信支付沙箱 WECHAT_SANDBOX=true WECHAT_APPID=sandbox_appid WECHAT_MCHID=sandbox_mchid # 支付宝沙箱 ALIPAY_SANDBOX=true ALIPAY_GATEWAY=https://openapi.alipaydev.com/gateway.do ``` ## 📊 数据库设计 ### 支付记录表 (eb_store_pay) ```sql CREATE TABLE `eb_store_pay` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `uid` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '用户id', `oid` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '订单id', `order_id` varchar(32) NOT NULL DEFAULT '' COMMENT '订单号', `out_trade_no` varchar(32) NOT NULL DEFAULT '' COMMENT '支付流水号', `pay_type` varchar(20) NOT NULL DEFAULT '' COMMENT '支付方式', `pay_price` decimal(10,2) UNSIGNED NOT NULL DEFAULT '0.00' COMMENT '支付金额', `trade_no` varchar(64) DEFAULT NULL COMMENT '第三方支付流水号', `paid` tinyint(1) UNSIGNED NOT NULL DEFAULT '0' COMMENT '支付状态', `pay_time` int(10) UNSIGNED DEFAULT NULL COMMENT '支付时间', `add_time` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `out_trade_no` (`out_trade_no`), KEY `order_id` (`order_id`), KEY `paid` (`paid`) ) ENGINE=InnoDB COMMENT='支付记录表'; ``` ## 🚀 部署运维 ### 生产环境配置 ```bash # 微信支付配置 WECHAT_APPID=your_appid WECHAT_MCHID=your_mchid WECHAT_KEY=your_key WECHAT_CERT_PATH=/path/to/cert.pem WECHAT_KEY_PATH=/path/to/key.pem # SSL证书配置 ssl_certificate /path/to/ssl/cert.pem; ssl_certificate_key /path/to/ssl/key.pem; ``` ### 监控告警 ```php // 支付监控指标 $metrics = [ 'payment_success_rate' => ($successCount / $totalCount) * 100, 'payment_response_time' => microtime(true) - $startTime, 'payment_error_count' => $errorCount ]; // 日志记录 Log::info('支付监控', $metrics); ``` ## 🔧 故障处理 ### 常见问题 1. **支付回调失败**:检查nginx配置、SSL证书、防火墙 2. **签名错误**:验证支付密钥配置 3. **金额不一致**:检查金额单位和优惠计算 4. **重复支付**:添加防重机制和状态检查 ### 应急处理 ```bash # 查看支付日志 tail -f runtime/log/payment.log # 禁用问题支付方式 php think pay:disable weixin # 启用备用支付 php think pay:enable alipay ``` --- **文档版本**: v2.0 **更新日期**: 2024-01-17 **适用版本**: CRMEB 5.6.4+ 💡 提示:支付功能涉及资金安全,请严格遵循安全规范,定期进行安全审计。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/支付开发流程文档 (help/dev-docs/phpapi/支付开发流程文档.md) # 支付开发流程文档 ## 🎯 支付功能概述 ### 支付场景 - **商品购买支付**:普通商品订单支付 - **服务购买支付**:虚拟服务、会员购买 - **充值支付**:余额充值、积分充值 - **保证金支付**:商户保证金、服务保证金 - **退款处理**:订单退款、冲正处理 ### 支持的支付方式 ```php const PAY_TYPE_WECHAT = 'wechat'; // 微信支付 const PAY_TYPE_ALIPAY = 'alipay'; // 支付宝 const PAY_TYPE_BALANCE = 'balance'; // 余额支付 const PAY_TYPE_INTEGRAL = 'integral'; // 积分支付 const PAY_TYPE_UNION = 'union'; // 云闪付 const PAY_TYPE_BANK = 'bank'; // 银行卡支付 ``` ## 🏗️ 支付系统架构 ### 支付模块架构 ``` ┌─────────────────────────────────────────────────────┐ │ 支付控制器 (Controller) │ │ - 支付入口处理 │ │ - 参数验证 │ │ - 结果返回 │ └─────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ 支付服务层 (PaymentService) │ │ - 支付逻辑处理 │ │ - 支付方式路由 │ │ - 支付状态管理 │ └─────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ 支付渠道适配层 (PaymentAdapter) │ │ - 微信支付适配器 (WechatPayment) │ │ - 支付宝适配器 (AlipayPayment) │ │ - 余额支付适配器 (BalancePayment) │ │ - 积分支付适配器 (IntegralPayment) │ └─────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ 第三方支付SDK │ │ - 微信支付官方SDK │ │ - 支付宝官方SDK │ │ - 银行支付接口 │ └─────────────────────────────────────────────────────┘ ``` ### 数据库设计 ```sql -- 支付记录表 CREATE TABLE `store_pay` ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(32) NOT NULL COMMENT '订单号', `out_trade_no` varchar(32) NOT NULL COMMENT '支付流水号', `pay_type` varchar(20) NOT NULL COMMENT '支付方式', `pay_price` decimal(10,2) NOT NULL COMMENT '支付金额', `trade_no` varchar(64) DEFAULT NULL COMMENT '第三方支付流水号', `pay_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '支付状态', `pay_time` int(11) DEFAULT NULL COMMENT '支付时间', `create_time` int(11) NOT NULL COMMENT '创建时间', `update_time` int(11) NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_out_trade_no` (`out_trade_no`), KEY `idx_order_id` (`order_id`), KEY `idx_pay_status` (`pay_status`) ) ENGINE=InnoDB COMMENT='支付记录表'; -- 退款记录表 CREATE TABLE `store_refund` ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(32) NOT NULL COMMENT '订单号', `refund_no` varchar(32) NOT NULL COMMENT '退款流水号', `refund_amount` decimal(10,2) NOT NULL COMMENT '退款金额', `refund_reason` varchar(255) DEFAULT NULL COMMENT '退款原因', `refund_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '退款状态', `refund_time` int(11) DEFAULT NULL COMMENT '退款时间', `create_time` int(11) NOT NULL COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_refund_no` (`refund_no`), KEY `idx_order_id` (`order_id`) ) ENGINE=InnoDB COMMENT='退款记录表'; ``` ## 🔧 开发流程 ### 1. 需求分析与设计 ```markdown 1. 确定支付场景和需求 2. 选择支持的支付方式 3. 设计支付流程和状态流转 4. 确定退款政策和规则 5. 设计对账和清算流程 ``` ### 2. 环境准备 ```bash # 安装支付SDK依赖 composer require overtrue/wechat composer require alipay-sdk/php-all # 配置支付参数 cp .env.example .env # 配置微信支付参数 WECHAT_APPID=your_appid WECHAT_MCHID=your_mchid WECHAT_KEY=your_key WECHAT_APPSECRET=your_appsecret # 配置支付宝参数 ALIPAY_APPID=your_appid ALIPAY_PRIVATE_KEY=your_private_key ALIPAY_PUBLIC_KEY=your_public_key ``` ### 3. 支付控制器开发 ```php request->post(); validate(PaymentValidate::class)->scene('create')->check($params); // 调用支付服务 $paymentService = app()->make(PaymentService::class); $result = $paymentService->createPayment($params); return $this->success($result); } /** * 支付回调处理 * @route('api/v1/payment/notify/:type') */ public function paymentNotify($type) { try { $paymentService = app()->make(PaymentService::class); $result = $paymentService->handleNotify($type, $this->request->post()); // 返回第三方支付要求的成功响应 return response($result['response']); } catch (\Exception $e) { Log::error('支付回调处理失败: ' . $e->getMessage()); return response('FAIL'); } } } ``` ### 4. 支付服务层开发 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 5. 支付适配器开发(以微信支付为例) ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 6. 支付接口定义 ```php 'TEST202401170001', 'pay_type' => 'wechat', 'pay_amount' => 100.00 ]; // 创建支付服务实例 $paymentService = new PaymentService(); // 测试支付创建 $result = $paymentService->createPayment($params); $this->assertArrayHasKey('pay_params', $result); $this->assertEquals('wechat', $result['pay_type']); } public function testPaymentNotify() { // 模拟微信支付回调数据 $notifyData = [ 'return_code' => 'SUCCESS', 'result_code' => 'SUCCESS', 'out_trade_no' => 'TEST202401170001', 'transaction_id' => '420000202401170001', 'total_fee' => '10000', 'time_end' => '20240117153000' ]; $paymentService = new PaymentService(); $result = $paymentService->handleNotify('wechat', $notifyData); $this->assertEquals('SUCCESS', $result['response']); } } ``` ### 2. 集成测试 ```bash # 运行支付相关测试 php think test tests/services/PaymentServiceTest php think test tests/services/payment/WechatPaymentTest php think test tests/services/payment/AlipayPaymentTest # 生成测试覆盖率报告 php think test --coverage-html coverage/payment ``` ### 3. 沙箱环境测试 ```php // 配置沙箱环境 'wechat' => [ 'app_id' => '沙箱appid', 'mch_id' => '沙箱商户号', 'key' => '沙箱key', 'sandbox' => true, // 开启沙箱模式 ] // 支付宝沙箱配置 'alipay' => [ 'app_id' => '沙箱appid', 'gateway_url' => 'https://openapi.alipaydev.com/gateway.do', 'sign_type' => 'RSA2', 'sandbox' => true, ] ``` ## 🚀 部署上线 ### 1. 生产环境配置 ```bash # 设置生产环境配置 cp .env.production .env # 配置生产环境支付参数 WECHAT_APPID=生产环境appid WECHAT_MCHID=生产环境商户号 WECHAT_KEY=生产环境key WECHAT_CERT_PATH=/path/to/cert/apiclient_cert.pem WECHAT_KEY_PATH=/path/to/cert/apiclient_key.pem ALIPAY_APPID=生产环境appid ALIPAY_PRIVATE_KEY=生产环境私钥 ALIPAY_PUBLIC_KEY=生产环境公钥 ``` ### 2. SSL证书配置 ```nginx # Nginx SSL配置 server { listen 443 ssl http2; server_name yourdomain.com; ssl_certificate /path/to/ssl/cert.pem; ssl_certificate_key /path/to/ssl/key.pem; # 支付回调接口 location /api/v1/payment/notify/ { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` ### 3. 监控告警配置 ```yaml # 支付监控指标 payment: success_rate: type: gauge help: 支付成功率 labels: [pay_type] response_time: type: histogram help: 支付响应时间分布 labels: [pay_type] error_count: type: counter help: 支付错误次数 labels: [pay_type, error_code] ``` ## 📊 运维监控 ### 1. 日志监控 ```php // 支付关键日志记录 Log::info('支付创建', [ 'order_id' => $orderId, 'pay_type' => $payType, 'amount' => $amount, 'user_id' => $userId ]); Log::error('支付失败', [ 'order_id' => $orderId, 'error_code' => $errorCode, 'error_msg' => $errorMsg, 'trace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3) ]); ``` ### 2. 性能监控 ```bash # 监控支付接口性能 # 平均响应时间 < 200ms # 95%响应时间 < 500ms # 错误率 < 0.1% # 使用Prometheus监控 payment_api_duration_seconds_bucket{pay_type="wechat",le="0.1"} 12345 payment_api_duration_seconds_bucket{pay_type="wechat",le="0.5"} 23456 ``` ### 3. 对账处理 ```php /** * 每日对账任务 */ public function dailyReconciliation() { $yesterday = strtotime('yesterday'); $today = strtotime('today'); // 查询本地支付记录 $localRecords = $this->payDao->getRecordsByTime($yesterday, $today); // 查询第三方支付记录 foreach (['wechat', 'alipay'] as $payType) { $adapter = $this->getPaymentAdapter($payType); $thirdPartyRecords = $adapter->queryBill($yesterday, $today); // 对账处理 $result = $this->reconcile($localRecords, $thirdPartyRecords); // 记录对账结果 $this->saveReconciliationResult($result); } } ``` ## 🔧 故障处理 ### 常见问题处理 ```markdown 1. **支付回调失败** - 检查网络连通性 - 验证证书有效性 - 检查回调地址配置 2. **支付签名错误** - 检查密钥配置 - 验证签名算法 - 检查参数编码 3. **支付金额不符** - 检查金额单位(分/元) - 验证金额计算逻辑 - 检查优惠券抵扣 4. **重复支付** - 检查支付状态验证 - 添加防重机制 - 人工审核处理 ``` ### 应急处理流程 ```bash # 1. 暂停支付功能 php think payment:disable wechat # 2. 查看支付日志 tail -f runtime/log/payment.log # 3. 回滚有问题的版本 git revert # 4. 启用备用支付通道 php think payment:enable alipay ``` --- **文档版本**: v1.0 **最后更新**: 2024-01-17 **维护人员**: 支付开发团队 💡 **提示**: 支付功能涉及资金安全,请严格遵循安全规范和审计要求。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/系统事件开发文档 (help/dev-docs/phpapi/系统事件开发文档.md) # CRMEB 系统事件开发文档 ## 1. 事件机制概述 CRMEB 后端系统采用**事件驱动架构**,通过事件机制实现模块间的解耦和通信。事件系统允许在不直接依赖的情况下,实现不同模块间的交互和业务逻辑扩展。 ### 1.1 核心概念 - **事件(Event)**:系统中发生的特定动作或状态变化,如订单创建、用户注册等 - **监听器(Listener)**:监听特定事件并执行相应处理逻辑的类 - **事件触发(Trigger)**:在特定业务逻辑点调用事件,通知相关监听器执行 ## 2. 事件系统架构 ### 2.1 监听器接口定义 所有监听器必须实现 `crmeb\interfaces\ListenerInterface` 接口,该接口定义了统一的事件处理方法: ```php [], // 事件绑定 'listen' => [ // 事件监听 'EventName' => [ 'Listener1::class', 'Listener2::class', ], ], ]; ``` **示例配置**: ```php return [ 'listen' => [ 'HttpEnd' => [\app\listener\http\HttpEndListener::class], //HTTP请求结束回调事件 'UserRegisterListener' => [\app\listener\user\RegisterListener::class], //用户注册后置事件 'OrderCreateAfterListener' => [\app\listener\order\OrderCreateAfterListener::class], //订单创建后置事件 // 更多事件... ], ]; ``` ## 3. 系统内置事件 CRMEB 系统内置了丰富的事件,涵盖了系统运行的各个方面: | 事件类别 | 事件名称 | 触发时机 | 监听器类 | |---------|---------|---------|---------| | **基础事件** | HttpEnd | HTTP请求结束 | \app\listener\http\HttpEndListener::class | | | QueueStartListener | 队列启动 | \app\listener\queue\QueueStartListener::class | | **用户相关** | UserLoginListener | 用户登录 | \app\listener\user\LoginListener::class | | | AdminLoginListener | 管理员登录 | \app\listener\admin\AdminLoginListener::class | | | UserRegisterListener | 用户注册 | \app\listener\user\RegisterListener::class | | | WechatAuthListener | 微信授权 | \app\listener\wechat\AuthListener::class | | | UserLevelListener | 用户升级 | \app\listener\user\UserLevelListener::class | | | UserVisitListener | 用户访问 | \app\listener\user\UserVisitListener::class | | **订单相关** | OrderCreateAfterListener | 订单创建 | \app\listener\order\OrderCreateAfterListener::class | | | OrderPaySuccessListener | 订单支付成功 | \app\listener\order\OrderPaySuccessListener::class | | | OrderDeliveryListener | 订单发货 | \app\listener\order\OrderDeliveryListener::class | | | OrderTakeListener | 订单收货 | \app\listener\order\OrderTakeListener::class | | | OrderRefundCreateAfterListener | 售后单生成 | \app\listener\order\OrderRefundCreateAfterListener::class | | | OrderRefundCancelAfterListener | 售后单取消 | \app\listener\order\OrderRefundCancelAfterListener::class | | **其他事件** | OutPushListener | 对外推送 | \app\listener\out\OutPushListener::class | | | NoticeListener | 通知消息 | \app\listener\notice\NoticeListener::class | | | CustomEventListener | 自定义事件 | \app\listener\CustomEventListener::class | ## 4. 事件触发与处理 ### 4.1 事件触发方式 事件通过 `event()` 函数进行触发,该函数是 ThinkPHP 框架提供的全局函数: ```php // 触发事件 event('EventName', $eventData); // 示例:触发订单创建事件 event('OrderCreateAfterListener', [$order, $group, $uid, $key, $combinationId, $seckillId, $bargainId]); ``` ### 4.2 事件处理流程 1. **事件触发**:在业务逻辑中通过 `event()` 函数触发特定事件 2. **事件分发**:系统根据事件名称查找对应的监听器列表 3. **监听器执行**:依次调用每个监听器的 `handle()` 方法,并传递事件数据 4. **业务处理**:监听器执行各自的业务逻辑,如数据处理、消息发送等 5. **处理完成**:所有监听器执行完成后,事件处理流程结束 ## 5. 监听器实现 ### 5.1 监听器创建步骤 1. **创建监听器类**:在 `app/listener/` 目录下创建相应的监听器类 2. **实现接口**:实现 `crmeb\interfaces\ListenerInterface` 接口 3. **编写处理逻辑**:在 `handle()` 方法中编写事件处理逻辑 4. **注册监听器**:在 `app/event.php` 文件中注册监听器 ### 5.2 监听器实现示例 #### 5.2.1 订单创建事件监听器 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` #### 5.2.2 用户注册事件监听器 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 6. 自定义事件 CRMEB 支持自定义事件,通过 `CustomEventListener` 实现灵活的业务扩展: ### 6.1 自定义事件触发 ```php // 触发自定义事件 event('CustomEventListener', ['event_mark', ['data1' => 'value1', 'data2' => 'value2']]); ``` ### 6.2 自定义事件处理 自定义事件由 `app\listener\CustomEventListener` 处理,该监听器从数据库中获取配置的自定义代码并执行: ```php make(SystemEventServices::class)->selectList(['mark' => $mark, 'is_del' => 0, 'is_open' => 1])->toArray(); foreach ($list as $item) { eval(json_decode($item['customCode'])); } } catch (\Throwable $e) { $listener_log_open = config("log.listener_log", false); if ($listener_log_open) { $date = date('Y-m-d H:i:s', time()); Log::write($date . '自定义事件错误:' . $e->getMessage(), 'listener'); } } } } ``` ### 6.3 自定义事件配置 自定义事件可以通过后台管理系统进行配置,在 "系统设置" -> "事件管理" 中添加和管理自定义事件。 ## 7. 最佳实践 ### 7.1 事件命名规范 - 事件名称应清晰表达事件的含义和触发时机,如 `OrderCreateAfterListener` 表示订单创建后的事件 - 使用驼峰命名法,首字母大写 ### 7.2 监听器设计原则 - **单一职责**:每个监听器应只负责处理一个特定的业务逻辑 - **无副作用**:监听器处理不应修改原始事件数据,避免影响其他监听器 - **异常处理**:在监听器中适当捕获异常,避免单个监听器失败影响整个事件处理流程 ### 7.3 性能优化 - **异步处理**:对于耗时的操作,建议使用队列进行异步处理,如发送短信、生成报表等 - **缓存使用**:合理使用缓存减少数据库查询,提高处理效率 - **避免循环依赖**:监听器之间不应相互依赖,避免形成循环调用 ## 8. 常见问题与解决方案 ### 8.1 事件不触发 **问题**:调用 `event()` 函数后,监听器未执行。 **解决方案**: - 检查事件名称是否与 `event.php` 中注册的名称一致 - 检查监听器类是否正确实现了 `ListenerInterface` 接口 - 检查监听器类是否正确注册到对应的事件中 ### 8.2 监听器执行顺序 **问题**:需要控制监听器的执行顺序。 **解决方案**: - 在 `event.php` 中,监听器的注册顺序决定了执行顺序 - 如需更复杂的控制,可以在监听器中手动触发其他事件 ### 8.3 事件数据传递 **问题**:监听器无法获取完整的事件数据。 **解决方案**: - 确保事件触发时传递了所有必要的数据 - 使用数组形式传递数据,便于扩展和维护 - 在监听器中对数据进行适当的验证和转换 ## 9. 代码优化建议 ### 9.1 监听器异常处理优化 **问题**:部分监听器可能缺少完善的异常处理机制,导致单个监听器失败影响整个事件处理流程。 **建议**:在监听器的 `handle()` 方法中添加 try-catch 块,捕获并记录异常,确保即使某个监听器失败,也不会影响其他监听器的执行。 ```php public function handle($event): void { try { // 监听器逻辑 } catch (\Exception $e) { // 记录异常日志 Log::error('Listener error: ' . $e->getMessage(), [ 'listener' => __CLASS__, 'event' => $event, 'trace' => $e->getTraceAsString() ]); // 可以根据需要添加其他处理逻辑 } } ``` ### 9.2 事件数据验证优化 **问题**:监听器对事件数据的依赖较强,但缺少对数据有效性的验证,可能导致运行时错误。 **建议**:在监听器中添加数据验证逻辑,确保接收到的数据符合预期格式和要求。 ```php public function handle($event): void { // 验证事件数据 if (!is_array($event) || count($event) < 4) { Log::warning('Invalid event data', [ 'listener' => __CLASS__, 'event' => $event ]); return; } [$order, $group, $uid, $key] = $event; // 验证必要参数 if (empty($order['id']) || empty($uid)) { Log::warning('Missing required parameters', [ 'listener' => __CLASS__, 'order_id' => $order['id'] ?? null, 'uid' => $uid ]); return; } // 监听器逻辑 } ``` ### 9.3 事件触发点优化 **问题**:事件触发点可能过于分散,导致难以追踪事件的触发位置和时机。 **建议**:建立事件触发点的文档或注释规范,明确记录每个事件的触发位置、时机和传递的数据结构,便于后续维护和扩展。 ```php /** * 创建订单 * @param array $data 订单数据 * @return array 订单信息 * @event OrderCreateAfterListener 订单创建后触发,传递参数:[$order, $group, $uid, $key, $combinationId, $seckillId, $bargainId] */ public function createOrder(array $data) { // 订单创建逻辑 // 触发事件 event('OrderCreateAfterListener', [$order, $group, $uid, $key, $combinationId, $seckillId, $bargainId]); return $order; } ``` ## 10. 输入输出示例 ### 10.1 触发订单创建事件 **输入**: ```php // 订单创建完成后触发事件 $order = [ 'id' => 1001, 'order_sn' => '2023120100001', 'uid' => 101, 'total_price' => 99.99, // 其他订单信息 ]; $group = [ // 订单商品组信息 ]; $uid = 101; $key = 'order_cache_key'; $combinationId = 0; $seckillId = 0; $bargainId = 0; // 触发事件 event('OrderCreateAfterListener', [$order, $group, $uid, $key, $combinationId, $seckillId, $bargainId]); ``` **输出**: ``` // 事件触发后,监听器执行以下操作: 1. 计算商品实际金额、佣金、优惠折扣 2. 设置默认地址 3. 清理购物车 4. 清除订单缓存 5. 写入订单记录表 6. 加入订单自动取消延迟队列 7. 记录下单行为 8. 触发小票打印 ``` ### 10.2 触发用户注册事件 **输入**: ```php // 用户注册完成后触发事件 $spreadUid = 201; // 推荐人ID $userType = 1; // 用户类型 $name = '张三'; // 用户名 $uid = 301; // 新用户ID $isNew = true; // 是否新用户 // 触发事件 event('UserRegisterListener', [$spreadUid, $userType, $name, $uid, $isNew]); ``` **输出**: ``` // 事件触发后,监听器执行以下操作: 1. 邀请新用户增加推荐人经验 2. 增加推荐人推广佣金 3. 处理分销等级升级 4. 记录推广绑定关系 5. 发送下级用户绑定成功通知 6. 发送新人优惠券 7. 开启推广权限(如果开启了人人分销) ``` ## 11. 总结 CRMEB 的事件系统提供了一种灵活、解耦的模块间通信机制,通过事件和监听器的配合,实现了业务逻辑的分离和扩展。合理使用事件系统可以: 1. **提高代码的可维护性**:将相关业务逻辑集中到监听器中,便于管理和维护 2. **增强系统的可扩展性**:通过事件机制,可以轻松添加新的业务逻辑,而无需修改原有代码 3. **降低模块间的耦合度**:模块间通过事件进行通信,而不是直接依赖,减少了模块间的耦合 4. **提高系统的响应速度**:对于耗时的操作,可以通过队列进行异步处理,提高系统的响应速度 在开发过程中,应遵循事件命名规范、监听器设计原则和性能优化建议,确保事件系统的高效运行。通过合理利用事件机制,可以大大提高代码质量和开发效率,为系统的长期维护和扩展奠定良好的基础。 --- ### Help/Dev Docs/Phpapi/系统安装流程文档 (help/dev-docs/phpapi/系统安装流程文档.md) # CRMEB 系统安装流程文档 ## 📋 文档概述 本文档提供CRMEB开源商城系统的完整安装流程,适用于CRMEB 5.6.4+版本。 ## 🖥️ 服务器环境要求 ### 基础配置要求 | 配置项 | 最低配置 | 推荐配置 | |--------|---------|---------| | CPU | 1核 | 2核及以上 | | 内存 | 1GB | 2GB及以上 | | 硬盘 | 20GB SSD | 50GB SSD及以上 | | 带宽 | 1Mbps | 5Mbps及以上 | ### 操作系统要求 | 系统类型 | 支持版本 | |---------|---------| | Linux | CentOS 7+/Ubuntu 18+/Debian 10+ | | Windows | Windows Server 2012+ | | macOS | 仅用于开发环境 | ### 软件环境要求 | 软件 | 最低版本 | 推荐版本 | 说明 | |------|---------|---------|------| | PHP | 7.1 | 7.4 | 必须开启PDO扩展 | | MySQL | 5.7 | 8.0 | 推荐InnoDB引擎 | | Redis | 3.0 | 7.0 | 可选,提升性能 | | Nginx | 1.18 | 1.22 | 反向代理服务器 | | Composer | 1.8 | 2.x | PHP依赖管理 | | Git | 2.0 | 最新版本 | 代码版本控制 | ### PHP扩展要求 ``` 必须开启的扩展: - fileinfo (文件信息) - pdo (数据库操作) - pdo_mysql (MySQL驱动) - openssl (加密处理) - mbstring (字符串处理) - curl (HTTP请求) - json (JSON处理) - session (会话管理) 推荐开启的扩展: - redis (Redis缓存) - gd (图片处理) - zip (压缩处理) - bcmath (高精度计算) ``` ### 禁用函数列表 ```php // php.ini 中需要取消禁用的函数 disable_functions = ; 移除以下函数: ; proc_open ; pcntl_signal ; pcntl_signal_dispatch ; pcntl_fork ; pcntl_wait ; pcntl_alarm ``` ## 🐳 方式一:Docker 一键部署(推荐) ### 1. 环境准备 ```bash # 检查Docker是否安装 docker --version # Docker version 20.10.x, build xxxxx # 检查Docker Compose docker-compose --version # Docker Compose version v2.x.x # 如未安装,请先安装Docker # Ubuntu系统安装: curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # 安装Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose ``` ### 2. 获取项目代码 ```bash # 克隆项目 git clone https://gitee.com/ZhongBangKeJi/CRMEB.git crmeb cd crmeb # 切换到稳定版本分支(根据需要选择) git checkout -b v5.6.4 origin/v5.6.4 ``` ### 3. 配置环境变量 ```bash # 复制环境变量模板 cp .env.example .env # 编辑环境变量 vim .env ``` ```ini # 数据库配置 DB_HOST=mysql DB_PORT=3306 DB_DATABASE=crmeb DB_USERNAME=root DB_PASSWORD=crmeb123456 # Redis配置 REDIS_HOST=redis REDIS_PORT=6379 REDIS_PASSWORD= # 应用配置 APP_DEBUG=true APP_URL=http://localhost # Admin后台配置 ADMIN_HTTPS=false ``` ### 4. 一键启动 ```bash # 构建并启动所有服务 docker-compose up -d --build # 查看服务状态 docker-compose ps # 输出示例: # Name Command State Ports # ---------------------------------------------------------------------- # crmeb-app docker-php-entrypoint apach ... Up 0.0.0.0:80->80/tcp # crmeb-mysql docker-entrypoint.sh mysqld ... Up 3306/tcp # crmeb-redis docker-entrypoint.sh redis ... Up 6379/tcp ``` ### 5. 访问安装向导 打开浏览器访问:`http://your-server-ip` 按照安装向导步骤完成系统安装: 1. 环境检测 2. 目录权限检查 3. 数据库配置 4. 管理员账号设置 5. 安装完成 ### Docker 管理命令 ```bash # 启动服务 docker-compose start # 停止服务 docker-compose stop # 重启服务 docker-compose restart # 查看日志 docker-compose logs -f # 删除服务(保留数据) docker-compose down # 删除服务(包含数据卷) docker-compose down -v ``` ## 🖥️ 方式二:手动部署(宝塔面板) ### 1. 安装宝塔面板 ```bash # CentOS系统 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh # Ubuntu/Debian系统 wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh ``` ### 2. 登录宝塔面板 安装完成后,记录面板登录地址、用户名和密码,登录宝塔面板。 ### 3. 安装环境套件 在宝塔面板中: 1. 点击「软件商店」 2. 安装以下软件: - Nginx 1.22 - MySQL 5.7/8.0 - PHP 7.4 - phpMyAdmin 4.7(可选,用于数据库管理) ### 4. 创建站点 1. 点击「网站」→「添加站点」 2. 填写站点信息: - 域名:`your-domain.com`(或IP用于测试) - 根目录:`/www/wwwroot/crmeb` - PHP版本:选择 7.4 - 数据库:选择创建数据库 - 数据库用户名和密码 - FTP:选择创建 ### 5. 上传项目代码 ```bash # 方法一:通过宝塔面板上传 # 1. 在本地下载项目源码 # 2. 通过宝塔文件管理上传并解压 # 方法二:通过命令行 cd /www/wwwroot wget https://gitee.com/ZhongBangKeJi/CRMEB/repository/archive/master.zip unzip master.zip mv CRMEB-master crmeb ``` ### 6. 配置目录权限 ```bash # 设置目录权限 chmod -R 755 /www/wwwroot/crmeb chmod -R 755 /www/wwwroot/crmeb/runtime chmod -R 755 /www/wwwroot/crmeb/public/uploads # 设置所有者 chown -R www:www /www/wwwroot/crmeb ``` ### 7. 配置伪静态 在宝塔面板中: 1. 点击对应站点的「设置」 2. 选择「伪静态」 3. 添加以下规则: ```nginx # ThinkPHP 伪静态规则 location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; break; } } # PHP配置 location ~ \.php$ { fastcgi_pass unix:/tmp/php-cgi-74.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } ``` ### 8. 配置PHP上传限制 在宝塔「软件商店」→「PHP 7.4」→「配置修改」中: - upload_max_filesize:100M - post_max_size:100M - max_execution_time:300 - max_input_time:300 - memory_limit:256M ### 9. 访问安装 打开浏览器访问:`http://your-domain.com` 按照安装向导完成系统安装。 ## 🖥️ 方式三:手动部署(命令行) ### 1. 安装PHP环境 ```bash # CentOS 7 yum install epel-release -y yum install -y yum-utils # 添加Remi源 yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm -y # 安装PHP 7.4 yum-config-manager --enable remi-php74 yum install -y php php-cli php-fpm php-mysql php-xml php-mbstring php-curl php-redis php-gd php-zip php-bcmath # 启动PHP-FPM systemctl start php-fpm systemctl enable php-fpm ``` ### 2. 安装Nginx ```bash # CentOS yum install -y nginx # 启动Nginx systemctl start nginx systemctl enable nginx ``` ### 3. 安装MySQL ```bash # CentOS 7 - 安装MySQL 5.7 wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm rpm -ivh mysql57-community-release-el7-9.noarch.rpm yum install -y mysql-community-server # 启动MySQL systemctl start mysqld systemctl enable mysqld # 查看初始密码 grep 'temporary password' /var/log/mysqld.log # 登录并修改密码 mysql -u root -p ``` ```sql -- MySQL 5.7 初始化 ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewPassword!'; -- 创建数据库 CREATE DATABASE crmeb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建用户并授权 CREATE USER 'crmeb'@'localhost' IDENTIFIED BY 'crmeb_password!'; GRANT ALL PRIVILEGES ON crmeb.* TO 'crmeb'@'localhost'; FLUSH PRIVILEGES; ``` ### 4. 安装Redis ```bash # CentOS yum install -y redis # 启动Redis systemctl start redis systemctl enable redis # 配置密码(编辑 /etc/redis.conf) requirepass your_redis_password ``` ### 5. 安装Composer ```bash # 下载安装 curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer # 切换中国镜像(加速下载) composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ ``` ### 6. 获取项目代码 ```bash # 克隆项目 cd /var/www git clone https://gitee.com/ZhongBangKeJi/CRMEB.git crmeb cd crmeb # 切换到稳定版本 git checkout -b v5.6.4 origin/v5.6.4 ``` ### 7. 配置环境变量 ```bash # 复制环境变量模板 cp .env.example .env # 编辑配置 vim .env ``` ```ini [APP] DEBUG = true DEFAULT_TIMEZONE = Asia/Shanghai [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = crmeb USERNAME = crmeb PASSWORD = crmeb_password! HOSTPORT = 3306 CHARSET = utf8mb4 DEBUG = true PREFIX = eb_ [CACHE] TYPE = redis HOST = 127.0.0.1 PORT = 6379 PREFIX = crmeb: [LANG] default_lang = zh-cn ``` ### 8. 安装依赖 ```bash # 切换到项目目录 cd /var/www/crmeb # 安装项目依赖 composer install --no-dev --optimize-autoloader ``` ### 9. 配置Nginx站点 ```bash # 创建站点配置 vim /etc/nginx/conf.d/crmeb.conf ``` ```nginx server { listen 80; server_name your-domain.com; root /var/www/crmeb/public; index index.php index.html; # 日志配置 access_log /var/log/nginx/crmeb_access.log; error_log /var/log/nginx/crmeb_error.log; # 静态文件缓存 location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ { expires 30d; add_header Cache-Control "public, immutable"; } # 主路由规则 location / { try_files $uri $uri/ /index.php?s=$uri&$args; } # PHP处理 location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 超时配置 fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; } # 禁止访问敏感文件 location ~ /\.(env|git|htaccess) { deny all; } } ``` ```bash # 测试配置 nginx -t # 重载Nginx nginx -s reload ``` ### 10. 配置目录权限 ```bash # 设置权限 chmod -R 755 /var/www/crmeb chmod -R 755 /var/www/crmeb/runtime chmod -R 755 /var/www/crmeb/public/uploads # 设置所有者 chown -R nginx:nginx /var/www/crmeb ``` ### 11. 启动消息队列(可选) ```bash # 使用Supervisor管理队列 yum install -y supervisor # 配置Supervisor vim /etc/supervisord.d/crmeb.ini ``` ```ini [program:crmeb-queue] command=php /var/www/crmeb/think queue:listen --queue directory=/var/www/crmeb user=nginx autostart=true autorestart=true stopasgroup=true killasgroup=true ``` ```bash # 启动Supervisor systemctl start supervisord systemctl enable supervisord # 启动队列任务 supervisorctl update supervisorctl start crmeb-queue ``` ### 12. 启动定时任务(可选) ```bash # 编辑定时任务 crontab -e # 添加以下任务 * * * * * cd /var/www/crmeb && php think timer start >> /dev/null 2>&1 ``` ### 13. 访问安装 打开浏览器访问:`http://your-domain.com` 按照安装向导完成系统安装。 ## 🔧 安装后配置 ### 1. 配置HTTPS(推荐) ```nginx server { listen 443 ssl http2; server_name your-domain.com; ssl_certificate /etc/nginx/ssl/crmeb.crt; ssl_certificate_key /etc/nginx/ssl/crmeb.key; ssl_session_timeout 5m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; # 其他配置同上... } # HTTP重定向到HTTPS server { listen 80; server_name your-domain.com; return 301 https://$server_name$request_uri; } ``` ### 2. 配置七牛云存储(可选) 在后台管理系统中: 1. 进入「系统设置」→「附件配置」 2. 选择「七牛云存储」 3. 配置以下参数: - AccessKey - SecretKey - Bucket(存储空间名称) - Domain(访问域名) ### 3. 配置短信服务(可选) 在后台管理系统中: 1. 进入「系统设置」→「短信设置」 2. 选择短信服务商(阿里云、腾讯云等) 3. 配置API密钥和签名 ## 🧪 常见问题处理 ### 问题1:页面显示500错误 ```bash # 检查PHP错误日志 tail -f /var/log/php-fpm/error.log # 检查Nginx错误日志 tail -f /var/log/nginx/crmeb_error.log # 检查项目runtime日志 tail -f /var/www/crmeb/runtime/log/xxx.log ``` ### 问题2:数据库连接失败 ```bash # 测试MySQL连接 mysql -h localhost -u crmeb -p # 检查数据库配置 cat /var/www/crmeb/.env | grep DB_ ``` ### 问题3:验证码不显示 ```bash # 检查PHP GD扩展 php -m | grep gd # 检查目录权限 ls -la /var/www/crmeb/runtime/ ``` ### 问题4:上传文件失败 ```bash # 检查upload目录权限 chmod -R 755 /var/www/crmeb/public/uploads chown -R nginx:nginx /var/www/crmeb/public/uploads # 检查PHP配置 php -i | grep file_uploads php -i | grep upload_max_filesize ``` ### 问题5:微信支付回调失败 ```bash # 检查防火墙 systemctl status firewalld iptables -L -n | grep 80 # 检查域名配置 # 确保回调域名已备案且可访问 ``` ## 🔐 安全加固建议 ### 1. 修改默认后台路径 ```bash # 重命名admin目录 mv public/admin public/backend # 修改路由配置 vim config/route.php ``` ### 2. 配置安全密钥 ```bash # 在.env中配置 APP_KEY=your_random_string_32_chars ``` ### 3. 定期更新系统 ```bash # 定期更新CRMEB cd /var/www/crmeb git fetch origin git pull origin v5.6.4 # 更新依赖 composer update ``` ## 📞 获取技术支持 - **官方文档**:https://doc.crmeb.com/ - **技术社区**:https://www.crmeb.com/ask/ - **Gitee Issues**:https://gitee.com/ZhongBangKeJi/CRMEB/issues --- **文档版本**: v1.0 **更新日期**: 2024-01-17 **适用版本**: CRMEB 5.6.4+ 💡 提示:建议生产环境使用HTTPS协议,定期备份数据库和文件。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/系统错误码说明 (help/dev-docs/phpapi/系统错误码说明.md) # 系统错误码说明 ## 📋 错误码规范 ### 总体规范 - **格式**: 3位数字错误码 + 错误信息 - **分类**: 按照模块和错误类型分类 - **统一响应**: 所有错误都通过统一异常处理返回 ### 响应格式 ```json { "status": 400, "msg": "参数错误", "data": null, "time": "2024-01-17 15:30:00" } ``` ## 🔢 错误码分类 | 错误码范围 | 错误类型 | 说明 | |-----------|---------|------| | 200 | 成功 | 请求成功 | | 400-499 | 客户端错误 | 参数错误、权限不足等 | | 500-599 | 服务器错误 | 系统异常、数据库错误等 | | 1000-1999 | 用户相关错误 | 登录、注册、用户信息等 | | 2000-2999 | 订单相关错误 | 订单创建、支付、售后等 | | 3000-3999 | 商品相关错误 | 商品信息、库存、分类等 | | 4000-4999 | 营销相关错误 | 优惠券、活动、积分等 | | 5000-5999 | 支付相关错误 | 支付处理、退款等 | | 6000-6999 | 第三方服务错误 | 微信、短信、物流等 | ## 📊 通用错误码 ### 成功状态 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 200 | success | 请求成功 | ### 系统级错误 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 400 | 参数错误 | 请求参数不符合要求 | | 401 | 未授权 | 用户未登录或Token无效 | | 403 | 权限不足 | 用户没有操作权限 | | 404 | 资源不存在 | 请求的资源不存在 | | 405 | 方法不允许 | 请求方法不正确 | | 408 | 请求超时 | 请求处理超时 | | 429 | 请求过于频繁 | 请求频率超过限制 | | 500 | 服务器内部错误 | 服务器处理异常 | | 501 | 功能未实现 | 请求的功能暂未实现 | | 502 | 网关错误 | 上游服务不可用 | | 503 | 服务不可用 | 服务暂时不可用 | | 504 | 网关超时 | 上游服务响应超时 | ## 👥 用户相关错误码 (1000-1999) ### 认证相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 1001 | 用户名或密码错误 | 登录认证失败 | | 1002 | 验证码错误 | 图形验证码或短信验证码错误 | | 1003 | 验证码已过期 | 验证码超过有效时间 | | 1004 | 账号已被禁用 | 用户账号被管理员禁用 | | 1005 | 账号未激活 | 用户账号未完成激活流程 | | 1006 | Token已过期 | JWT Token超过有效期 | | 1007 | Token无效 | JWT Token格式错误或已失效 | | 1008 | 登录状态异常 | 登录状态检查失败 | ### 注册相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 1101 | 手机号已注册 | 手机号已经被其他用户注册 | | 1102 | 邮箱已注册 | 邮箱已经被其他用户注册 | | 1103 | 用户名已存在 | 用户名已经被其他用户使用 | | 1104 | 邀请码无效 | 注册时使用的邀请码无效 | | 1105 | 注册信息不完整 | 注册必填信息缺失 | ### 用户信息相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 1201 | 用户不存在 | 指定的用户ID不存在 | | 1202 | 用户信息更新失败 | 更新用户信息时发生错误 | | 1203 | 原密码错误 | 修改密码时原密码验证失败 | | 1204 | 手机号格式错误 | 手机号格式不符合要求 | | 1205 | 邮箱格式错误 | 邮箱格式不符合要求 | | 1206 | 实名认证失败 | 实名认证信息验证失败 | ## 🛒 订单相关错误码 (2000-2999) ### 订单创建 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 2001 | 商品库存不足 | 下单时商品库存不足 | | 2002 | 商品已下架 | 下单时商品已下架 | | 2003 | 收货地址无效 | 选择的收货地址不可用 | | 2004 | 优惠券不可用 | 选择的优惠券不符合使用条件 | | 2005 | 积分不足 | 积分支付时积分余额不足 | | 2006 | 余额不足 | 余额支付时余额不足 | | 2007 | 订单金额计算错误 | 订单金额计算异常 | ### 订单支付 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 2101 | 支付方式不支持 | 选择的支付方式不可用 | | 2102 | 支付密码错误 | 余额支付时支付密码错误 | | 2103 | 支付超时 | 支付操作超时 | | 2104 | 支付金额不匹配 | 支付金额与订单金额不一致 | | 2105 | 支付状态异常 | 支付状态不符合预期 | ### 订单操作 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 2201 | 订单状态不允许操作 | 当前订单状态不支持该操作 | | 2202 | 订单不存在 | 指定的订单ID不存在 | | 2203 | 订单取消失败 | 取消订单时发生错误 | | 2204 | 订单删除失败 | 删除订单时发生错误 | | 2205 | 订单确认收货失败 | 确认收货操作失败 | ### 售后相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 2301 | 申请售后时间已过 | 超过可申请售后的时间限制 | | 2302 | 售后申请重复提交 | 同一订单重复提交售后申请 | | 2303 | 退款金额超过限制 | 退款金额超过可退款金额 | | 2304 | 售后状态不允许操作 | 当前售后状态不支持该操作 | | 2305 | 退货物流信息错误 | 退货物流单号或公司错误 | ## 🏪 商品相关错误码 (3000-3999) ### 商品信息 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 3001 | 商品不存在 | 指定的商品ID不存在 | | 3002 | 商品已删除 | 商品已被逻辑删除 | | 3003 | 商品分类不存在 | 指定的分类ID不存在 | | 3004 | 商品规格无效 | 商品规格选择错误 | | 3005 | 商品属性错误 | 商品属性信息错误 | ### 库存相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 3101 | 库存扣减失败 | 扣减商品库存时发生错误 | | 3102 | 库存回滚失败 | 回滚商品库存时发生错误 | | 3103 | 库存锁定失败 | 锁定商品库存时发生错误 | | 3104 | 库存不足 | 操作时商品库存不足 | ### 购物车相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 3201 | 购物车商品不存在 | 购物车中商品不存在 | | 3202 | 购物车商品数量超限 | 商品数量超过购买限制 | | 3203 | 购物车操作失败 | 购物车添加、删除操作失败 | ## 🎯 营销相关错误码 (4000-4999) ### 优惠券相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 4001 | 优惠券不存在 | 指定的优惠券不存在 | | 4002 | 优惠券已领完 | 优惠券已被领取完毕 | | 4003 | 优惠券领取超限 | 超过单人领取数量限制 | | 4004 | 优惠券已过期 | 优惠券已超过有效期 | | 4005 | 优惠券使用条件不满足 | 不符合优惠券使用条件 | | 4006 | 优惠券状态异常 | 优惠券状态不可用 | ### 活动相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 4101 | 活动不存在 | 指定的活动不存在 | | 4102 | 活动未开始 | 活动尚未开始 | | 4103 | 活动已结束 | 活动已经结束 | | 4104 | 活动参与人数已满 | 活动参与人数达到上限 | | 4105 | 活动资格不足 | 不符合活动参与条件 | ### 积分相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 4201 | 积分不足 | 积分余额不足 | | 4202 | 积分操作失败 | 积分增减操作失败 | | 4203 | 积分规则不存在 | 积分规则配置错误 | ## 💳 支付相关错误码 (5000-5999) ### 支付处理 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 5001 | 支付渠道不可用 | 支付渠道配置错误或不可用 | | 5002 | 支付签名错误 | 支付签名验证失败 | | 5003 | 支付回调验证失败 | 支付回调数据验证失败 | | 5004 | 支付订单不存在 | 支付订单记录不存在 | | 5005 | 支付金额错误 | 支付金额异常 | ### 退款相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 5101 | 退款申请失败 | 退款申请操作失败 | | 5102 | 退款金额错误 | 退款金额超过可退款金额 | | 5103 | 退款状态异常 | 退款状态不符合预期 | | 5104 | 退款凭证错误 | 退款凭证信息错误 | ## 🌐 第三方服务错误码 (6000-6999) ### 微信相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 6001 | 微信授权失败 | 微信授权登录失败 | | 6002 | 微信支付失败 | 微信支付操作失败 | | 6003 | 微信模板消息发送失败 | 模板消息发送失败 | | 6004 | 微信公众号配置错误 | 公众号配置信息错误 | ### 短信相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 6101 | 短信发送失败 | 短信发送接口调用失败 | | 6102 | 短信模板不存在 | 短信模板配置错误 | | 6103 | 短信验证码失效 | 短信验证码验证失败 | ### 物流相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 6201 | 物流查询失败 | 物流信息查询失败 | | 6202 | 物流公司不支持 | 不支持的物流公司 | | 6203 | 物流单号错误 | 物流单号格式错误 | ### 文件存储相关 | 错误码 | 错误信息 | 说明 | |--------|---------|------| | 6301 | 文件上传失败 | 文件上传到服务器失败 | | 6302 | 文件格式不支持 | 不支持的文件格式 | | 6303 | 文件大小超限 | 文件大小超过限制 | | 6304 | 云存储配置错误 | 云存储服务配置错误 | ## 🛠️ 错误处理最佳实践 ### 控制器层处理 ```php try { // 业务逻辑处理 $result = $service->doSomething($params); return $this->success($result); } catch (ApiException $e) { // 捕获业务异常 return $this->fail($e->getMessage(), $e->getCode()); } catch (\Exception $e) { // 捕获系统异常 Log::error('系统异常: ' . $e->getMessage()); return $this->fail('系统繁忙,请稍后重试', 500); } ``` ### 服务层抛出异常 ```php // 业务验证失败时抛出异常 if (!$user) { throw new ApiException('用户不存在', 1201); } if ($stock < $quantity) { throw new ApiException('商品库存不足', 2001); } ``` ### 自定义异常类 ```php class ApiException extends \Exception { public function __construct($message = "", $code = 400, \Throwable $previous = null) { parent::__construct($message, $code, $previous); } } class AdminException extends ApiException { // 管理端专用异常 } ``` ## 📝 错误码维护规范 ### 新增错误码 1. 选择合适的错误码范围 2. 在本文档中记录错误码和说明 3. 在对应的异常处理中添加错误码映射 ### 错误码使用原则 1. **唯一性**: 每个错误码对应唯一的错误场景 2. **可读性**: 错误信息清晰明确,便于理解 3. **一致性**: 相同类型的错误使用相同的错误码范围 4. **扩展性**: 为后续功能扩展预留错误码空间 ## 🔍 错误排查指南 ### 常见错误排查步骤 1. **确认错误码**: 根据返回的错误码定位问题类别 2. **查看日志**: 检查相关业务逻辑的日志记录 3. **验证参数**: 检查请求参数是否符合要求 4. **检查状态**: 确认相关数据的状态是否正常 5. **测试环境**: 在测试环境复现问题并调试 ### 日志记录规范 ```php // 记录错误日志 Log::error('错误信息', [ 'error_code' => $errorCode, 'params' => $requestParams, 'user_id' => $userId, 'trace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5) ]); ``` --- **最后更新**: 2024-01-17 **维护人员**: 开发团队 **文档版本**: v1.0 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/系统队列任务开发文档 (help/dev-docs/phpapi/系统队列任务开发文档.md) # 系统队列任务开发文档 ## 1. 队列机制概述 CRMEB系统采用基于ThinkPHP Queue的队列任务机制,用于处理耗时操作,提高系统响应速度和并发能力。队列任务支持异步执行、延迟执行、失败重试等功能,适用于订单处理、消息推送、数据分析等场景。 ### 1.1 核心组件 - **任务接口**:`JobInterface` - 定义任务执行的标准接口 - **任务基类**:`BaseJobs` - 提供任务执行的基础实现 - **队列工具**:`Queue` - 提供队列任务的创建和管理功能 - **队列特性**:`QueueTrait` - 提供快捷的队列调度方法 - **配置文件**:`queue.php` - 配置队列的驱动和参数 ## 2. 队列配置 ### 2.1 配置文件 队列配置文件位于 `/crmeb/config/queue.php`,主要配置项包括: ```php return [ // 默认队列驱动 'default' => 'redis', // 队列连接方式配置 'connections' => [ 'sync' => [ 'type' => 'sync', ], 'database' => [ 'type' => 'database', 'queue' => 'default', 'table' => 'jobs', 'connection' => null, ], 'redis' => [ 'type' => 'redis', 'queue' => 'default', 'host' => env('redis.host', '127.0.0.1'), 'port' => env('redis.port', 6379), 'password' => env('redis.password', ''), 'select' => env('redis.select', 0), 'timeout' => 0, 'persistent' => false, ], ], // 失败队列配置 'failed' => [ 'type' => 'none', 'table' => 'failed_jobs', ], ]; ``` ### 2.2 配置说明 - **default**:默认队列驱动,支持sync(同步)、database(数据库)、redis(Redis) - **connections**:队列连接配置,可配置多种队列驱动 - **failed**:失败队列配置,用于存储执行失败的任务 ## 3. 任务接口定义 ### 3.1 JobInterface 任务接口定义了队列任务的标准执行方法: ```php namespace crmeb\interfaces; use think\queue\Job; interface JobInterface { public function fire(Job $job, $data): void; } ``` - **fire**:任务执行的入口方法,接收Job对象和任务数据 ## 4. 任务基类 ### 4.1 BaseJobs 任务基类实现了`JobInterface`接口,提供了任务执行的基础逻辑: ```php namespace crmeb\basic; use crmeb\interfaces\JobInterface; use think\queue\Job; use think\facade\Log; abstract class BaseJobs implements JobInterface { /** * @param Job $job * @param $data */ public function fire(Job $job, $data): void { try { $method = $data['method'] ?? 'doJob'; if (method_exists($this, $method)) { if (!isset($data['data'])) { $res = $this->{$method}(); } else { $res = $this->{$method}(...$data['data']); } if ($res) { $job->delete(); } else { if ($job->attempts() > 3) { $job->delete(); } else { $job->release(); } } } else { $job->delete(); } } catch (\Throwable $e) { Log::error('队列任务执行失败:' . $e->getMessage()); if ($job->attempts() > 3) { $job->delete(); } else { $job->release(); } } } } ``` - **fire**:实现JobInterface接口的方法,处理任务执行、错误捕获和失败重试 - **doJob**:默认的任务执行方法,子类可以重写 ## 5. 队列工具类 ### 5.1 Queue 队列工具类提供了链式调用的方式来创建和管理队列任务: ```php namespace crmeb\utils; use think\facade\Config; use think\facade\Queue as QueueThink; use think\facade\Log; class Queue { // 任务执行方法 protected $do = 'doJob'; // 任务类名 protected $job; // 错误次数 protected $errorCount = 3; // 数据 protected $data; // 队列名 protected $queueName = null; // 延迟执行秒数 protected $secs = 0; // ... 其他方法 } ``` ### 5.2 QueueTrait 队列特性提供了快捷的队列调度方法: ```php namespace crmeb\traits; trait QueueTrait { /** * 加入队列 * @param string $queueName * @param array $data * @return bool */ public static function dispatch(string $queueName = null, ...$data) { $class = get_called_class(); return Queue::instance()->job($class)->data($data)->queue($queueName)->push(); } /** * 延迟加入队列 * @param int $secs * @param string|null $queueName * @param array $data * @return bool */ public static function dispatchSecs(int $secs, string $queueName = null, ...$data) { $class = get_called_class(); return Queue::instance()->job($class)->data($data)->secs($secs)->queue($queueName)->push(); } } ``` ## 6. 创建队列任务 ### 6.1 任务创建步骤 1. 创建任务类,继承`BaseJobs` 2. 实现`doJob`方法或自定义方法 3. 使用`QueueTrait`提供的快捷方法调度任务 ### 6.2 任务示例 ```php namespace app\jobs; use crmeb\basic\BaseJobs; use crmeb\traits\QueueTrait; use think\facade\Log; class OrderCreateAfterJob extends BaseJobs { use QueueTrait; /** * 订单后置处理 * @param $orderInfo * @param $data * @param $activity * @return bool */ public function doJob($orderInfo, $data, $activity) { try { // 处理订单逻辑 // ... return true; } catch (\Throwable $e) { Log::error('订单后置处理失败:' . $e->getMessage()); return false; } } } ``` ## 7. 调度队列任务 ### 7.1 基本调度 使用`QueueTrait`提供的`dispatch`方法调度任务: ```php // 调度订单后置处理任务 OrderCreateAfterJob::dispatch(null, $orderInfo, $data, $activity); ``` ### 7.2 延迟调度 使用`QueueTrait`提供的`dispatchSecs`方法延迟调度任务: ```php // 延迟10秒执行订单后置处理任务 OrderCreateAfterJob::dispatchSecs(10, null, $orderInfo, $data, $activity); ``` ### 7.3 使用Queue工具调度 使用`Queue`工具类进行更灵活的调度: ```php use crmeb\utils\Queue; // 创建并调度任务 Queue::instance() ->job(OrderCreateAfterJob::class) ->data($orderInfo, $data, $activity) ->secs(10) ->queue('order') ->push(); ``` ## 8. 任务执行流程 1. **任务调度**:通过`dispatch`或`Queue`工具将任务加入队列 2. **任务消费**:队列消费者进程从队列中获取任务 3. **任务执行**:调用任务类的`fire`方法执行任务 4. **结果处理**: - 执行成功:删除任务 - 执行失败:根据重试次数决定是否重新执行 - 重试超限:将任务移至失败队列(如果配置) ## 9. 队列管理 ### 9.1 启动队列消费者 使用ThinkPHP的命令行工具启动队列消费者: ```bash # 启动默认队列的消费者 php think queue:listen # 启动指定队列的消费者 php think queue:listen --queue order # 启动守护进程模式的消费者 php think queue:work --daemon ``` ### 9.2 查看队列状态 ```bash # 查看队列任务数 php think queue:status # 查看失败任务 php think queue:failed # 重试失败任务 php think queue:retry all # 删除失败任务 php think queue:flush ``` ## 10. 最佳实践 ### 10.1 任务设计原则 - **单一职责**:每个任务只负责一个功能 - **幂等性**:任务重复执行不会产生副作用 - **数据完整性**:确保任务执行所需的数据完整 - **错误处理**:妥善处理任务执行中的异常 ### 10.2 性能优化 - 合理设置失败重试次数,避免无限重试 - 对耗时任务进行拆分,提高并发处理能力 - 使用合适的队列驱动,Redis适用于高并发场景 - 定期清理失败队列,避免数据堆积 ### 10.3 监控与日志 - 记录任务执行日志,便于问题排查 - 监控队列长度,及时发现处理瓶颈 - 设置告警机制,当队列任务堆积时及时通知 ## 11. 常见问题 ### 11.1 任务执行失败 - 检查任务数据是否完整 - 检查任务依赖的服务是否可用 - 查看日志文件,定位错误原因 - 检查队列驱动是否正常工作 ### 11.2 队列任务堆积 - 增加队列消费者进程数量 - 优化任务执行逻辑,减少执行时间 - 检查队列驱动的性能瓶颈 - 考虑使用更高效的队列驱动 ### 11.3 延迟任务不执行 - 检查队列消费者是否正常运行 - 检查延迟时间设置是否正确 - 检查队列驱动是否支持延迟任务 - 查看队列日志,定位问题原因 ## 12. 内置任务列表 CRMEB系统内置了多个队列任务,用于处理各种业务场景: | 任务类名 | 功能描述 | |---------|---------| | OrderCreateAfterJob | 订单创建后置处理 | | PinkJob | 拼团任务处理 | | MiniOrderJob | 小程序订单处理 | | StoreOrderStatusJob | 订单状态处理 | | UserBrokerageJob | 用户佣金处理 | | StoreProductStockJob | 商品库存处理 | | StoreOrderRefundJob | 订单退款处理 | | StoreOrderSendJob | 订单发货处理 | | StoreOrderTakeJob | 订单收货处理 | | StoreOrderPayJob | 订单支付处理 | ## 13. 总结 CRMEB系统的队列任务机制提供了强大的异步处理能力,通过合理使用队列任务,可以提高系统的响应速度和并发能力,改善用户体验。开发人员可以根据业务需求创建自定义队列任务,实现各种异步处理逻辑。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/系统队列任务文档说明 (help/dev-docs/phpapi/系统队列任务文档说明.md) # CRMEB 系统队列任务文档说明 ## 概述 CRMEB 系统采用基于 Redis 的消息队列机制,通过 ThinkPHP 框架的队列组件实现异步任务处理。队列系统在提高系统性能、优化用户体验、保证数据一致性方面发挥着重要作用。 ## 队列系统架构 ### 1. 技术栈 - **队列驱动**: Redis (主) + Database (备) + Sync (同步) - **队列服务**: ThinkPHP Queue - **定时任务**: Workerman + Crontab - **任务调度**: 基于事件的异步处理 ### 2. 核心组件 #### 2.1 队列配置 (config/queue.php) ```php return [ 'default' => 'redis', // 默认驱动 'prefix' => 'crmeb_', // 队列前缀 'connections' => [ 'redis' => [ 'driver' => 'redis', 'queue' => 'CRMEB', // 队列名称 'host' => '127.0.0.1', 'port' => 6379, 'password' => '', 'select' => 0, ], ], 'failed' => [ 'type' => 'database', 'table' => 'failed_jobs', // 失败任务表 ], ]; ``` #### 2.2 基础任务类 (BaseJobs) ```php abstract class BaseJobs implements JobInterface { // 任务执行入口 public function fire(Job $job, $data): void // 任务重试机制 protected function runJob(string $action, Job $job, array $infoData, int $errorCount = 3) } ``` #### 2.3 队列特性 (QueueTrait) ```php trait QueueTrait { // 立即推送任务 public static function dispatch($action, array $data = [], string $queueName = null) // 延迟推送任务 public static function dispatchSecs(int $secs, $action, array $data = [], string $queueName = null) } ``` ## 队列任务分类 ### 1. 订单相关任务 #### 1.1 OrderJob - 订单处理任务 **功能**: 订单支付成功后的后续处理 **触发时机**: 订单支付成功时 **主要处理**: - 计算商品节省金额 - 更新用户支付订单数量 - 检测并设置推广人身份 - 添加用户购买标签 - 发送客服通知消息 - 检测会员等级升级 - 向后台发送新订单消息 ```php // 使用示例 OrderJob::dispatch('doJob', [$orderInfo]); ``` #### 1.2 OrderCreateAfterJob - 订单创建后处理 **功能**: 订单创建后的数据处理 **触发时机**: 订单创建完成后 **主要处理**: - 计算订单实际价格 - 处理推广关系 - 计算佣金分配 - 更新订单附加信息 #### 1.3 UnpaidOrderCancelJob - 未支付订单取消 **功能**: 自动取消超时未支付订单 **触发时机**: 定时任务或延迟队列 **处理逻辑**: - 检查订单支付状态 - 回退积分和优惠券 - 恢复商品库存 - 标记订单为已取消 ```php // 延迟30分钟后执行 UnpaidOrderCancelJob::dispatchSecs(1800, 'doJob', [$orderId]); ``` ### 2. 商品相关任务 #### 2.1 ProductLogJob - 商品日志记录 **功能**: 记录商品相关行为日志 **触发时机**: 商品浏览、加购、下单等 **日志类型**: - `visit`: 商品访问 - `cart`: 加入购物车 - `order`: 下单 - `pay`: 支付 - `collect`: 收藏 - `refund`: 退款 ```php ProductLogJob::dispatch('doJob', ['visit', $productData]); ``` #### 2.2 ProductStockJob - 商品库存处理 **功能**: 商品库存计算和更新 **触发时机**: 商品操作后 **处理功能**: - 分布式库存计算 - 规格库存汇总 - 库存同步更新 #### 2.3 ProductCopyJob - 商品复制任务 **功能**: 异步复制商品信息 **触发时机**: 商品复制操作 **处理内容**: - 商品基本信息复制 - 规格属性复制 - 图片资源复制 ### 3. 通知相关任务 #### 3.1 SmsJob - 短信发送任务 **功能**: 异步发送短信通知 **触发时机**: 各种业务事件 **支持场景**: - 订单通知 - 支付提醒 - 注册验证 - 营销推广 ```php SmsJob::dispatch('doJob', [$phone, $data, $template]); ``` #### 3.2 TemplateJob - 模板消息任务 **功能**: 发送微信模板消息 **触发时机**: 业务状态变更 **消息类型**: - 订单状态通知 - 支付成功通知 - 物流更新通知 #### 3.3 SyncMessageJob - 消息同步任务 **功能**: 多端消息同步 **触发时机**: 消息发送时 **同步范围**: - 客服系统 - 管理后台 - 用户端 ### 4. 营销相关任务 #### 4.1 PinkJob - 拼团任务 **功能**: 拼团活动处理 **触发时机**: 拼团相关操作 **处理内容**: - 拼团状态更新 - 拼团失败处理 - 拼团成功通知 #### 4.2 LiveJob - 直播任务 **功能**: 直播相关处理 **触发时机**: 直播事件 **处理内容**: - 直播状态同步 - 商品上下架 - 观众数据统计 #### 4.3 AutoCommentJob - 自动评论任务 **功能**: 自动生成商品评论 **触发时机**: 订单完成后 **处理逻辑**: - 根据商品信息生成评论 - 模拟用户评价 - 提升商品活跃度 ### 5. 系统维护任务 #### 5.1 TaskJob - 定时任务 **功能**: 系统定时维护 **执行频率**: 每日定时 **维护内容**: - 清理过期文件 - 数据统计汇总 - 系统健康检查 ```php // 清理昨日海报 TaskJob::dispatch('emptyYesterdayAttachment'); ``` #### 5.2 UpgradeJob - 系统升级任务 **功能**: 系统升级处理 **触发时机**: 手动触发或定时 **处理内容**: - 数据库结构更新 - 配置文件升级 - 兼容性检查 #### 5.3 CheckQueueJob - 队列检查任务 **功能**: 监控队列健康状态 **执行频率**: 定时检查 **检查项目**: - 队列堆积情况 - 失败任务统计 - 系统资源使用 ### 6. 用户相关任务 #### 6.1 UserJob - 用户处理任务 **功能**: 用户相关异步处理 **触发时机**: 用户操作 **处理内容**: - 用户等级计算 - 积分统计分析 - 行为数据更新 #### 6.2 AgentJob - 代理任务 **功能**: 代理商相关处理 **触发时机**: 代理业务 **处理内容**: - 佣金计算 - 等级升级 - 数据统计 ### 7. 物流相关任务 #### 7.1 OrderExpressJob - 订单物流任务 **功能**: 物流信息处理 **触发时机**: 物流状态变更 **处理内容**: - 物流信息同步 - 状态更新通知 - 异常情况处理 #### 7.2 TakeOrderJob - 订单接收任务 **功能**: 订单接收处理 **触发时机**: 订单创建 **处理内容**: - 订单数据验证 - 库存检查 - 自动分配 ### 8. 财务相关任务 #### 8.1 OrderInvoiceJob - 订单发票任务 **功能**: 发票处理 **触发时机**: 发票申请 **处理内容**: - 发票生成 - 状态同步 - 通知发送 #### 8.2 OutPushJob - 外部推送任务 **功能**: 数据外部推送 **触发时机**: 数据变更 **推送内容**: - 订单数据 - 用户数据 - 商品数据 ## 定时任务系统 ### 1. Timer 命令 基于 Workerman 实现的定时任务调度器 ```bash # 启动定时任务 php think timer start # 守护进程方式启动 php think timer start -d # 停止定时任务 php think timer stop # 重启定时任务 php think timer reload ``` ### 2. 系统定时任务 数据库表: `system_crontab` **字段说明**: - `name`: 任务名称 - `task_type`: 任务类型 - `mark`: 任务标识 - `content`: 任务内容 - `max_execution_time`: 最大执行时间 - `execution_cycle`: 执行周期 - `is_open`: 是否开启 - `next_execution_time`: 下次执行时间 - `last_execution_time`: 上次执行时间 ### 3. 内置定时任务 #### 3.1 订单相关 - **未支付订单取消**: 每分钟检查一次 - **预售商品下架**: 每小时检查一次 - **拼团失败处理**: 每5分钟检查一次 #### 3.2 数据统计 - **日统计汇总**: 每日凌晨执行 - **用户行为分析**: 每小时执行 - **销售数据统计**: 每日执行 #### 3.3 系统维护 - **日志清理**: 每周执行 - **临时文件清理**: 每日执行 - **缓存刷新**: 定时执行 ## 队列监控与管理 ### 1. 队列状态监控 ```php // 检查队列状态 Queue::instance()->getQueueInfo(); // 获取队列长度 Queue::instance()->getQueueLength(); // 获取失败任务 Queue::instance()->getFailedJobs(); ``` ### 2. 任务管理 ```php // 重新执行失败任务 Queue::instance()->retryFailed($jobId); // 清空队列 Queue::instance()->clearQueue($queueName); // 暂停队列 Queue::instance()->pauseQueue($queueName); ``` ### 3. 日志记录 所有队列任务都有详细的日志记录: - 成功执行日志 - 失败重试日志 - 异常堆栈信息 - 性能执行统计 ## 队列配置最佳实践 ### 1. 队列分组 根据业务重要性分组: ```php // 高优先级队列 'order_pay' => 'CRMEB_ORDER_PAY' 'sms' => 'CRMEB_SMS' 'email' => 'CRMEB_EMAIL' // 普通优先级队列 'statistics' => 'CRMEB_STATISTICS' 'log' => 'CRMEB_LOG' // 低优先级队列 'report' => 'CRMEB_REPORT' 'cleanup' => 'CRMEB_CLEANUP' ``` ### 2. 重试策略 ```php // 不同任务的重试次数 'order_pay' => 3 // 支付任务重试3次 'sms' => 5 // 短信任务重试5次 'email' => 3 // 邮件任务重试3次 'statistics' => 1 // 统计任务重试1次 ``` ### 3. 延迟设置 ```php // 常见延迟时间 UnpaidOrderCancelJob::dispatchSecs(1800, 'doJob', [$orderId]); // 30分钟 OrderRemindJob::dispatchSecs(86400, 'doJob', [$orderId]); // 24小时 CleanupJob::dispatchSecs(604800, 'doJob', [$data]); // 7天 ``` ## 性能优化建议 ### 1. 队列优化 - 使用 Redis 集群提高可用性 - 合理设置队列数量避免热点 - 定期清理过期队列数据 - 监控队列长度及时扩容 ### 2. 任务优化 - 避免单个任务过于复杂 - 合理拆分大任务为小任务 - 使用事务保证数据一致性 - 添加超时控制避免阻塞 ### 3. 资源优化 - 控制并发任务数量 - 合理设置内存限制 - 优化数据库查询性能 - 使用连接池减少开销 ## 故障处理 ### 1. 常见问题 #### 1.1 队列堆积 **现象**: 队列长度持续增长 **原因**: 消费速度小于生产速度 **解决**: - 增加消费者进程数 - 优化任务执行效率 - 检查系统资源使用 #### 1.2 任务重复执行 **现象**: 同一任务被执行多次 **原因**: 任务重复入队或幂等性问题 **解决**: - 添加任务唯一标识 - 实现幂等性检查 - 优化任务重试逻辑 #### 1.3 内存泄漏 **现象**: 进程内存持续增长 **原因**: 任务中存在资源未释放 **解决**: - 检查对象引用 - 及时释放大对象 - 定期重启消费者进程 ### 2. 应急处理 #### 2.1 队列暂停 ```bash # 暂停所有队列 php think queue:pause # 暂停指定队列 php think queue:pause --queue=order_pay ``` #### 2.2 强制清空 ```bash # 清空指定队列 php think queue:clear --queue=statistics # 清空所有队列 php think queue:clear --all ``` #### 2.3 重建队列 ```bash # 重建队列表 php think queue:table # 重新发布失败任务 php think queue:retry all ``` ## 开发指南 ### 1. 创建新任务 #### 1.1 创建任务类 ```php processData($data); return true; } catch (\Exception $e) { // 记录错误日志 Log::error('任务执行失败: ' . $e->getMessage()); return false; } } private function processData(array $data): void { // 具体业务逻辑 } } ``` #### 1.2 调度任务 ```php // 立即执行 CustomJob::dispatch('doJob', [$data]); // 延迟执行 CustomJob::dispatchSecs(300, 'doJob', [$data]); // 指定队列 CustomJob::dispatch('doJob', [$data], 'custom_queue'); ``` ### 2. 测试队列任务 #### 2.1 单元测试 ```php public function testCustomJob() { $job = new CustomJob(); $result = $job->doJob($testData); $this->assertTrue($result); } ``` #### 2.2 集成测试 ```php public function testQueueDispatch() { // 模拟队列调度 Queue::fake(); CustomJob::dispatch('doJob', [$testData]); Queue::assertPushed(CustomJob::class, function ($job) use ($testData) { return $job->data[0] === $testData; }); } ``` ### 3. 监控和调试 #### 3.1 添加日志 ```php public function doJob(array $data): bool { Log::info('任务开始执行', ['data' => $data]); try { // 业务逻辑 Log::info('任务执行成功'); return true; } catch (\Exception $e) { Log::error('任务执行失败', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return false; } } ``` #### 3.2 性能监控 ```php public function doJob(array $data): bool { $startTime = microtime(true); try { // 业务逻辑 $endTime = microtime(true); $executeTime = ($endTime - $startTime) * 1000; // 毫秒 Log::info('任务执行完成', [ 'execute_time' => $executeTime . 'ms', 'memory_usage' => memory_get_usage(true) ]); return true; } catch (\Exception $e) { Log::error('任务执行失败', ['error' => $e->getMessage()]); return false; } } ``` ## 总结 CRMEB 的队列任务系统是系统高性能运行的关键组件,通过合理的任务分类、优先级管理、错误处理和监控机制,确保了系统的稳定性和可扩展性。在实际使用中,需要根据业务特点合理设计任务粒度,优化执行效率,并建立完善的监控告警机制。 队列系统的正确使用可以显著提升用户体验,降低系统负载,提高数据处理的一致性。建议开发团队充分理解队列机制,在合适场景下合理应用,并持续优化和改进队列性能。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/统计分析开发文档 (help/dev-docs/phpapi/统计分析开发文档.md) # 统计分析开发文档 ## 1. 文档概述 ### 1.1 文档目的 本文档旨在详细说明CRMEB系统中统计分析模块的设计架构、核心功能、代码实现及开发规范,为系统开发人员提供完整的开发参考。 ### 1.2 适用范围 本文档适用于CRMEB系统开发人员、维护人员及二次开发人员,用于指导统计分析模块的开发、扩展和维护工作。 ### 1.3 术语定义 | 术语 | 解释 | |------|------| | PV | 页面访问量(Page View),即页面浏览次数 | | UV | 独立访客数(Unique Visitor),即不同IP地址访问网站的用户数 | | 转化率 | 转化次数与访问次数的比率,如注册转化率、下单转化率 | | 复购率 | 重复购买用户数与总购买用户数的比率 | | 环比 | 本期统计数据与上期统计数据的比较 | | 同比 | 本期统计数据与上年同期统计数据的比较 | | 资金流水 | 系统中所有资金的流入流出记录 | ## 2. 核心功能模块 ### 2.1 流量统计 - **PV/UV统计**:统计网站的页面访问量和独立访客数 - **访问趋势分析**:支持按小时、日、周、月维度查看访问趋势 - **访问来源分析**:分析用户的访问来源渠道 - **页面热度分析**:统计各个页面的访问热度 - **访问设备分析**:分析用户使用的设备类型(PC、移动端、平板等) ### 2.2 用户统计 - **用户基础信息统计**:新增用户数、成交用户数、充值用户数、付费用户数 - **用户增长趋势**:按时间维度查看用户增长情况 - **用户地域分布**:统计用户的地域分布(按省份、城市) - **用户性别分布**:统计用户的性别分布 - **用户年龄分布**:统计用户的年龄分布 - **微信用户分析**:微信用户关注/取关统计 - **用户行为分析**:用户浏览、搜索、购买等行为分析 ### 2.3 销售统计 - **订单金额统计**:统计订单总金额、实付金额、退款金额等 - **订单数量统计**:统计订单总数、成交订单数、退款订单数等 - **订单趋势分析**:按时间维度查看订单趋势 - **订单来源分析**:分析订单的来源渠道 - **订单类型分布**:统计不同类型订单的分布情况 - **实时交易数据**:实时展示交易数据 - **支付方式分析**:分析不同支付方式的使用情况 ### 2.4 资金统计 - **资金流水统计**:统计系统中的资金流入流出记录 - **账单记录**:生成日/周/月账单 - **余额统计**:统计用户余额情况 - **余额趋势分析**:按时间维度查看余额趋势 - **余额来源分析**:分析余额的来源渠道 - **余额类型分析**:分析不同类型余额的分布 ### 2.5 商品统计 - **商品销售基础数据**:商品销售额、销量、访客数、转化率等 - **商品销售趋势**:按时间维度查看商品销售趋势 - **商品排行**:商品销售额排行、销量排行、访客数排行等 - **商品分类统计**:按商品分类统计销售情况 - **商品属性分析**:分析商品不同属性的销售情况 ## 3. 代码结构与设计 ### 3.1 架构设计 系统采用分层架构设计,严格遵循MVC设计模式: ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Controllers │ │ Services │ │ Daos │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └───────────────────────┼───────────────────────┘ │ ┌─────────────────┐ │ Models │ └─────────────────┘ │ ┌─────────────────┐ │ 数据库 │ └─────────────────┘ ``` ### 3.2 核心文件结构 #### 3.2.1 控制器层(Controller) **统计分析控制器**:`/crmeb/app/adminapi/controller/v1/statistic/` - `FlowStatistic.php` - 资金流水统计控制器 - `UserStatistic.php` - 用户统计控制器 - `OrderStatistic.php` - 订单统计控制器 - `TradeStatistic.php` - 交易统计控制器 - `ProductStatistic.php` - 商品统计控制器 - `BalanceStatistic.php` - 余额统计控制器 #### 3.2.2 服务层(Services) **统计分析服务**:`/crmeb/app/services/statistic/` - `CapitalFlowServices.php` - 资金流水统计服务 - `UserStatisticServices.php` - 用户统计服务 - `OrderStatisticServices.php` - 订单统计服务 - `TradeStatisticServices.php` - 交易统计服务 - `ProductStatisticServices.php` - 商品统计服务 - `BalanceStatisticServices.php` - 余额统计服务 #### 3.2.3 数据访问层(Dao) **统计分析Dao**:与各个业务模块的Dao共用,如用户Dao、订单Dao、商品Dao等 #### 3.2.4 模型层(Model) **统计分析模型**:与各个业务模块的模型共用,如用户模型、订单模型、商品模型等 ## 4. 数据库设计 ### 4.1 资金流水表(capital_flow) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 流水ID | | uid | int(10) | 用户ID | | link_id | int(10) | 关联ID(如订单ID、充值ID等) | | type | varchar(20) | 交易类型(pay-支付订单,refund-退款,recharge-充值,extract-提现等) | | money | decimal(10,2) | 交易金额 | | pm | tinyint(1) | 收支方向(1-收入,0-支出) | | balance | decimal(10,2) | 交易后余额 | | mark | varchar(255) | 备注 | | add_time | int(10) | 添加时间 | ### 4.2 访问记录表(visit_log) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 记录ID | | uid | int(10) | 用户ID(0-游客) | | ip | varchar(15) | 访问IP | | url | varchar(255) | 访问URL | | referer | varchar(255) | 来源URL | | user_agent | text | 用户代理信息 | | device | varchar(20) | 设备类型(pc, mobile, tablet) | | browser | varchar(20) | 浏览器 | | os | varchar(20) | 操作系统 | | add_time | int(10) | 访问时间 | ### 4.3 销售统计表(sale_statistics) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 统计ID | | date | date | 统计日期 | | order_count | int(10) | 订单数量 | | order_amount | decimal(10,2) | 订单总金额 | | pay_amount | decimal(10,2) | 实付金额 | | refund_count | int(10) | 退款订单数量 | | refund_amount | decimal(10,2) | 退款金额 | | user_count | int(10) | 成交用户数 | | add_time | int(10) | 添加时间 | ## 5. API接口说明 ### 5.1 流量统计接口 #### 5.1.1 获取PV/UV统计 - **请求URL**:`/adminapi/v1/statistic/flow/pvuv` - **请求方法**:GET - **权限要求**:statistic/flow/pvuv - **请求参数**: - type:时间维度(hour, day, week, month) - start_time:开始时间 - end_time:结束时间 - **返回结果**:PV/UV统计数据 #### 5.1.2 获取访问来源分析 - **请求URL**:`/adminapi/v1/statistic/flow/source` - **请求方法**:GET - **权限要求**:statistic/flow/source - **请求参数**: - start_time:开始时间 - end_time:结束时间 - **返回结果**:访问来源分析数据 ### 5.2 用户统计接口 #### 5.2.1 获取用户基础统计 - **请求URL**:`/adminapi/v1/statistic/user/basic` - **请求方法**:GET - **权限要求**:statistic/user/basic - **请求参数**: - start_time:开始时间 - end_time:结束时间 - **返回结果**:用户基础统计数据 #### 5.2.2 获取用户增长趋势 - **请求URL**:`/adminapi/v1/statistic/user/trend` - **请求方法**:GET - **权限要求**:statistic/user/trend - **请求参数**: - type:时间维度(hour, day, week, month) - start_time:开始时间 - end_time:结束时间 - **返回结果**:用户增长趋势数据 #### 5.2.3 获取用户地域分布 - **请求URL**:`/adminapi/v1/statistic/user/region` - **请求方法**:GET - **权限要求**:statistic/user/region - **请求参数**: - start_time:开始时间 - end_time:结束时间 - **返回结果**:用户地域分布数据 ### 5.3 销售统计接口 #### 5.3.1 获取订单统计 - **请求URL**:`/adminapi/v1/statistic/order/basic` - **请求方法**:GET - **权限要求**:statistic/order/basic - **请求参数**: - start_time:开始时间 - end_time:结束时间 - **返回结果**:订单统计数据 #### 5.3.2 获取订单趋势 - **请求URL**:`/adminapi/v1/statistic/order/trend` - **请求方法**:GET - **权限要求**:statistic/order/trend - **请求参数**: - type:时间维度(hour, day, week, month) - start_time:开始时间 - end_time:结束时间 - **返回结果**:订单趋势数据 ### 5.4 资金统计接口 #### 5.4.1 获取资金流水列表 - **请求URL**:`/adminapi/v1/statistic/flow/list` - **请求方法**:GET - **权限要求**:statistic/flow/list - **请求参数**: - page:页码 - limit:每页数量 - type:交易类型 - start_time:开始时间 - end_time:结束时间 - **返回结果**:资金流水列表数据 #### 5.4.2 获取账单记录 - **请求URL**:`/adminapi/v1/statistic/flow/bill` - **请求方法**:GET - **权限要求**:statistic/flow/bill - **请求参数**: - type:账单类型(day, week, month) - date:统计日期 - **返回结果**:账单记录数据 ### 5.5 商品统计接口 #### 5.5.1 获取商品销售基础数据 - **请求URL**:`/adminapi/v1/statistic/product/basic` - **请求方法**:GET - **权限要求**:statistic/product/basic - **请求参数**: - product_id:商品ID - start_time:开始时间 - end_time:结束时间 - **返回结果**:商品销售基础数据 #### 5.5.2 获取商品销售排行 - **请求URL**:`/adminapi/v1/statistic/product/rank` - **请求方法**:GET - **权限要求**:statistic/product/rank - **请求参数**: - type:排行类型(sales, amount, visitor) - start_time:开始时间 - end_time:结束时间 - limit:返回数量 - **返回结果**:商品销售排行数据 ## 5. 开发规范与流程 ### 5.1 代码规范 1. **命名规范**: - 类名采用大驼峰命名法,如 `UserStatisticServices` - 方法名采用小驼峰命名法,如 `getUserBasicInfo` - 变量名采用小驼峰命名法,如 `visitorCount` - 常量名采用全大写,下划线分隔,如 `STATISTIC_TYPE_HOUR` 2. **代码结构**: - 严格遵循分层架构,禁止跨层调用 - 每个方法职责单一,代码行数控制在50行以内 - 适当添加注释,说明方法功能、参数含义和返回值 - 所有统计数据必须包含完整的时间范围 3. **性能优化**: - 统计查询必须使用索引,避免全表扫描 - 复杂统计查询必须使用缓存,减少数据库压力 - 统计数据必须定期汇总,避免实时计算大量数据 - 使用合适的统计周期,如小时、日、周、月 ### 5.2 开发流程 1. **需求分析**:明确统计分析的功能需求和业务逻辑 2. **设计阶段**:设计数据结构、API接口和业务流程 3. **编码实现**: - 实现统计服务层逻辑 - 实现统计控制器接口 - 实现数据汇总和缓存机制 4. **单元测试**:编写单元测试,确保统计结果正确性 5. **性能测试**:对统计查询进行性能测试,优化查询效率 6. **代码审查**:提交代码审查,确保代码质量 7. **部署上线**:部署到生产环境 ## 6. 常见问题与解决方案 ### 6.1 统计数据不准确 **问题**:统计数据与实际数据不符 **解决方案**: 1. 检查统计逻辑,确保统计范围正确 2. 检查数据来源,确保数据完整 3. 检查时间范围,确保时间格式正确 4. 检查统计周期,确保周期划分正确 5. 实现数据校验机制,定期核对统计数据 ### 6.2 统计查询性能问题 **问题**:统计查询耗时过长,影响系统性能 **解决方案**: 1. 使用索引优化查询 2. 实现统计数据缓存 3. 定期预计算统计数据 4. 优化数据库结构,如分表、分区 5. 使用数据仓库或OLAP数据库处理复杂统计 ### 6.3 统计维度不足 **问题**:无法满足多维度统计需求 **解决方案**: 1. 设计灵活的统计架构,支持自定义统计维度 2. 实现统计维度扩展机制 3. 使用数据立方体技术,支持多维数据分析 ### 6.4 实时统计问题 **问题**:实时统计数据延迟或不准确 **解决方案**: 1. 使用流处理技术,如Kafka、Flink等 2. 实现准实时统计,平衡实时性和准确性 3. 优化实时数据处理流程,减少延迟 ## 7. 扩展与定制 ### 7.1 添加新的统计维度 1. **设计统计逻辑**:确定新统计维度的计算逻辑 2. **修改服务层**:在相应的统计服务中添加新的统计方法 3. **添加API接口**:在相应的控制器中添加新的API接口 4. **前端修改**:在前端页面中添加新的统计图表和展示 ### 7.2 实现自定义统计报表 1. **设计报表结构**:确定报表的字段、维度和指标 2. **实现报表生成逻辑**:在统计服务中添加报表生成方法 3. **添加报表管理功能**:实现报表的创建、编辑、删除功能 4. **前端修改**:在前端页面中添加报表展示和导出功能 ### 7.3 集成第三方统计工具 1. **设计集成方案**:确定与第三方统计工具的集成方式 2. **实现数据同步**:实现与第三方统计工具的数据同步 3. **添加API接口**:添加获取第三方统计数据的API接口 4. **前端修改**:在前端页面中集成第三方统计图表 ## 8. 文档更新记录 | 版本 | 更新日期 | 更新内容 | 更新人 | |------|----------|----------|--------| | 1.0 | 2026-01-19 | 初始版本,包含流量统计、用户统计、销售统计、资金统计、商品统计等核心功能 | AI Assistant | ## 9. 附录 ### 9.1 核心类关系图 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Controllers │ │ Services │ │ Daos │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └───────────────────────┼───────────────────────┘ │ ┌─────────────────┐ │ Models │ └─────────────────┘ │ ┌─────────────────┐ │ 数据库 │ └─────────────────┘ ``` ### 9.2 统计流程示意图 ``` 统计流程: 1. 系统收集原始数据(访问日志、订单数据、用户数据等) 2. 定期汇总原始数据,生成统计数据 3. 将统计数据存储到统计表中 4. 提供API接口,供前端查询统计数据 5. 前端展示统计图表和数据 6. 支持统计数据导出 ``` ### 9.3 支持的统计维度 | 维度名称 | 描述 | |----------|------| | 时间维度 | 小时、日、周、月、年 | | 地域维度 | 省份、城市 | | 设备维度 | PC、移动端、平板 | | 渠道维度 | 微信、支付宝、APP、小程序等 | | 商品维度 | 商品分类、商品属性、品牌等 | | 用户维度 | 性别、年龄、会员等级等 | | 订单维度 | 订单类型、支付方式、配送方式等 | ### 9.4 统计指标列表 | 指标名称 | 描述 | |----------|------| | PV | 页面访问量 | | UV | 独立访客数 | | 新增用户数 | 新增注册用户数 | | 成交用户数 | 完成交易的用户数 | | 复购率 | 重复购买用户数与总购买用户数的比率 | | 转化率 | 转化次数与访问次数的比率 | | 订单总金额 | 订单的总金额 | | 实付金额 | 实际支付的金额 | | 订单数量 | 订单总数 | | 客单价 | 平均每笔订单的金额 | | 商品销售额 | 商品的销售总额 | | 商品销量 | 商品的销售数量 | | 资金流入 | 系统中的资金流入总额 | | 资金流出 | 系统中的资金流出总额 | --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/营销活动开发文档 (help/dev-docs/phpapi/营销活动开发文档.md) # 营销活动开发文档 ## 1. 文档概述 ### 1.1 文档目的 本文档旨在详细说明CRMEB系统中营销活动模块的设计架构、核心功能、代码实现及开发规范,为系统开发人员提供完整的开发参考。 ### 1.2 适用范围 本文档适用于CRMEB系统开发人员、维护人员及二次开发人员,用于指导营销活动模块的开发、扩展和维护工作。 ### 1.3 术语定义 | 术语 | 解释 | |------|------| | 限时秒杀 | 在特定时间段内,商品以低于原价的价格销售 | | 商品砍价 | 用户邀请好友帮忙砍价,以更低价格购买商品 | | 多人拼团 | 多个用户联合购买商品,享受更低价格 | | 优惠券 | 可用于抵扣商品价格的电子券 | | SPU | 标准化产品单元,如"iPhone 13" | | SKU | 库存量单位,如"iPhone 13 128G 白色" | | 开团 | 创建拼团活动 | | 参团 | 加入他人创建的拼团活动 | | 助力 | 帮助好友砍价 | ## 2. 核心功能模块 ### 2.1 限时秒杀 - **秒杀配置**:设置秒杀时间段、参与商品、秒杀价格 - **秒杀商品管理**:添加/编辑/删除参与秒杀的商品 - **秒杀时间段管理**:设置秒杀活动的时间段 - **秒杀记录**:查看用户秒杀记录 - **秒杀状态管理**:开启/关闭秒杀活动 ### 2.2 商品砍价 - **砍价商品配置**:设置砍价商品、初始价格、最低价格、砍价次数 - **砍价活动管理**:添加/编辑/删除砍价活动 - **砍价记录管理**:查看用户砍价记录 - **砍价助力记录**:查看用户砍价助力记录 - **砍价状态管理**:开启/关闭砍价活动 ### 2.3 多人拼团 - **拼团商品配置**:设置拼团商品、拼团价格、成团人数、拼团有效期 - **拼团活动管理**:添加/编辑/删除拼团活动 - **拼团记录管理**:查看拼团记录、成团状态 - **拼团规则设置**:设置拼团规则,如是否允许重复参团 - **拼团状态管理**:开启/关闭拼团活动 ### 2.4 优惠券管理 - **优惠券模板配置**:设置优惠券类型(满减、折扣)、面值、使用条件、有效期 - **优惠券发放管理**:手动发放、自动发放、批量发放优惠券 - **用户优惠券管理**:查看用户领取的优惠券、使用情况 - **优惠券使用统计**:统计优惠券领取量、使用率、优惠金额 - **优惠券状态管理**:开启/关闭优惠券 ### 2.5 积分商城 - **积分商品配置**:设置积分商品、积分价格、库存 - **积分商品管理**:添加/编辑/删除积分商品 - **积分兑换记录**:查看用户积分兑换记录 - **积分规则设置**:设置积分获取、使用规则 ### 2.6 预售活动 - **预售商品配置**:设置预售商品、预售价格、定金、尾款支付时间 - **预售活动管理**:添加/编辑/删除预售活动 - **预售订单管理**:查看预售订单、定金支付情况、尾款支付情况 - **预售状态管理**:开启/关闭预售活动 ## 3. 代码结构与设计 ### 3.1 架构设计 系统采用分层架构设计,严格遵循MVC设计模式: ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ ActivityModel │ │ ActivityDao │ │ ActivityServices│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └───────────────────────┼───────────────────────┘ │ ┌─────────────────┐ │ ActivityController│ └─────────────────┘ │ ┌─────────────────┐ │ Routes │ └─────────────────┘ ``` ### 3.2 核心文件结构 #### 3.2.1 模型层(Model) 所有营销活动模型均位于 `crmeb/app/model/activity/` 目录下,按活动类型分类: - **秒杀活动**: - `seckill/StoreSeckill.php` - 秒杀商品模型 - **砍价活动**: - `bargain/StoreBargain.php` - 砍价商品模型 - `bargain/StoreBargainUser.php` - 砍价用户参与记录模型 - `bargain/StoreBargainUserHelp.php` - 砍价助力记录模型 - **拼团活动**: - `combination/StoreCombination.php` - 拼团商品模型 - `combination/StorePink.php` - 拼团记录模型 - **优惠券活动**: - `coupon/StoreCoupon.php` - 优惠券模板模型 - `coupon/StoreCouponIssue.php` - 优惠券发放记录模型 - `coupon/StoreCouponProduct.php` - 优惠券适用商品模型 - `coupon/StoreCouponUser.php` - 用户优惠券模型 #### 3.2.2 数据访问层(DAO) 所有营销活动DAO均位于 `crmeb/app/dao/activity/` 目录下,按活动类型分类: - **秒杀活动**: - `seckill/StoreSeckillDao.php` - 秒杀商品DAO - **砍价活动**: - `bargain/StoreBargainDao.php` - 砍价商品DAO - `bargain/StoreBargainUserDao.php` - 砍价用户参与记录DAO - `bargain/StoreBargainUserHelpDao.php` - 砍价助力记录DAO - **拼团活动**: - `combination/StoreCombinationDao.php` - 拼团商品DAO - `combination/StorePinkDao.php` - 拼团记录DAO - **优惠券活动**: - `coupon/StoreCouponDao.php` - 优惠券模板DAO - `coupon/StoreCouponIssueDao.php` - 优惠券发放记录DAO - `coupon/StoreCouponProductDao.php` - 优惠券适用商品DAO - `coupon/StoreCouponUserDao.php` - 用户优惠券DAO #### 3.2.3 业务服务层(Services) 所有营销活动Services均位于 `crmeb/app/services/activity/` 目录下,按活动类型分类: - **秒杀活动**: - `seckill/StoreSeckillServices.php` - 秒杀商品Services - **砍价活动**: - `bargain/StoreBargainServices.php` - 砍价商品Services - `bargain/StoreBargainUserServices.php` - 砍价用户参与记录Services - `bargain/StoreBargainUserHelpServices.php` - 砍价助力记录Services - **拼团活动**: - `combination/StoreCombinationServices.php` - 拼团商品Services - `combination/StorePinkServices.php` - 拼团记录Services - **优惠券活动**: - `coupon/StoreCouponServices.php` - 优惠券模板Services - `coupon/StoreCouponIssueServices.php` - 优惠券发放记录Services - `coupon/StoreCouponUserServices.php` - 用户优惠券Services #### 3.2.4 控制器层(Controller) 管理员API控制器位于 `crmeb/app/adminapi/controller/v1/marketing/` 目录下: - `StoreSeckill.php` - 秒杀活动控制器 - `StoreBargain.php` - 砍价活动控制器 - `StoreCombination.php` - 拼团活动控制器 - `StoreCoupon.php` - 优惠券控制器 移动端API控制器位于 `crmeb/app/api/controller/v1/activity/` 目录下,提供移动端调用的活动接口。 #### 3.2.5 路由配置 营销活动路由配置位于 `crmeb/app/adminapi/route/marketing.php` 文件中,包含了各种活动的增删改查、状态管理、统计等路由。 移动端路由配置位于 `crmeb/app/api/route/` 目录下,根据API版本分类。 ## 4. 数据库设计 ### 4.1 秒杀活动相关表 #### 秒杀商品表(store_seckill) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 秒杀商品ID | | product_id | int(10) | 关联商品ID | | title | varchar(100) | 秒杀活动标题 | | image | varchar(255) | 秒杀商品图片 | | unit_name | varchar(10) | 单位名称 | | sec_price | decimal(10,2) | 秒杀价格 | | price | decimal(10,2) | 原价 | | cost | decimal(10,2) | 成本价 | | description | varchar(255) | 秒杀活动描述 | | start_time | int(10) | 开始时间 | | end_time | int(10) | 结束时间 | | status | tinyint(1) | 状态(0-关闭,1-开启) | | sales | int(10) | 销量 | | stock | int(10) | 库存 | | give_integral | int(10) | 赠送积分 | | sort | int(10) | 排序 | | is_delete | tinyint(1) | 是否删除 | | add_time | int(10) | 添加时间 | ### 4.2 砍价活动相关表 #### 砍价商品表(store_bargain) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 砍价商品ID | | product_id | int(10) | 关联商品ID | | title | varchar(100) | 砍价活动标题 | | image | varchar(255) | 砍价商品图片 | | unit_name | varchar(10) | 单位名称 | | min_price | decimal(10,2) | 最低价格 | | price | decimal(10,2) | 原价 | | cost | decimal(10,2) | 成本价 | | description | varchar(255) | 砍价活动描述 | | start_time | int(10) | 开始时间 | | end_time | int(10) | 结束时间 | | status | tinyint(1) | 状态(0-关闭,1-开启) | | sales | int(10) | 销量 | | stock | int(10) | 库存 | | people_num | int(10) | 每人可发起砍价次数 | | bargain_num | int(10) | 每次砍价可邀请人数 | | sort | int(10) | 排序 | | is_delete | tinyint(1) | 是否删除 | | add_time | int(10) | 添加时间 | #### 砍价用户参与记录表(store_bargain_user) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 记录ID | | uid | int(10) | 用户ID | | bargain_id | int(10) | 砍价商品ID | | price | decimal(10,2) | 最终砍价价格 | | status | tinyint(1) | 状态(0-进行中,1-成功,2-失败) | | add_time | int(10) | 开始时间 | | stop_time | int(10) | 结束时间 | #### 砍价助力记录表(store_bargain_user_help) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 记录ID | | bargain_user_id | int(10) | 砍价用户记录ID | | uid | int(10) | 助力用户ID | | price | decimal(10,2) | 砍掉的价格 | | add_time | int(10) | 助力时间 | ### 4.3 拼团活动相关表 #### 拼团商品表(store_combination) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 拼团商品ID | | product_id | int(10) | 关联商品ID | | title | varchar(100) | 拼团活动标题 | | image | varchar(255) | 拼团商品图片 | | unit_name | varchar(10) | 单位名称 | | pink_price | decimal(10,2) | 拼团价格 | | price | decimal(10,2) | 原价 | | cost | decimal(10,2) | 成本价 | | description | varchar(255) | 拼团活动描述 | | start_time | int(10) | 开始时间 | | end_time | int(10) | 结束时间 | | status | tinyint(1) | 状态(0-关闭,1-开启) | | sales | int(10) | 销量 | | stock | int(10) | 库存 | | people | int(10) | 成团人数 | | sort | int(10) | 排序 | | is_delete | tinyint(1) | 是否删除 | | add_time | int(10) | 添加时间 | #### 拼团记录表(store_pink) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 记录ID | | cid | int(10) | 拼团商品ID | | uid | int(10) | 开团用户ID | | order_id | int(10) | 开团订单ID | | people | int(10) | 成团人数 | | price | decimal(10,2) | 拼团价格 | | status | tinyint(1) | 状态(0-拼团中,1-成团,2-失败) | | add_time | int(10) | 开团时间 | | stop_time | int(10) | 结束时间 | ### 4.4 优惠券相关表 #### 优惠券模板表(store_coupon) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 优惠券ID | | type | tinyint(1) | 优惠券类型(0-满减,1-折扣) | | title | varchar(100) | 优惠券名称 | | money | decimal(10,2) | 优惠券金额 | | min_price | decimal(10,2) | 最低使用金额 | | discount | decimal(10,2) | 折扣(如9.5折) | | use_type | tinyint(1) | 使用类型(0-全场通用,1-指定商品,2-指定分类) | | start_time | int(10) | 开始时间 | | end_time | int(10) | 结束时间 | | status | tinyint(1) | 状态(0-关闭,1-开启) | | total_count | int(10) | 总发行量 | | give_count | int(10) | 已发放数量 | | use_count | int(10) | 已使用数量 | | get_type | tinyint(1) | 获取方式(0-手动领取,1-自动发放) | | is_perpetual | tinyint(1) | 是否永久有效 | | effective_days | int(10) | 有效天数 | | sort | int(10) | 排序 | | add_time | int(10) | 添加时间 | #### 用户优惠券表(store_coupon_user) | 字段名 | 数据类型 | 描述 | |--------|----------|------| | id | int(10) unsigned | 记录ID | | cid | int(10) | 优惠券ID | | uid | int(10) | 用户ID | | status | tinyint(1) | 状态(0-未使用,1-已使用,2-已过期) | | get_time | int(10) | 领取时间 | | use_time | int(10) | 使用时间 | | order_id | int(10) | 使用订单ID | | end_time | int(10) | 过期时间 | ## 5. API接口说明 ### 5.1 秒杀活动接口 #### 5.1.1 秒杀商品列表 - **请求URL**:`/adminapi/v1/marketing/seckill/list` - **请求方法**:GET - **权限要求**:marketing/seckill/list - **请求参数**: - page:页码 - limit:每页数量 - keyword:搜索关键词 - status:状态(0-关闭,1-开启) - **返回结果**:秒杀商品列表数据 #### 5.1.2 添加秒杀商品 - **请求URL**:`/adminapi/v1/marketing/seckill/create` - **请求方法**:POST - **权限要求**:marketing/seckill/create - **请求参数**:秒杀商品信息 - **返回结果**:操作结果 #### 5.1.3 编辑秒杀商品 - **请求URL**:`/adminapi/v1/marketing/seckill/update/{id}` - **请求方法**:PUT - **权限要求**:marketing/seckill/update - **请求参数**:秒杀商品信息 - **返回结果**:操作结果 #### 5.1.4 删除秒杀商品 - **请求URL**:`/adminapi/v1/marketing/seckill/delete/{id}` - **请求方法**:DELETE - **权限要求**:marketing/seckill/delete - **返回结果**:操作结果 ### 5.2 砍价活动接口 #### 5.2.1 砍价商品列表 - **请求URL**:`/adminapi/v1/marketing/bargain/list` - **请求方法**:GET - **权限要求**:marketing/bargain/list - **请求参数**: - page:页码 - limit:每页数量 - keyword:搜索关键词 - status:状态(0-关闭,1-开启) - **返回结果**:砍价商品列表数据 #### 5.2.2 添加砍价商品 - **请求URL**:`/adminapi/v1/marketing/bargain/create` - **请求方法**:POST - **权限要求**:marketing/bargain/create - **请求参数**:砍价商品信息 - **返回结果**:操作结果 ### 5.3 拼团活动接口 #### 5.3.1 拼团商品列表 - **请求URL**:`/adminapi/v1/marketing/combination/list` - **请求方法**:GET - **权限要求**:marketing/combination/list - **请求参数**: - page:页码 - limit:每页数量 - keyword:搜索关键词 - status:状态(0-关闭,1-开启) - **返回结果**:拼团商品列表数据 #### 5.3.2 添加拼团商品 - **请求URL**:`/adminapi/v1/marketing/combination/create` - **请求方法**:POST - **权限要求**:marketing/combination/create - **请求参数**:拼团商品信息 - **返回结果**:操作结果 ### 5.4 优惠券接口 #### 5.4.1 优惠券列表 - **请求URL**:`/adminapi/v1/marketing/coupon/list` - **请求方法**:GET - **权限要求**:marketing/coupon/list - **请求参数**: - page:页码 - limit:每页数量 - keyword:搜索关键词 - status:状态(0-关闭,1-开启) - **返回结果**:优惠券列表数据 #### 5.4.2 添加优惠券 - **请求URL**:`/adminapi/v1/marketing/coupon/create` - **请求方法**:POST - **权限要求**:marketing/coupon/create - **请求参数**:优惠券信息 - **返回结果**:操作结果 ## 5. 开发规范与流程 ### 5.1 代码规范 1. **命名规范**: - 类名采用大驼峰命名法,如 `StoreSeckillServices` - 方法名采用小驼峰命名法,如 `getSeckillList` - 变量名采用小驼峰命名法,如 `seckillProduct` - 常量名采用全大写,下划线分隔,如 `COUPON_TYPE_FULL` 2. **代码结构**: - 严格遵循分层架构,禁止跨层调用 - 每个方法职责单一,代码行数控制在50行以内 - 适当添加注释,说明方法功能、参数含义和返回值 3. **数据库操作**: - 所有数据库操作必须通过Dao层进行 - 使用ORM提供的查询构建器,避免直接编写SQL - 涉及资金、库存等关键数据操作必须使用事务处理 ### 5.2 开发流程 1. **需求分析**:明确营销活动的功能需求和业务逻辑 2. **设计阶段**:设计数据结构、API接口和业务流程 3. **编码实现**:按照分层架构编写代码 4. **单元测试**:编写单元测试,确保功能正确性 5. **集成测试**:进行模块集成测试,测试活动与商品、订单等模块的交互 6. **性能测试**:对高并发场景进行性能测试,如秒杀活动 7. **代码审查**:提交代码审查,确保代码质量 8. **部署上线**:部署到生产环境 ## 6. 常见问题与解决方案 ### 6.1 高并发处理 **问题**:秒杀、拼团等活动在高并发场景下可能出现超卖、数据不一致等问题 **解决方案**: 1. 使用数据库事务和乐观锁机制 2. 实现库存预扣和释放机制 3. 使用Redis等缓存技术,提高库存操作效率 4. 采用分布式锁,确保数据一致性 5. 实现流量削峰,如使用队列、限流等技术 ### 6.2 活动时间管理 **问题**:活动开始和结束时间的精确控制 **解决方案**: 1. 使用定时器任务,定期检查活动状态 2. 在关键操作(如用户参与活动)时,再次验证活动时间 3. 使用Redis的过期时间功能,自动更新活动状态 ### 6.3 活动数据统计 **问题**:实时统计活动参与人数、销售额等数据 **解决方案**: 1. 使用Redis缓存实时数据,定期同步到数据库 2. 采用异步处理方式,避免影响主业务流程 3. 实现数据报表功能,支持多维度查询 ### 6.4 活动冲突处理 **问题**:同一商品参与多个活动时的冲突 **解决方案**: 1. 设计活动优先级机制,明确活动执行顺序 2. 在用户参与活动时,验证商品是否可以同时参与多个活动 3. 提供活动冲突检测功能,在创建活动时提示冲突 ## 7. 扩展与定制 ### 7.1 功能扩展 系统设计具有良好的扩展性,可通过以下方式扩展功能: 1. **添加新活动类型**: - 在 `model/activity/` 目录下创建新的活动模型 - 在 `dao/activity/` 目录下创建对应的DAO - 在 `services/activity/` 目录下创建对应的Services - 在 `controller/` 目录下创建对应的控制器 - 在路由文件中添加新的路由 2. **扩展现有活动功能**: - 在现有模型中添加新字段 - 在现有Services中添加新方法 - 在现有控制器中添加新接口 ### 7.2 事件扩展 系统在关键业务节点触发事件,可通过监听事件进行功能扩展: 1. **活动开始事件**:ActivityStartEvent 2. **活动结束事件**:ActivityEndEvent 3. **用户参与活动事件**:UserJoinActivityEvent 4. **活动订单创建事件**:ActivityOrderCreateEvent 5. **活动订单支付事件**:ActivityOrderPayEvent ### 7.3 钩子扩展 系统提供了多个钩子点,可通过钩子函数进行功能扩展: 1. **活动创建前钩子**:activity_create_before 2. **活动创建后钩子**:activity_create_after 3. **活动编辑前钩子**:activity_edit_before 4. **活动编辑后钩子**:activity_edit_after 5. **活动删除前钩子**:activity_delete_before 6. **活动删除后钩子**:activity_delete_after 7. **用户参与活动前钩子**:user_join_activity_before 8. **用户参与活动后钩子**:user_join_activity_after ## 8. 文档更新记录 | 版本 | 更新日期 | 更新内容 | 更新人 | |------|----------|----------|--------| | 1.0 | 2026-01-19 | 初始版本,包含秒杀、砍价、拼团、优惠券等核心营销活动 | AI Assistant | ## 9. 附录 ### 9.1 核心类关系图 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ ActivityModel │ │ ActivityDao │ │ ActivityServices│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └───────────────────────┼───────────────────────┘ │ ┌─────────────────┐ │ ActivityController│ └─────────────────┘ │ ┌─────────────────┐ │ Routes │ └─────────────────┘ ``` ### 9.2 秒杀活动流程图 ``` 秒杀活动流程: 1. 用户进入秒杀活动页面 2. 系统验证活动是否开始 3. 用户点击秒杀按钮 4. 系统验证商品库存 5. 系统预扣商品库存 6. 用户创建订单 7. 用户支付订单 8. 系统确认订单,扣减库存 9. 活动结束,释放未支付订单的库存 ``` ### 9.3 拼团活动流程图 ``` 拼团活动流程: 1. 用户进入拼团活动页面 2. 选择商品和拼团规格 3. 选择开团或参团 a. 开团:创建新的拼团记录 b. 参团:加入已有拼团记录 4. 系统预扣商品库存 5. 用户创建订单 6. 用户支付订单 7. 系统检查是否达到成团人数 a. 达到:拼团成功 b. 未达到:等待其他用户参团 8. 拼团时间结束 a. 成团:订单生效 b. 未成团:退款给用户,释放库存 ``` ### 9.4 砍价活动流程图 ``` 砍价活动流程: 1. 用户进入砍价活动页面 2. 选择商品,点击开始砍价 3. 系统创建砍价记录 4. 用户邀请好友帮忙砍价 5. 好友点击助力,系统随机砍掉一定金额 6. 用户达到最低价格或砍价时间结束 7. 用户以砍价价格购买商品 8. 系统创建订单,扣减库存 ``` --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/订单模块说明 (help/dev-docs/phpapi/订单模块说明.md) # 订单模块说明 ## 📦 订单状态流转 ### 订单核心状态 ```php const ORDER_STATUS_UNPAID = 0; // 未支付 const ORDER_STATUS_PAID = 1; // 已支付 const ORDER_STATUS_SHIPPED = 2; // 已发货 const ORDER_STATUS_COMPLETED = 3; // 已完成 const ORDER_STATUS_CANCELLED = -1; // 已取消 const ORDER_STATUS_REFUNDING = -2; // 退款中 const ORDER_STATUS_REFUNDED = -3; // 已退款 ``` ### 支付状态 ```php const PAY_STATUS_UNPAID = 0; // 未支付 const PAY_STATUS_PAID = 1; // 已支付 const PAY_STATUS_REFUNDING = 2; // 退款中 const PAY_STATUS_REFUNDED = 3; // 已退款 ``` ## 🔄 订单创建流程 ### 1. 参数验证 ```php // 验证收货地址、商品信息、优惠券等 $validate = new OrderValidate(); if (!$validate->scene('create')->check($params)) { throw new ApiException($validate->getError()); } ``` ### 2. 商品校验 ```php // 检查商品库存、价格、状态 foreach ($cartInfo as $item) { $product = $productService->getProductInfo($item['product_id']); if ($product['stock'] < $item['cart_num']) { throw new ApiException('商品库存不足'); } } ``` ### 3. 优惠计算 ```php // 计算优惠券、积分、满减等 $couponAmount = $couponService->calculateCoupon($uid, $cartInfo); $integralAmount = $integralService->calculateIntegral($uid, $totalAmount); $finalAmount = $totalAmount - $couponAmount - $integralAmount; ``` ### 4. 创建订单 ```php // 生成订单数据 $orderData = [ 'order_id' => $this->getNewOrderId(), 'uid' => $uid, 'total_price' => $totalAmount, 'pay_price' => $finalAmount, 'status' => self::ORDER_STATUS_UNPAID, 'add_time' => time() ]; // 保存订单 $orderId = $this->dao->save($orderData); ``` ## 💳 支付处理 ### 支付方式 ```php const PAY_TYPE_WECHAT = 'wechat'; // 微信支付 const PAY_TYPE_ALIPAY = 'alipay'; // 支付宝 const PAY_TYPE_BALANCE = 'balance'; // 余额支付 const PAY_TYPE_INTEGRAL = 'integral'; // 积分支付 ``` ### 支付回调处理 ```php public function payNotify($params) { // 验证支付结果 if ($this->verifyPayResult($params)) { // 更新订单状态 $this->updateOrderStatus($params['order_id'], self::ORDER_STATUS_PAID); // 记录支付流水 $this->savePayRecord($params); // 发送支付成功通知 $this->sendPaySuccessNotify($params['order_id']); } } ``` ## 📦 发货处理 ### 发货流程 ```php public function deliverOrder($orderId, $expressData) { // 检查订单状态 $order = $this->getOrderInfo($orderId); if ($order['status'] != self::ORDER_STATUS_PAID) { throw new ApiException('订单状态不允许发货'); } // 生成发货单 $deliverData = [ 'order_id' => $orderId, 'express_code' => $expressData['code'], 'express_number' => $expressData['number'], 'deliver_time' => time() ]; // 更新订单状态 $this->updateOrderStatus($orderId, self::ORDER_STATUS_SHIPPED); // 发送发货通知 $this->sendDeliverNotify($orderId); } ``` ## 🔄 售后处理 ### 退款申请 ```php public function applyRefund($orderId, $reason, $amount) { // 检查订单是否可退款 if (!$this->canRefund($orderId)) { throw new ApiException('该订单不可退款'); } // 创建退款记录 $refundData = [ 'order_id' => $orderId, 'refund_amount' => $amount, 'refund_reason' => $reason, 'status' => self::REFUND_STATUS_APPLY ]; // 更新订单状态 $this->updateOrderStatus($orderId, self::ORDER_STATUS_REFUNDING); } ``` ### 退款审核 ```php public function auditRefund($refundId, $status, $remark = '') { $refund = $this->getRefundInfo($refundId); if ($status == self::REFUND_STATUS_APPROVED) { // 执行退款 $this->doRefund($refund); // 更新订单状态 $this->updateOrderStatus($refund['order_id'], self::ORDER_STATUS_REFUNDED); } else { // 拒绝退款 $this->updateRefundStatus($refundId, self::REFUND_STATUS_REJECTED, $remark); // 恢复订单状态 $this->recoverOrderStatus($refund['order_id']); } } ``` ## 📊 订单统计 ### 常用统计方法 ```php // 今日订单统计 public function getTodayOrderStats() { $todayStart = strtotime('today'); $todayEnd = strtotime('tomorrow') - 1; return [ 'total' => $this->dao->where('add_time', 'between', [$todayStart, $todayEnd])->count(), 'amount' => $this->dao->where('add_time', 'between', [$todayStart, $todayEnd])->sum('pay_price'), 'paid' => $this->dao->where('add_time', 'between', [$todayStart, $todayEnd]) ->where('status', '>', 0)->count() ]; } ``` --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Phpapi/项目目录文档 (help/dev-docs/phpapi/项目目录文档.md) # CRMEB 项目目录文档 ## 1. 引言 - **文档目的**: 详细说明 CRMEB 项目的目录结构和各目录功能 - **适用范围**: 项目开发人员、维护人员、新成员 - **术语定义**: 无特殊术语 ## 2. 项目根目录结构 ### 2.1 目录树 ``` CRMEB/ ├── .comate/ # Comate 工具配置 ├── .env # 环境配置文件 ├── .git/ # Git 版本控制 ├── .gitignore # Git 忽略文件 ├── .idea/ # IDEA 编辑器配置 ├── .trae/ # Trae 工具配置 │ ├── rules/ # 规则配置 │ └── skills/ # 技能配置 ├── crmeb/ # 核心应用目录 ├── docker-compose/ # Docker 配置 ├── docs/ # 文档目录 ├── docs.zip # 文档压缩包 ├── LICENSE # 许可证文件 ├── readme/ # 说明文档 ├── README.md # 项目说明 ├── template/ # 模板文件 └── 安装必读.docx # 安装说明 ``` ### 2.2 根目录说明 - **.trae/**: Trae 工具配置目录,包含规则和技能配置 - **crmeb/**: 项目核心应用目录,包含所有业务逻辑 - **docker-compose/**: Docker 容器配置,用于快速部署 - **docs/**: 项目文档目录,存放各类说明文档 - **readme/**: 项目说明文档,包含功能介绍和截图 - **template/**: 模板文件目录,用于生成代码和配置 ## 3. 核心应用目录结构 (crmeb/) ### 3.1 目录树 ``` crmeb/ ├── .constant # 常量定义 ├── .env # 应用环境配置 ├── .htaccess # Apache 配置 ├── .phpstorm.meta.php # PHPStorm 元数据 ├── .travis.yml # Travis CI 配置 ├── .version # 版本信息 ├── app/ # 应用核心目录 ├── backup/ # 备份目录 ├── build.example.php # 构建配置示例 ├── composer.json # Composer 依赖配置 ├── composer.lock # Composer 依赖锁定 ├── config/ # 配置文件目录 ├── crmeb/ # 核心库目录 ├── filetree.txt # 文件树结构 ├── index.html # 入口 HTML ├── install.lock # 安装锁定 ├── LICENSE.txt # 许可证文件 ├── public/ # 静态资源目录 ├── README.md # 应用说明 ├── route/ # 路由配置目录 ├── runtime/ # 运行时目录 ├── think # ThinkPHP 命令行工具 ├── vendor/ # 依赖库目录 └── workerman.bat # Workerman 启动脚本 ``` ### 3.2 核心目录说明 - **app/**: 应用核心目录,包含所有业务逻辑 - **config/**: 配置文件目录,存放应用配置 - **crmeb/**: 核心库目录,提供基础功能 - **public/**: 静态资源目录,存放前端文件 - **route/**: 路由配置目录,定义 URL 路由 - **runtime/**: 运行时目录,存放缓存和日志 - **vendor/**: 依赖库目录,Composer 安装的依赖 ## 4. 应用核心目录结构 (app/) ### 4.1 目录树 ``` app/ ├── adminapi/ # 后台 API 接口 ├── api/ # 前端 API 接口 ├── AppService.php # 应用服务 ├── build.php # 构建配置 ├── common.php # 公共函数 ├── dao/ # 数据访问层 ├── event.php # 事件配置 ├── ExceptionHandle.php # 异常处理 ├── filetree.txt # 文件树结构 ├── http/ # HTTP 相关 ├── jobs/ # 队列任务 ├── kefuapi/ # 客服 API 接口 ├── lang/ # 语言包 ├── listener/ # 事件监听器 ├── middleware.php # 中间件配置 ├── model/ # 数据模型 ├── outapi/ # 外部 API 接口 ├── provider.php # 服务提供者 ├── README.md # 目录说明 ├── Request.php # 请求基类 ├── service.php # 服务配置 └── services/ # 业务逻辑层 ``` ### 4.2 核心目录说明 - **adminapi/**: 后台管理系统 API 接口,处理后台请求 - **api/**: 前端应用 API 接口,处理客户端请求 - **dao/**: 数据访问层,封装数据库操作 - **jobs/**: 队列任务,处理异步操作 - **kefuapi/**: 客服系统 API 接口 - **model/**: 数据模型,定义数据结构 - **outapi/**: 外部系统 API 接口 - **services/**: 业务逻辑层,实现核心业务功能 ## 5. 核心模块说明 ### 5.1 控制器层 (api/, adminapi/, kefuapi/) - 处理 HTTP 请求 - 路由分发 - 参数验证 - 返回响应 ### 5.2 业务逻辑层 (services/) - 实现核心业务逻辑 - 调用数据访问层 - 处理业务规则 ### 5.3 数据访问层 (dao/) - 封装数据库操作 - 提供数据查询方法 - 处理数据持久化 ### 5.4 数据模型层 (model/) - 定义数据结构 - 关联关系 - 数据验证 ### 5.5 配置层 (config/) - 应用配置 - 数据库配置 - 缓存配置 - 日志配置 ## 6. 静态资源目录 (public/) - **css/**: 样式文件 - **js/**: JavaScript 文件 - **images/**: 图片文件 - **fonts/**: 字体文件 - **uploads/**: 上传文件 ## 7. 配置文件说明 ### 7.1 核心配置文件 - **.env**: 环境变量配置 - **config/app.php**: 应用配置 - **config/database.php**: 数据库配置 - **config/cache.php**: 缓存配置 ### 7.2 路由配置 - **route/api.php**: API 路由 - **route/adminapi.php**: 后台 API 路由 - **route/kefuapi.php**: 客服 API 路由 ## 8. 核心文件说明 ### 8.1 入口文件 - **public/index.php**: 应用入口文件 - **think**: 命令行工具 ### 8.2 基础类 - **app/Request.php**: 请求基类 - **app/ExceptionHandle.php**: 异常处理类 - **app/AppService.php**: 应用服务类 ### 8.3 配置文件 - **composer.json**: 依赖管理 - **.htaccess**: Apache 重写规则 ## 9. 目录使用建议 ### 9.1 开发规范 - **新增文件**: 按照对应模块目录结构存放 - **修改文件**: 保持原有目录结构 - **删除文件**: 确认无依赖后删除 ### 9.2 命名规范 - **目录名**: 小写单词,无特殊字符 - **文件名**: 驼峰命名或小写下划线 - **类名**: PascalCase - **方法名**: camelCase ## 10. 总结 ### 10.1 目录结构特点 - **分层清晰**: 遵循 MVC 架构,分层明确 - **模块分离**: 按功能模块划分目录 - **配置集中**: 配置文件统一管理 - **资源分离**: 静态资源单独存放 ### 10.2 后续计划 - 定期更新目录结构文档 - 根据项目演进调整目录结构 - 保持目录结构的合理性和可维护性 --- 版本: 1.0 作者: 系统生成 更新日期: 2026-01-23 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Uniapp/Uniapp目录结构 (help/dev-docs/uniapp/uniapp目录结构.md) # CRMEB 项目 uniapp 目录结构文档 ## 1. 引言 - **文档目的**: 详细说明 CRMEB 项目中 uniapp 目录结构和各目录功能 - **适用范围**: 移动端开发人员、前端开发人员、项目维护人员 - **术语定义**: uniapp - 基于 Vue.js 的跨平台应用开发框架 ## 2. 目录结构 ### 2.1 目录树 ``` uni-app/ ├── androidPrivacy.json # Android 隐私政策配置 ├── api/ # API 接口目录 ├── App.vue # 应用入口组件 ├── components/ # 公共组件目录 ├── config/ # 配置文件目录 ├── libs/ # 第三方库目录 ├── main.js # 应用入口文件 ├── manifest.json # 应用配置文件 ├── mixins/ # 混入文件目录 ├── package-lock.json # npm 依赖锁定文件 ├── package.json # npm 依赖配置文件 ├── pages/ # 页面目录 ├── pages.json # 页面路由配置文件 ├── plugin/ # 插件目录 ├── static/ # 静态资源目录 ├── store/ # 状态管理目录 ├── uni.scss # 全局样式文件 ├── utils/ # 工具函数目录 └── vue.config.js # Vue 配置文件 ``` ### 2.2 目录功能说明 #### 2.2.1 核心目录 - **api/**: 存放 API 接口定义,包含所有后端接口调用 - **components/**: 存放公共组件,可在多个页面复用 - **pages/**: 存放应用页面,每个页面对应一个子目录 - **static/**: 存放静态资源,如图片、字体、图标等 - **utils/**: 存放工具函数,如日期处理、请求封装等 #### 2.2.2 配置目录 - **config/**: 存放应用配置,如 API 地址、常量定义等 - **mixins/**: 存放混入文件,用于复用组件逻辑 - **store/**: 存放 Vuex 状态管理文件 - **libs/**: 存放第三方库,如 SDK、工具库等 #### 2.2.3 插件目录 - **plugin/**: 存放应用插件,如支付插件、分享插件等 ## 3. 核心文件说明 ### 3.1 入口文件 - **App.vue**: 应用根组件,全局配置和生命周期管理 - **main.js**: 应用入口文件,初始化 Vue 实例和全局配置 ### 3.2 配置文件 - **manifest.json**: 应用配置文件,包含应用名称、版本、权限等 - **pages.json**: 页面路由配置文件,定义页面路径、导航栏等 - **vue.config.js**: Vue 项目配置文件,如代理配置、构建配置等 ### 3.3 样式文件 - **uni.scss**: 全局样式文件,定义主题变量和通用样式 ### 3.4 依赖文件 - **package.json**: npm 依赖配置文件,管理项目依赖 - **package-lock.json**: npm 依赖锁定文件,确保依赖版本一致 ## 4. 页面目录结构 ### 4.1 页面组织方式 ``` pages/ ├── index/ # 首页 │ ├── index.vue # 页面组件 │ └── main.js # 页面入口(可选) ├── goods/ # 商品相关页面 │ ├── list.vue # 商品列表 │ └── detail.vue # 商品详情 └── user/ # 用户相关页面 ├── index.vue # 用户中心 └── login.vue # 登录页面 ``` ### 4.2 页面文件说明 - **页面组件 (.vue)**: 包含模板、脚本和样式 - **页面入口 (main.js)**: 页面级别的初始化配置(可选) ## 5. 开发规范 ### 5.1 命名规范 - **目录名**: 小写单词,多个单词用连字符(-)分隔 - **文件名**: 小写单词,多个单词用连字符(-)分隔 - **组件名**: PascalCase 命名法 - **变量名**: camelCase 命名法 - **常量名**: 全大写,多个单词用下划线(_)分隔 ### 5.2 代码规范 - 遵循 Vue 官方风格指南 - 使用 ES6+ 语法 - 组件化开发,提高代码复用性 - 合理使用 Vuex 管理全局状态 - 页面逻辑清晰,避免过度嵌套 ### 5.3 性能优化 - 图片资源优化,使用适当尺寸和格式 - 减少 HTTP 请求,合理使用缓存 - 组件懒加载,减少初始包大小 - 避免在模板中使用复杂计算 - 合理使用 uni-app 提供的性能优化 API ## 6. 注意事项 ### 6.1 跨平台兼容性 - 注意不同平台的 API 差异 - 避免使用平台特定的特性 - 测试时覆盖主要平台(iOS、Android、微信小程序等) ### 6.2 打包配置 - 根据不同平台配置相应的打包参数 - 注意应用权限配置 - 合理配置应用图标和启动页 ### 6.3 调试技巧 - 使用 uni-app 开发者工具进行调试 - 利用 console.log 输出调试信息 - 关注控制台警告和错误信息 ## 7. 总结 ### 7.1 目录结构特点 - **结构清晰**: 遵循 uni-app 官方推荐的目录结构 - **模块化强**: 按功能模块化组织代码 - **易于维护**: 目录职责明确,代码结构合理 - **扩展性好**: 便于添加新功能和页面 ### 7.2 后续计划 - 完善组件库,提高代码复用性 - 优化页面性能,提升用户体验 - 增加自动化测试,确保代码质量 - 持续更新依赖库,保持框架先进性 --- 版本: 1.0 作者: 系统生成 更新日期: 2026-01-23 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Dev Docs/Uniapp/移动端前端架构说明 (help/dev-docs/uniapp/移动端前端架构说明.md) # CRMEB 移动端前端架构说明 ## 📱 技术栈概览 | 技术 | 版本 | 说明 | |------|------|------| | UniApp | 2.x/3.x | 跨端开发框架 | | Vue.js | 2.x/3.x | 核心框架 | | Vuex | 3.x/4.x | 状态管理 | | uView UI | 2.x | 移动端UI组件库 | | Sass/Less | CSS预处理器 | | | Axios | HTTP客户端 | 封装请求 | ## 🏗️ 整体架构 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 🧩 核心功能模块 ### 1. 商品模块 - 商品列表展示 - 商品详情页 - 商品搜索 - 商品分类 ### 2. 购物车模块 - 添加商品到购物车 - 购物车管理 - 批量操作 ### 3. 订单模块 - 订单创建 - 订单列表 - 订单详情 - 订单状态跟踪 ### 4. 用户模块 - 用户登录注册 - 个人中心 - 地址管理 - 收藏管理 ### 5. 支付模块 - 微信支付 - 支付宝支付 - 余额支付 ## 🔧 开发最佳实践 ### 1. 页面生命周期 ```javascript export default { // 页面加载 onLoad(options) { this.initPage(options) }, // 页面显示 onShow() { this.refreshData() }, // 下拉刷新 onPullDownRefresh() { this.loadData().finally(() => { uni.stopPullDownRefresh() }) }, // 上拉加载 onReachBottom() { this.loadMore() }, methods: { async initPage(options) { // 初始化页面数据 }, async refreshData() { // 刷新数据 } } } ``` ### 2. 组件通信 ```javascript // 父传子 // 子组件 export default { props: { data: { type: Object, default: () => ({}) } }, methods: { emitEvent() { this.$emit('custom-event', eventData) } } } ``` ### 3. 状态管理 ```javascript // 使用 Vuex import { mapState, mapActions } from 'vuex' export default { computed: { ...mapState('user', ['userInfo']), ...mapState('cart', ['cartList']) }, methods: { ...mapActions('user', ['login']), ...mapActions('cart', ['addToCart']) } } ``` ## 🎯 性能优化 ### 1. 图片优化 ```javascript // 使用懒加载 // 使用webp格式 // 使用合适的图片尺寸 ``` ### 2. 数据缓存 ```javascript // 使用本地存储 uni.setStorageSync('key', data) const data = uni.getStorageSync('key') // 使用内存缓存 const cache = new Map() cache.set('key', data) const data = cache.get('key') ``` ### 3. 请求优化 ```javascript // 防抖处理 const debounce = (func, wait) => { let timeout return function() { clearTimeout(timeout) timeout = setTimeout(() => func.apply(this, arguments), wait) } } // 使用 search: debounce(function(keyword) { this.doSearch(keyword) }, 300) ``` ## 📦 多端适配 ### 1. 条件编译 ```javascript // #ifdef H5 console.log('只在H5平台显示') // #endif // #ifdef MP-WEIXIN console.log('只在微信小程序显示') // #endif // #ifdef APP-PLUS console.log('只在App显示') // #endif ``` ### 2. 平台差异处理 ```javascript const platform = { isH5: uni.getSystemInfoSync().platform === 'h5', isWeapp: uni.getSystemInfoSync().platform === 'devtools', isApp: uni.getSystemInfoSync().platform === 'app' } // 使用 if (platform.isH5) { // H5特有逻辑 } ``` ## 🚀 部署发布 ### 1. 小程序发布 ```bash # 微信小程序 npm run build:mp-weixin # 然后使用微信开发者工具上传 # 支付宝小程序 npm run build:mp-alipay ``` ### 2. H5部署 ```bash # 构建H5 npm run build:h5 # 部署到服务器 scp -r dist/build/h5 user@server:/path/to/www ``` ### 3. App发布 ```bash # 构建App npm run build:app # 使用HBuilderX进行打包和发布 ``` ## 🔍 调试技巧 ### 1. 开发工具使用 ```javascript // 打印调试信息 console.log('调试信息', data) // 使用debugger debugger // 性能监控 console.time('operation') // 执行操作 console.timeEnd('operation') ``` ### 2. 真机调试 ```javascript // 使用uni-app调试工具 // 1. 连接手机和电脑 // 2. 开启USB调试 // 3. 使用HBuilderX真机运行 ``` ## 📝 代码规范 ### 1. 命名规范 ```javascript // 变量命名 - 小驼峰 const userName = 'John' let isLoading = false // 常量命名 - 全大写 const API_BASE_URL = 'https://api.example.com' const MAX_COUNT = 100 // 组件命名 - 大驼峰 // MyComponent.vue export default { name: 'MyComponent' } ``` ### 2. 代码组织 ```javascript // 文件结构 export default { // 1. 组件名 name: 'ComponentName', // 2. 组件属性 props: {}, // 3. 数据 data() { return {} }, // 4. 计算属性 computed: {}, // 5. 监听器 watch: {}, // 6. 生命周期 mounted() {}, // 7. 方法 methods: {} } ``` --- **文档版本**: v1.0 **更新日期**: 2024-01-17 **适用版本**: CRMEB 5.6.4+ 💡 提示:移动端开发需要特别注意性能优化和多端适配,建议使用uni-app的Conditional Compile功能处理平台差异。 --- > **提示**:该文档由AI生成,仅供参考。 --- ### Help/Docker/README (help/docker/README.md) # 安装docker ## docker 官网下载 https://www.docker.com/products/docker-desktop ## 命令安装 ``` curl -sSL https://get.daocloud.io/docker | sh ``` # 方式一:一键启动CRMEB 系统 ``` docker run -d \ --name crmeb_app \ -p 8111:80 \ -v $(pwd)/crmeb/runtime:/var/www/crmeb/runtime \ -v $(pwd)/crmeb/uploads:/var/www/crmeb/public/uploads \ -v $(pwd)/crmeb_mysql:/var/lib/mysql \ -v $(pwd)/crmeb_redis:/var/lib/redis \ -e TZ=Asia/Shanghai \ ccr.ccs.tencentyun.com/zbkj/crmebky:latest ``` # 方式二:docker-compose 快速运行项目 ## 1、安装docker-compose https://www.runoob.com/docker/docker-compose.html ## 2、下载CRMEB程序 建议去下载最新开源代码 https://gitee.com/ZhongBangKeJi/CRMEB 程序放到docker 同级目录下 ## 3、启动项目 ``` 进入docker-compose目录 cd /docker 运行命令: ``` docker-compose up -d ``` ## 4、访问CRMEB 系统 移动端访问地址:http://localhost:8011/ PC端访问地址:http://localhost:8011/admin ## 5、安装CRMEB ### Mysql数据库信息: ``` Host:crmeb_mysql Post:3306 user:crmeb pwd:123456 ``` ### Redis信息: ``` Host:crmeb_redis Post:6379 db:0 pwd:123456 ``` ## 6、常见错误及解决方案 ### 6.1 MySQL 启动失败 **错误现象**:MySQL 容器启动失败,日志显示 "--initialize specified but the data directory has files in it. Aborting." **解决方案**: 1. 停止所有容器:`docker-compose down` 2. 清空数据目录:`rm -rf mysql/data/*` 3. 重新启动服务:`docker-compose up -d` **原因**:MySQL 数据目录不为空,导致初始化失败。 ### 6.2 数据目录映射问题 **错误现象**:数据库无法启动或数据无法持久化 **解决方案**: 1. 确保 `mysql/data` 目录存在:`mkdir -p mysql/data` 2. 确保 `mysql/data` 目录为空 3. 确保 docker-compose.yml 中正确配置了数据卷映射: ```yaml volumes: - ./mysql/data:/var/lib/mysql ``` **原因**:数据目录未映射或映射不正确,导致数据库无法创建或数据丢失。 ## 6.3 常见需要映射的目录说明 ### 6.3.1 MySQL 数据目录 - **本地路径**:`mysql/data` - **容器路径**:`/var/lib/mysql` - **用途**:存储 MySQL 数据库的数据文件 - **注意事项**:必须为空目录,否则 MySQL 初始化会失败 ### 6.2 MySQL 日志目录 - **本地路径**:`mysql/log` - **容器路径**:`/var/log/mysql` - **用途**:存储 MySQL 的日志文件 - **注意事项**:确保目录存在且有读写权限 ### 6.3.2 PHP 应用目录 - **本地路径**:`../../crmeb` - **容器路径**:`/var/www` - **用途**:存储 CRMEB 应用代码 - **注意事项**:确保目录存在且包含完整的 CRMEB 代码 ### 6.3.3 PHP 运行时目录 - **本地路径**:`../../crmeb/runtime` - **容器路径**:`/var/www/runtime` - **用途**:存储 PHP 应用的运行时文件,如缓存、日志等 - **注意事项**:确保目录存在且有读写权限 ### 6.3.4 Nginx 配置目录 - **本地路径**:`./nginx/vhost.conf` - **容器路径**:`/etc/nginx/conf.d/default.conf` - **用途**:Nginx 虚拟主机配置文件 - **注意事项**:确保配置文件存在且格式正确 ### 6.3.5 Nginx 日志目录 - **本地路径**:`./nginx/log` - **容器路径**:`/etc/nginx/log` - **用途**:存储 Nginx 的日志文件 - **注意事项**:确保目录存在且有读写权限 ### 6.3.6 目录创建命令 ```bash # 创建所有必要的目录 mkdir -p mysql/data mysql/log nginx/log # 确保 CRMEB 应用目录存在 mkdir -p ../crmeb ../crmeb/runtime ``` --- ### Help/Docker/Docker Compose.Yml (help/docker/docker-compose.yml) services: # mysql 容器 mysql: container_name: crmeb_mysql image: ccr.ccs.tencentyun.com/crmebky_php/mysql:v8.0.45 ports: - "33061:3306" environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: 123456 MYSQL_USER: crmeb MYSQL_PASSWORD: 123456 MYSQL_DATABASE: crmeb volumes: - ./mysql/data:/var/lib/mysql - ./mysql/log:/var/log/mysql networks: app_net: ipv4_address: 192.168.10.11 # redis 容器 redis: container_name: crmeb_redis image: ccr.ccs.tencentyun.com/crmebky_php/redis:v8.6.1 ports: - "63791:6379" environment: TZ: Asia/Shanghai REDIS_PASSWORD: 123456 networks: app_net: ipv4_address: 192.168.10.10 # php 容器 phpfpm: container_name: crmeb_php image: ccr.ccs.tencentyun.com/crmebky_php/php:v7.4 restart: always environment: TZ: Asia/Shanghai MYSQL_HOST_IP: crmeb_mysql MYSQL_PORT: "3306" MYSQL_USER: crmeb MYSQL_PASSWORD: 123456 MYSQL_DATABASE: crmeb REDIS_HOST_IP: crmeb_redis REDIS_PORT: "6379" REDIS_DATABASE: "0" REDIS_PASSWORD: 123456 APP_DEBUG: true DEFAULT_TIMEZONE: Asia/Shanghai ports: - "9000:9000" - "40001:40001" - "40002:40002" working_dir: /var/www volumes: - ../../crmeb:/var/www - ../../crmeb/runtime:/var/www/runtime networks: app_net: ipv4_address: 192.168.10.90 # nginx 容器 nginx: container_name: crmeb_nginx image: ccr.ccs.tencentyun.com/crmebky_php/nginx:v1.29.6 restart: always ports: - "8011:80" depends_on: - phpfpm environment: TZ: Asia/Shanghai working_dir: /var/www volumes_from: - phpfpm volumes: - ./nginx/vhost.conf:/etc/nginx/conf.d/default.conf - ./nginx/log:/etc/nginx/log networks: app_net: ipv4_address: 192.168.10.80 networks: app_net: driver: bridge ipam: driver: default config: - subnet: 192.168.10.0/24 --- ### Template/README (template/README.md) # Template 目录说明文档 ## 目录结构 `template` 目录包含 CRMEB 系统的前端项目代码,主要分为两个子项目: ``` template/ ├── admin/ # 管理端前端项目(Vue.js + Element UI) └── uni-app/ # 移动端前端项目(UniApp) ``` ## 项目说明 ### 1. 管理端前端项目 (admin/) 管理端前端项目基于 Vue.js + Element UI 开发,用于后台管理系统的操作界面。 #### 主要目录结构 ``` admin/ ├── public/ # 静态资源目录 ├── src/ # 源代码目录 │ ├── api/ # API 接口定义 │ ├── assets/ # 静态资源文件 │ ├── components/ # 通用组件 │ ├── config/ # 配置文件 │ ├── directive/ # 自定义指令 │ ├── filters/ # 过滤器 │ ├── layout/ # 布局组件 │ ├── libs/ # 工具库 │ ├── pages/ # 页面组件 │ ├── router/ # 路由配置 │ ├── store/ # 状态管理 │ ├── styles/ # 样式文件 │ ├── utils/ # 工具函数 │ ├── App.vue # 根组件 │ └── main.js # 入口文件 ├── .env.dev # 开发环境配置 ├── .env.production # 生产环境配置 ├── package.json # 项目依赖 ├── vue.config.js # Vue 配置 └── README.md # 项目说明 ``` #### 技术栈 - Vue.js 2.x - Element UI - Vue Router - Vuex - Axios - ECharts #### 开发命令 - 安装依赖:`npm install` - 开发环境运行:`npm run dev` - 生产环境构建:`npm run build` - 代码检查:`npm run lint` ### 2. 移动端前端项目 (uni-app/) 移动端前端项目基于 UniApp 开发,支持多端发布(微信小程序、H5、App 等)。 #### 主要目录结构 ``` uni-app/ ├── api/ # API 接口定义 ├── components/ # 通用组件 ├── config/ # 配置文件 ├── libs/ # 工具库 ├── mixins/ # 混合器 ├── pages/ # 页面组件 ├── static/ # 静态资源 ├── App.vue # 根组件 ├── main.js # 入口文件 ├── manifest.json # 应用配置 ├── pages.json # 页面配置 └── package.json # 项目依赖 ``` #### 技术栈 - UniApp - Vue.js 2.x - uView UI (UniApp 组件库) - Vuex - Axios #### 开发命令 - 安装依赖:`npm install` - 开发环境运行:使用 HBuilderX 运行到对应平台 - 生产环境构建:使用 HBuilderX 发行到对应平台 ## 前端与后端交互 前端项目通过 API 接口与后端进行交互,主要配置如下: ### 管理端 API 配置 - 开发环境:`admin/.env.dev` 文件中的 `VUE_APP_API_URL` - 生产环境:`admin/.env.production` 文件中的 `VUE_APP_API_URL` ### 移动端 API 配置 - 配置文件:`uni-app/config/api.js` - API 基础路径:`baseURL` 变量 ## 部署说明 ### 管理端部署 1. 执行构建命令:`npm run build` 2. 将 `admin/dist` 目录下的文件部署到 Web 服务器 3. 配置 Nginx 或 Apache 服务器,指向构建后的静态文件 ### 移动端部署 1. 使用 HBuilderX 打开 `uni-app` 目录 2. 根据需要发行到对应平台: - 微信小程序:发行 -> 小程序-微信 - H5:发行 -> H5 - App:发行 -> 原生 App-云打包 ## 开发规范 ### 代码风格 - 遵循 Vue 官方风格指南 - 使用 ESLint 进行代码检查 - 组件名使用 PascalCase - 方法和变量名使用 camelCase ### 命名规范 - 文件和目录名使用 kebab-case - 组件名使用 PascalCase - 常量使用全大写,单词间用下划线分隔 ### 目录使用 - `api/`:按模块组织 API 接口 - `components/`:存放可复用组件 - `pages/`:存放页面组件 - `utils/`:存放工具函数 - `styles/`:存放全局样式 ## 注意事项 1. **API 接口**:前端项目需要与后端 API 接口保持一致,如有接口变更,需要同步修改前端代码。 2. **环境配置**:不同环境下的 API 地址需要在对应配置文件中修改。 3. **依赖管理**:使用 npm 管理项目依赖,确保依赖版本的一致性。 4. **构建优化**:生产环境构建时会自动进行代码压缩和优化。 5. **跨域处理**:开发环境下使用 Vue CLI 的代理配置处理跨域问题,生产环境需要在服务器端配置 CORS。 6. **性能优化**: - 合理使用组件懒加载 - 优化图片资源 - 减少不必要的 API 请求 - 使用缓存减少重复数据获取 ## 常见问题 ### 1. 开发环境 API 调用失败 - 检查 `.env.dev` 文件中的 API 地址是否正确 - 检查后端服务是否正常运行 - 检查网络连接是否正常 ### 2. 构建后页面空白 - 检查路由配置是否正确 - 检查是否有未捕获的错误 - 检查静态资源路径是否正确 ### 3. 移动端适配问题 - 使用 Flex 布局进行响应式设计 - 针对不同设备尺寸进行适配 - 测试不同设备的显示效果 ## 联系与支持 - 官方文档:https://doc.crmeb.com - 技术社区:https://www.crmeb.com/ask - 官方 QQ 群:请参考官方网站 ## 版本信息 - CRMEB 版本:5.6.4 - 管理端前端:Vue 2.x + Element UI - 移动端前端:UniApp --- **说明**:本目录为前端项目代码,后端代码位于项目根目录的 `crmeb/` 目录中。 --- ### Template/Admin/README (template/admin/README.md) # CRMEB Admin ## 开发规范 统一使用ES6 语法 方法注释 /* * th => 表头 * data => 数据 * fileName => 文件名 * fileType => 文件类型 * sheetName => sheet页名 */ export default function toExcel ({ th, data, fileName, fileType, sheetName }) 行注释 // ### 命名 页面目录 文件夹命名格式骆驼式命名法,例如:用户列表 userList 例如:商品模块 product 商品 ├─ product 商品管理 ├─ productList 商品管理目录 ├─ index.vue 首页 ├─ components 组建 ├─ tableFrom.vue ├─ tableList.vue ├─ handle 操作功能页面目录 ├─ delete.vue ├─ productCategory 商品分类目录 ├─ index.vue 商品分类首页 页面命名、组建、文件夹 命名格式小驼峰命名法,例如:用户列表 userList 类名函数命名 大驼峰式 例如:addUser 变量命名 小驼峰式 例如:user 或者 userInfo _userinfo user-info 常量 采用全大些下划线命名 例如:VUE_APP_API_URl ### 文件管理规范 pages 页面模块必须件文件夹区分 api 接口一个模块一个文件 组建 一个组建一个文件夹 plugins 插件一个插件一个文件夹 vuex 路由状态管理,一个模块在modules 中建一个文件夹 router 一个模块一个模块在modules 中建一个文件夹 style 样式尽量采用iView自带组建,common.less 系统通用样式不要轻易动 自定义通用样式 style.less,每次添加必须加注释,页面独立样式在在页面内写,后缀less 格式 组建样式 styles 中添加文件夹 composents 对应components 目录新建样式文件 utils 自定义工具js 独立命名,一般不用新建文件夹 ## 模块命名 ~~~ ├─ product 商品管理 ├─ user 用户管理 ├─ order 系统订单管理 ├─ setting 系统设置维护 系统权限管理、系统菜单管理 客服管理 ├─ chat 客服管理(列表,添加,删除,编辑) ├─ application 各个应用模块功能管理公众号、小程序、支付宝、百度小程序、今日头条小程序 ├─ system 系统更新日志 数据库管理 ├─ finance 财务管理 ├─ agent 分销管理 ├─ marketing 优惠券、积分、拼团、砍价、秒杀 ├─ echarts 数据统计分析 ├─ notification 消息通知管理、模版消息(列表,通知,添加,编辑)、短信 ├─ file 附件文件管理 ├─ freight 运费模版管理 物流公司 ├─ merchant 商户管理 ├─ widget 组件 小插件 └─ cms 文章管理 ~~~ ## 目录结构 主要目录结构及说明: ~~~ ├── public # 静态资源 │ ├── favicon.ico # favicon图标 │ └── index.html # html 模板 ├── src # 源代码 │ ├── api # 所有请求 │ │ └──account.js # 有关登录的接口 │ │ └──agent.js # 有关分销的接口 │ │ └──app.js # 有关应用(小程序、公众号)的接口 │ │ └──cms.js # 有关内容(文章管理、分类)的接口 │ │ └──common.js # 表格删除、获取消息提醒的接口 │ │ └──finance.js # 有关财务的接口 │ │ └──index.js # 有关首页的接口 │ │ └──marketing.js # 有关营销的接口 │ │ └──order.js # 有关订单的接口 │ │ └──product.js # 有关商品的接口 │ │ └──setting.js # 有关设置的接口 │ │ └──system.js # 有关维护(开发配置、安全维护)的接口 │ │ └──systemAdmin.js # 有关管理员的接口(设置--管理权限--管理员列表) │ │ └──systemMenus.js # 有关权限规则的接口(设置--管理权限--权限规则) │ │ └──uploadPictures.js # 有关上传图片附件的接口 │ │ └──user.js # 有关会员的接口 │ ├── assets # 图片、svg 等静态资源 │ ├── components # 公共组件 │ │ └──cards # 统计 │ │ └──copyright # 页面footer的底部声明 │ │ └──customerInfo # 选择用户 │ │ └──echarts # 统计图 │ │ └──freightTemplate # 运费模板 │ │ └──from # 生成表单 │ │ └──goodsList # 商品列表 │ │ └──iconFrom # 导航添加图标 │ │ └──link # a连接 │ │ └──mde # 多文本框 │ │ └──modelSure # 确认模态框 │ │ └──newsCategory # 图文管理页 │ │ └──publicSearchFrom # 头部搜索(没用到) │ │ └──quill # 编辑器(没用到) │ │ └──referrerInfo # 推荐人信息 │ │ └──searchFrom # 订单页的搜索 │ │ └──sendCoupons # 发送优惠券 │ │ └──systemStore # 添加提货点 │ │ └──uploadPictures # 上传图片 │ │ └──uploadVideo # 上传视频(用于商品编辑器里面) │ ├── i18n # 多语言 │ ├── layouts # 布局 │ │ └──header-breadcrumb # 头部面包屑样式 │ │ └──header-collapse # 头部控制折叠面板的图标 │ │ └──header-fullscreen # 头部控制是否全屏的图标 │ │ └──header-i18n # 头部控制多语言 │ │ └──header-log # 头部控制日志异常图标 │ │ └──header-logo # 头部logo │ │ └──header-notice # 头部提示消息 │ │ └──header-reload # 头部控制刷新的图标 │ │ └──header-search # 头部搜索 │ │ └──header-setting # 设置页面风格 │ │ └──header-user # 我的(个人中心、退出登录) │ │ └──menu-head # │ │ └──menu-side # 侧边导航栏 │ │ └──tabs # 头部的横向导航标签 │ │ └──mixins # 用于横向滚动获取title的一个js │ ├── libs # 公共方法 │ ├── menu # 菜单配置 │ ├── mixins # 通用混合 │ ├── mock # 数据模拟 │ ├── pages # 所有页面 │ │ └──account # 有关登录页 │ │ └──login # 登录 │ │ └──register # 注册 │ │ └──agent # 分销 │ │ └──agentManage # 分销员管理 │ │ └──app # 应用 │ │ └──routine # 小程序模板消息 │ │ └──wechat # 公众号 │ │ └──menus # 微信菜单 │ │ └──newsCategory # 图文管理 │ │ └──save # 图文添加 │ │ └──reply # 自动回复 │ │ └──follow # 微信关注回复/无效关键词回复 │ │ └──keyword # 关键字回复 │ │ └──user # 用户 │ │ └──tag # 用户标签 │ │ └──user # 微信用户 │ │ └──message # 用户行为记录 │ │ └──cms # 内容 │ │ └──addArticle # 添加文章/编辑文章 │ │ └──article # 文章管理 │ │ └──articleCategory # 文章分类 │ │ └──finance # 财务 │ │ └──commission # 佣金记录 │ │ └──financialRecords # 财务记录 │ │ └──bill # 资金记录 │ │ └──recharge # 充值记录 │ │ └──userExtract # 提现申请 │ │ └──index # 主页 │ │ └──marketing # 营销 │ │ └──storeBargain # 砍价商品 │ │ └──storeCombination # 拼团管理 │ │ └──combinaList # 拼团列表 │ │ └──create # 添加拼团商品 │ │ └──index # 拼团商品 │ │ └──storeCoupon # 优惠券制作 │ │ └──storeCouponIssue # 优惠券列表 │ │ └──storeCouponUser # 会员领取记录 │ │ └──storeSeckill # 秒杀管理 │ │ └──index # 秒杀商品 │ │ └──create # 添加秒杀商品 │ │ └──userPoint # 积分日志 │ │ └──notify # 短信设置 │ │ └──smsConfig # 短信账户 │ │ └──smsPay # 短信购买 │ │ └──smsTemplateApply # 短信模板 │ │ └──order # 订单管理 │ │ └──product # 商品 │ │ └──productAdd # 添加商品 │ │ └──productAttr # 商品规格 │ │ └──productClassify # 商品分类 │ │ └──productList # 商品管理 │ │ └──productReply # 商品评论管理 │ │ └──setting # 设置 │ │ └──cityDada # 城市数据 │ │ └──clerkList # 核销员管理 │ │ └──freight # 物流公司 │ │ └──setSystem # 系统设置 │ │ └──shippingTemplates # 运费模板 │ │ └──storeList # 提货点列表 │ │ └──storeService # 客服管理 │ │ └──systemAdmin # 管理员列表 │ │ └──systemMenus # 权限规则 │ │ └──systemRole # 身份管理 │ │ └──systemStore # 门店设置 │ │ └──user # 个人中心 │ │ └──verifyOrder # 核销订单 │ │ └──system # 维护 │ │ └──auth # 商业授权 │ │ └──clear # 刷新缓存 │ │ └──configTab # 配置 │ │ └──index # 配置分类 │ │ └──list # 配置列表 │ │ └──error # 错误页 │ │ └──403 # 403 │ │ └──404 # 404 │ │ └──500 # 500 │ │ └──group # 组合数据 │ │ └──maintain │ │ └──systemCleardata # 清除数据 │ │ └──systemDatabackup # 数据备份 │ │ └──systemFile # 文件校验 │ │ └──opendir # 文件管理 │ │ └──systemLog # 系统日志 │ │ └──user # 会员 │ │ └──group # 会员分组 │ │ └──label # 会员标签 │ │ └──level # 会员等级 │ │ └──list # 会员管理 │ ├── plugins # 插件 │ ├── router # 路由配置 │ │ └──modules # 页面路由模块 │ │ └──agent.js # 有关分销 │ │ └──app.js # 有关应用(小程序、公众号) │ │ └──cms.js # 有关内容(文章管理、文章分类) │ │ └──echarts.js # 有关统计 │ │ └──finance.js # 有关财务 │ │ └──index.js # 有关主页 │ │ └──marketing.js # 有关营销 │ │ └──order.js # 有关订单 │ │ └──product.js # 有关商品 │ │ └──setting.js # 有关设置 │ │ └──system.js # 有关维护 │ │ └──user.js # 有关会员 │ │ └──index.js # 路由的导出以及拦截处理 │ │ └──routes.js # 路由的汇总 │ ├── store # Vuex 状态管理 │ ├── utils # js工具 │ │ └──authLapse.js # 授权提示框 │ │ └──modalForm.js # 表单模态框 │ │ └──videoCloud.js # 上传云储存视频(七牛、腾讯、阿里) │ │ └──validate.js # 将时间戳转化成时间; │ │ └──public.js # 询问模态框; │ ├── styles # 样式管理 │ ├── setting.env.js # 开发配置文件 │ ├── setting.js # 业务配置文件 │ ├── main.js # 入口文件 加载组件 初始化等 │ └── App.vue # 入口页面 ├── tests # 测试管理 ├── alias.config.js # 别名,仅用于配置 WebStorm 识别别名,无实际用处 ├── babel.config.js # babel 配置 ├── jest.config.js # jest 配置 ├── package.json # package.json └── vue.config.js # Vue CLI 3 配置 ~~~ ## 开发打包项目 ~~~ # 进入项目目录 $ cd admin # 安装依赖 $ npm install # 启动项目(本地开发环境) $ npm run dev # 打包项目 $ npm run build ~~~ ## 配置请求域名 ### 开发环境配置 配置文件地址:/.env.dev *请求域名配置* `$ VUE_APP_API_URL='http://自己的域名/adminapi'` ### 生产环境 *接口请求地址 (http)或 (https)://www.crmeb.com(换成你的域名)/adminapi 非独立部署默认为空* `$ VUE_APP_API_URL=''` --- ### Template/Admin/Package.Json (template/admin/package.json) { "name": "from-crmeb-admin", "version": "5.7.0", "author": "sugar1569<763569752@qq.com>", "private": false, "scripts": { "serve": "node src/libs/start.js && vue-cli-service serve --open --mode=dev", "dev": "node src/libs/start.js && vue-cli-service serve --open --mode=dev", "build": "vue-cli-service build --mode=production", "eslint:comment": "使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .js 和 .vue 的文件", "eslint": "eslint --ext .js,.vue,.ts --ignore-path .gitignore --fix src", "prettier:comment": "自动格式化当前目录下的所有文件", "prettier": "prettier --write ." }, "dependencies": { "@babel/polyfill": "^7.12.1", "@babel/runtime": "^7.2.0", "@better-scroll/core": "^2.0.5", "@form-create/element-ui": "^2.5.31", "async-validator": "^3.4.0", "awe-dnd": "^0.3.4", "better-scroll": "^1.15.2", "clipboard": "^2.0.0", "codemirror": "^5.38.0", "core-js": "^3.32.2", "cos-js-sdk-v5": "^0.5.26", "countup": "^1.8.2", "cropperjs": "^1.2.2", "crypto-js": "^4.1.1", "dayjs": "^1.7.7", "echarts": "^4.8.0", "editor": "^1.0.0", "element-ui": "2.15.6", "emoji-awesome": "0.0.2", "exceljs": "^4.3.0", "file-saver": "^2.0.5", "html2canvas": "^1.0.0-alpha.12", "js-cookie": "^2.2.0", "js-md5": "^0.7.3", "lodash": "^4.17.10", "moment": "^2.29.1", "monaco-editor": "^0.28.1", "monaco-editor-webpack-plugin": "^4.2.0", "oss": "0.0.1", "print-js": "^1.6.0", "qiniu-js": "^2.5.5", "qrcodejs2": "0.0.2", "qs": "^6.6.0", "quill": "^1.3.6", "screenfull": "^5.0.2", "sortablejs": "^1.15.0", "swiper": "^5.4.5", "tree-table-vue": "^1.1.0", "uglifyjs-webpack-plugin": "^2.2.0", "v-org-tree": "^1.0.6", "v-viewer": "^1.5.1", "vue": "^2.5.10", "vue-awesome-swiper": "^4.1.1", "vue-clipboard2": "^0.3.3", "vue-codemirror": "^4.0.6", "vue-cropper": "^0.5.11", "vue-happy-scroll": "^2.1.1", "vue-i18n": "^7.8.0", "vue-pickers": "^2.5.3", "vue-puzzle-vcode": "^1.1.9", "vue-router": "^3.0.1", "vue-tree-list": "^1.5.0", "vue-ydui": "^1.2.6", "vuedraggable": "^2.16.0", "vuescroll": "^4.16.1", "vuex": "^3.0.1", "vuex-persist": "^2.2.0", "vxe-pc-ui": "^3.7.5", "vxe-table": "^3.16.3", "wangeditor": "^4.7.15", "xe-utils": "^3.5.4", "xlsx": "^0.13.5" }, "devDependencies": { "@babel/cli": "^7.21.0", "@babel/core": "^7.21.0", "@babel/node": "^7.20.7", "@babel/plugin-transform-runtime": "^7.2.0", "@babel/preset-env": "^7.20.2", "@vue/cli-plugin-babel": "^4.4.6", "@vue/cli-plugin-eslint": "^5.0.8", "@vue/cli-plugin-unit-jest": "^3.2.3", "@vue/cli-plugin-unit-mocha": "^3.0.1", "@vue/cli-service": "^3.0.1", "@vue/eslint-config-prettier": "^7.0.0", "@vue/eslint-config-standard": "^3.0.0-beta.10", "axios": "^0.18.1", "compression-webpack-plugin": "^6.1.1", "eslint": "^7.15.0", "eslint-loader": "^4.0.2", "eslint-plugin-cypress": "^2.0.1", "eslint-plugin-prettier": "^3.4.1", "eslint-plugin-vue": "^7.2.0", "jsencrypt": "^3.3.2", "lint-staged": "^6.0.0", "prettier": "^2.5.1", "sass": "^1.69.5", "sass-loader": "^10.4.1", "script-loader": "^0.7.2", "svg-sprite-loader": "^3.8.0", "text-loader": "0.0.1", "vue-lazyload": "^1.3.3", "vue-template-compiler": "^2.5.13", "vue-waterfall-easy": "^2.4.4" }, "engines": { "node": ">14.0.0 < 23.0.0", "npm": ">=6" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ], "gitHooks": { "pre-commit": "lint-staged" }, "lint-staged": { "*.js": [ "vue-cli-service lint", "git add" ], "*.vue": [ "vue-cli-service lint", "git add" ] } } --- ### Template/Admin/.Travis.Yml (template/admin/.travis.yml) language: node_js node_js: stable script: npm run lint notifications: email: false --- ### Template/Admin/Public/Manifest.Json (template/admin/public/manifest.json) { "name":"CRMEB", "display":"standalone", "start_url":".", "id": "index.html", "background_color": "#999", "theme_color":"#292d3e", "icons":[{ "src":"./image/logo-small.png", "sizes":"144x144", "type":"image/png" }] } --- ### Template/Admin/Src/Assets/IconfontYI/IconfontYI.Json (template/admin/src/assets/iconfontYI/iconfontYI.json) { "id": "993865", "name": "商城模板—第三方修改", "font_family": "iconfontYI", "css_prefix_text": "icon-", "description": "外包项目图标添加", "glyphs": [ { "icon_id": "160836", "name": "精品推荐", "font_class": "jingpintuijian", "unicode": "e60d", "unicode_decimal": 58893 }, { "icon_id": "464461", "name": "笑脸", "font_class": "xiaolian", "unicode": "e60f", "unicode_decimal": 58895 }, { "icon_id": "539040", "name": "推广", "font_class": "tuiguang", "unicode": "e63b", "unicode_decimal": 58939 }, { "icon_id": "689324", "name": "圆点小", "font_class": "yuandianxiao", "unicode": "e82f", "unicode_decimal": 59439 }, { "icon_id": "720963", "name": "搜索", "font_class": "xiazai5", "unicode": "e605", "unicode_decimal": 58885 }, { "icon_id": "872548", "name": "支付宝", "font_class": "icon34", "unicode": "e62b", "unicode_decimal": 58923 }, { "icon_id": "926111", "name": "打电话-01", "font_class": "dadianhua01", "unicode": "e623", "unicode_decimal": 58915 }, { "icon_id": "1090230", "name": "点选", "font_class": "webicon318", "unicode": "e6c2", "unicode_decimal": 59074 }, { "icon_id": "1141383", "name": "关闭", "font_class": "iconfontguanbi", "unicode": "e643", "unicode_decimal": 58947 }, { "icon_id": "1207404", "name": "拍照", "font_class": "icon25201", "unicode": "e70d", "unicode_decimal": 59149 }, { "icon_id": "1518998", "name": "促销管理", "font_class": "cuxiaoguanli", "unicode": "e60e", "unicode_decimal": 58894 }, { "icon_id": "1534823", "name": "秒杀", "font_class": "miaosha", "unicode": "e6c3", "unicode_decimal": 59075 }, { "icon_id": "1671897", "name": "会员", "font_class": "huiyuan", "unicode": "e60b", "unicode_decimal": 58891 }, { "icon_id": "1727266", "name": "05采购-线性", "font_class": "caigou-xianxing", "unicode": "e887", "unicode_decimal": 59527 }, { "icon_id": "1727267", "name": "05采购", "font_class": "caigou", "unicode": "e888", "unicode_decimal": 59528 }, { "icon_id": "1727371", "name": "30应用程序-线性", "font_class": "yingyongchengxu-xianxing", "unicode": "e8a1", "unicode_decimal": 59553 }, { "icon_id": "1727372", "name": "30应用程序", "font_class": "yingyongchengxu", "unicode": "e8a2", "unicode_decimal": 59554 }, { "icon_id": "1727379", "name": "33资源-线性", "font_class": "ziyuan-xianxing", "unicode": "e8a4", "unicode_decimal": 59556 }, { "icon_id": "1727423", "name": "204首页", "font_class": "shouye", "unicode": "e8b9", "unicode_decimal": 59577 }, { "icon_id": "1727424", "name": "204首页-线性", "font_class": "shouye-xianxing", "unicode": "e8ba", "unicode_decimal": 59578 }, { "icon_id": "1727458", "name": "224用户-线性", "font_class": "yonghu-xianxing", "unicode": "e8c8", "unicode_decimal": 59592 }, { "icon_id": "1727459", "name": "224用户", "font_class": "yonghu", "unicode": "e8c9", "unicode_decimal": 59593 }, { "icon_id": "1727598", "name": "411地图", "font_class": "ditu", "unicode": "e906", "unicode_decimal": 59654 }, { "icon_id": "1780995", "name": "搜索", "font_class": "sousuo2", "unicode": "e757", "unicode_decimal": 59223 }, { "icon_id": "1850915", "name": "订单", "font_class": "2", "unicode": "e684", "unicode_decimal": 59012 }, { "icon_id": "1852350", "name": "地址", "font_class": "dizhi", "unicode": "e608", "unicode_decimal": 58888 }, { "icon_id": "1857286", "name": "皇冠2", "font_class": "huangguan", "unicode": "e624", "unicode_decimal": 58916 }, { "icon_id": "1857287", "name": "皇冠3", "font_class": "huangguan1", "unicode": "e625", "unicode_decimal": 58917 }, { "icon_id": "1857288", "name": "皇冠", "font_class": "huangguan2", "unicode": "e626", "unicode_decimal": 58918 }, { "icon_id": "1983323", "name": "物流", "font_class": "wuliu", "unicode": "e6f2", "unicode_decimal": 59122 }, { "icon_id": "2051400", "name": "选中", "font_class": "xuanzhong", "unicode": "e615", "unicode_decimal": 58901 }, { "icon_id": "2121745", "name": "新品", "font_class": "xinpin", "unicode": "e610", "unicode_decimal": 58896 }, { "icon_id": "2182776", "name": "箭头", "font_class": "arrow", "unicode": "e627", "unicode_decimal": 58919 }, { "icon_id": "2203117", "name": "余额支付", "font_class": "yuezhifu", "unicode": "e65e", "unicode_decimal": 58974 }, { "icon_id": "2351436", "name": "编辑", "font_class": "bianji", "unicode": "e6cc", "unicode_decimal": 59084 }, { "icon_id": "2360857", "name": "问题", "font_class": "wenti", "unicode": "e758", "unicode_decimal": 59224 }, { "icon_id": "2540845", "name": "钱袋 (1) (3)", "font_class": "qiandai", "unicode": "e6b1", "unicode_decimal": 59057 }, { "icon_id": "2551763", "name": "向右", "font_class": "xiangyou", "unicode": "e679", "unicode_decimal": 59001 }, { "icon_id": "2553385", "name": "排行", "font_class": "paihang", "unicode": "e73e", "unicode_decimal": 59198 }, { "icon_id": "2559567", "name": "位置", "font_class": "weizhi", "unicode": "e62d", "unicode_decimal": 58925 }, { "icon_id": "2562049", "name": "热门", "font_class": "remen", "unicode": "e67c", "unicode_decimal": 59004 }, { "icon_id": "2664568", "name": "团队", "font_class": "tuandui", "unicode": "e685", "unicode_decimal": 59013 }, { "icon_id": "2672470", "name": "余额支付", "font_class": "yuezhifu1", "unicode": "e61a", "unicode_decimal": 58906 }, { "icon_id": "2681908", "name": "用户", "font_class": "yonghu2", "unicode": "e60a", "unicode_decimal": 58890 }, { "icon_id": "2762285", "name": "拼团", "font_class": "hebingxingzhuang", "unicode": "e656", "unicode_decimal": 58966 }, { "icon_id": "2762614", "name": "购物车", "font_class": "gouwuche1", "unicode": "e642", "unicode_decimal": 58946 }, { "icon_id": "2808105", "name": "浏览", "font_class": "liulan", "unicode": "e629", "unicode_decimal": 58921 }, { "icon_id": "2980623", "name": "金币", "font_class": "jinbi1", "unicode": "e655", "unicode_decimal": 58965 }, { "icon_id": "3034678", "name": "关闭", "font_class": "guanbi2", "unicode": "e61c", "unicode_decimal": 58908 }, { "icon_id": "3054938", "name": "搜索", "font_class": "sousuo", "unicode": "e67d", "unicode_decimal": 59005 }, { "icon_id": "3131690", "name": "微信", "font_class": "weixin", "unicode": "e600", "unicode_decimal": 58880 }, { "icon_id": "3185373", "name": "微信", "font_class": "weixin3", "unicode": "e618", "unicode_decimal": 58904 }, { "icon_id": "3203334", "name": "排行", "font_class": "paihang1", "unicode": "e633", "unicode_decimal": 58931 }, { "icon_id": "3232659", "name": "统计 (1)", "font_class": "tongji", "unicode": "e687", "unicode_decimal": 59015 }, { "icon_id": "3355930", "name": "菜单", "font_class": "caidan", "unicode": "e62a", "unicode_decimal": 58922 }, { "icon_id": "3402041", "name": "二维码", "font_class": "erweima", "unicode": "e607", "unicode_decimal": 58887 }, { "icon_id": "3416446", "name": "收 藏", "font_class": "shoucang", "unicode": "e606", "unicode_decimal": 58886 }, { "icon_id": "3453309", "name": "减", "font_class": "jian", "unicode": "e621", "unicode_decimal": 58913 }, { "icon_id": "3577985", "name": "加", "font_class": "jia", "unicode": "e7e0", "unicode_decimal": 59360 }, { "icon_id": "3584611", "name": "关 闭", "font_class": "guanbi", "unicode": "e62f", "unicode_decimal": 58927 }, { "icon_id": "3751425", "name": "向上", "font_class": "xiangshang1", "unicode": "e622", "unicode_decimal": 58914 }, { "icon_id": "3790017", "name": "说明", "font_class": "shuoming", "unicode": "e630", "unicode_decimal": 58928 }, { "icon_id": "3844134", "name": "下拉", "font_class": "xiala", "unicode": "e67f", "unicode_decimal": 59007 }, { "icon_id": "3845489", "name": "排列2", "font_class": "pailie", "unicode": "e61b", "unicode_decimal": 58907 }, { "icon_id": "3931371", "name": "分享", "font_class": "fenxiang", "unicode": "e603", "unicode_decimal": 58883 }, { "icon_id": "3968583", "name": "银行卡", "font_class": "yinhangqia", "unicode": "e72c", "unicode_decimal": 59180 }, { "icon_id": "4018497", "name": "搜索01", "font_class": "sousuo1", "unicode": "e64c", "unicode_decimal": 58956 }, { "icon_id": "4018775", "name": "对号01", "font_class": "duihao", "unicode": "e64e", "unicode_decimal": 58958 }, { "icon_id": "4133807", "name": "订单", "font_class": "dingdan", "unicode": "e61e", "unicode_decimal": 58910 }, { "icon_id": "4182111", "name": "图片排列", "font_class": "tupianpailie", "unicode": "e620", "unicode_decimal": 58912 }, { "icon_id": "4432686", "name": "充值", "font_class": "chongzhi", "unicode": "e602", "unicode_decimal": 58882 }, { "icon_id": "4603167", "name": "设置", "font_class": "shezhi", "unicode": "e619", "unicode_decimal": 58905 }, { "icon_id": "4769807", "name": "个人中心", "font_class": "gerenzhongxin", "unicode": "e636", "unicode_decimal": 58934 }, { "icon_id": "4770063", "name": "首页", "font_class": "shouye1", "unicode": "e637", "unicode_decimal": 58935 }, { "icon_id": "4770130", "name": "购物车", "font_class": "gouwuche2", "unicode": "e638", "unicode_decimal": 58936 }, { "icon_id": "4919800", "name": "说明", "font_class": "shuoming1", "unicode": "e673", "unicode_decimal": 58995 }, { "icon_id": "4943660", "name": "对号", "font_class": "duihao2", "unicode": "e601", "unicode_decimal": 58881 }, { "icon_id": "5087448", "name": "选中", "font_class": "complete", "unicode": "e646", "unicode_decimal": 58950 }, { "icon_id": "5110066", "name": "微信", "font_class": "weixin1", "unicode": "e66e", "unicode_decimal": 58990 }, { "icon_id": "5116806", "name": "线下支付", "font_class": "xianxiazhifu", "unicode": "e6e1", "unicode_decimal": 59105 }, { "icon_id": "5174616", "name": "添加地址", "font_class": "tianjiadizhi", "unicode": "e640", "unicode_decimal": 58944 }, { "icon_id": "5236609", "name": "微信", "font_class": "weixin2", "unicode": "e604", "unicode_decimal": 58884 }, { "icon_id": "5258701", "name": "购物车", "font_class": "gouwuche", "unicode": "e669", "unicode_decimal": 58985 }, { "icon_id": "5301920", "name": "加载", "font_class": "jiazai", "unicode": "e62c", "unicode_decimal": 58924 }, { "icon_id": "5383811", "name": "新闻通知", "font_class": "huabanfuben", "unicode": "e654", "unicode_decimal": 58964 }, { "icon_id": "5387815", "name": "客服_o", "font_class": "kefu_o", "unicode": "eb63", "unicode_decimal": 60259 }, { "icon_id": "5387821", "name": "礼物_o", "font_class": "liwu_o", "unicode": "eb65", "unicode_decimal": 60261 }, { "icon_id": "5387908", "name": "按钮_箭头展开_o", "font_class": "anniu_jiantouzhankai_o", "unicode": "eb89", "unicode_decimal": 60297 }, { "icon_id": "5387922", "name": "箭头_下一页_o", "font_class": "jiantou_xiayiye_o", "unicode": "eb8f", "unicode_decimal": 60303 }, { "icon_id": "5387926", "name": "箭头_上下切换_o", "font_class": "jiantou_shangxiaqiehuan_o", "unicode": "eb90", "unicode_decimal": 60304 }, { "icon_id": "5387950", "name": "上下展开_o", "font_class": "shangxiazhankai_o", "unicode": "eb9a", "unicode_decimal": 60314 }, { "icon_id": "5387958", "name": "货币流_o", "font_class": "huobiliu_o", "unicode": "eb9f", "unicode_decimal": 60319 }, { "icon_id": "5387967", "name": "金币_o", "font_class": "jinbi_o", "unicode": "eba1", "unicode_decimal": 60321 }, { "icon_id": "5387990", "name": "个人头像_o", "font_class": "gerentouxiang_o", "unicode": "ebac", "unicode_decimal": 60332 }, { "icon_id": "5387992", "name": "群组_o", "font_class": "qunzu_o", "unicode": "ebad", "unicode_decimal": 60333 }, { "icon_id": "5387993", "name": "电话_o", "font_class": "dianhua_o", "unicode": "ebaf", "unicode_decimal": 60335 }, { "icon_id": "5387995", "name": "收藏_o", "font_class": "shoucang_o", "unicode": "ebae", "unicode_decimal": 60334 }, { "icon_id": "5388009", "name": "云上传_o", "font_class": "yunshangchuan_o", "unicode": "ebb3", "unicode_decimal": 60339 }, { "icon_id": "5388011", "name": "饼图_o", "font_class": "bingtu_o", "unicode": "ebb4", "unicode_decimal": 60340 }, { "icon_id": "5388017", "name": "包裹_环保盒_o", "font_class": "baoguo_huanbaohe_o", "unicode": "ebb6", "unicode_decimal": 60342 }, { "icon_id": "5388018", "name": "包裹_取消收货_o", "font_class": "baoguo_quxiaoshouhuo_o", "unicode": "ebb7", "unicode_decimal": 60343 }, { "icon_id": "5388019", "name": "包裹_收货_o", "font_class": "baoguo_shouhuo_o", "unicode": "ebb8", "unicode_decimal": 60344 }, { "icon_id": "5388020", "name": "包裹_领件_o", "font_class": "baoguo_lingjian_o", "unicode": "ebb9", "unicode_decimal": 60345 }, { "icon_id": "5388021", "name": "包裹_收纳_o", "font_class": "baoguo_shouna_o", "unicode": "ebbe", "unicode_decimal": 60350 }, { "icon_id": "5388026", "name": "地点定位_o", "font_class": "didiandingwei_o", "unicode": "ebba", "unicode_decimal": 60346 }, { "icon_id": "5441298", "name": "折扣", "font_class": "zhekou", "unicode": "e790", "unicode_decimal": 59280 }, { "icon_id": "5452215", "name": "喇叭", "font_class": "laba", "unicode": "e612", "unicode_decimal": 58898 }, { "icon_id": "5860911", "name": "权限管理锁子", "font_class": "quanxianguanlisuozi", "unicode": "e6d2", "unicode_decimal": 59090 }, { "icon_id": "5996196", "name": "右键", "font_class": "youjian", "unicode": "e677", "unicode_decimal": 58999 }, { "icon_id": "6091393", "name": "下 拉", "font_class": "xiala1", "unicode": "e609", "unicode_decimal": 58889 }, { "icon_id": "6133627", "name": "微信支付", "font_class": "weixinzhifu", "unicode": "e632", "unicode_decimal": 58930 }, { "icon_id": "6155492", "name": "经验值", "font_class": "jingyanzhi", "unicode": "e62e", "unicode_decimal": 58926 }, { "icon_id": "6194276", "name": "更多", "font_class": "up", "unicode": "e617", "unicode_decimal": 58903 }, { "icon_id": "6265459", "name": "客服", "font_class": "kefu", "unicode": "e6b2", "unicode_decimal": 59058 }, { "icon_id": "6450775", "name": "审核中", "font_class": "shenhezhong", "unicode": "e6ce", "unicode_decimal": 59086 }, { "icon_id": "6582604", "name": "砍价", "font_class": "kanjia1", "unicode": "e613", "unicode_decimal": 58899 }, { "icon_id": "6636378", "name": "删 除", "font_class": "shanchu1", "unicode": "e611", "unicode_decimal": 58897 }, { "icon_id": "6783580", "name": "支付宝", "font_class": "zhifubao", "unicode": "e61d", "unicode_decimal": 58909 }, { "icon_id": "6825609", "name": "用户", "font_class": "yonghu1", "unicode": "e644", "unicode_decimal": 58948 }, { "icon_id": "6854655", "name": "功能", "font_class": "gongneng", "unicode": "e63a", "unicode_decimal": 58938 }, { "icon_id": "6970586", "name": "锁子", "font_class": "suozi", "unicode": "e631", "unicode_decimal": 58929 }, { "icon_id": "7133397", "name": "图标_设备列表轮播图右键头", "font_class": "jiantou", "unicode": "e641", "unicode_decimal": 58945 }, { "icon_id": "7193264", "name": "砍价", "font_class": "kanjia", "unicode": "e69b", "unicode_decimal": 59035 }, { "icon_id": "7246995", "name": "拼团", "font_class": "pintuan", "unicode": "e60c", "unicode_decimal": 58892 }, { "icon_id": "7311029", "name": "编辑", "font_class": "bianji1", "unicode": "e614", "unicode_decimal": 58900 }, { "icon_id": "7341104", "name": "优惠券", "font_class": "youhuiquan", "unicode": "e6e4", "unicode_decimal": 59108 }, { "icon_id": "7383390", "name": "分类", "font_class": "fenleiyemian", "unicode": "e639", "unicode_decimal": 58937 }, { "icon_id": "7467481", "name": "向右", "font_class": "xiangxia", "unicode": "e8ca", "unicode_decimal": 59594 }, { "icon_id": "7474826", "name": "删 除", "font_class": "shanchu", "unicode": "e628", "unicode_decimal": 58920 }, { "icon_id": "7540338", "name": "关 闭", "font_class": "guanbi3", "unicode": "e6c5", "unicode_decimal": 59077 }, { "icon_id": "7559350", "name": "选中001", "font_class": "xuanzhong1", "unicode": "e6ef", "unicode_decimal": 59119 }, { "icon_id": "7559357", "name": "未选中001", "font_class": "weixuanzhong", "unicode": "e6f0", "unicode_decimal": 59120 }, { "icon_id": "7559551", "name": "装饰线", "font_class": "zhuangshixian", "unicode": "e6f1", "unicode_decimal": 59121 }, { "icon_id": "7559552", "name": "技术支持", "font_class": "jishuzhichi", "unicode": "e6f3", "unicode_decimal": 59123 }, { "icon_id": "7560557", "name": "边框001", "font_class": "biankuang", "unicode": "e6f4", "unicode_decimal": 59124 }, { "icon_id": "7560838", "name": "关 闭", "font_class": "guanbi1", "unicode": "e6f5", "unicode_decimal": 59125 }, { "icon_id": "7560940", "name": "向右", "font_class": "xiangshang", "unicode": "ebbb", "unicode_decimal": 60347 }, { "icon_id": "7561200", "name": "¥", "font_class": "icon-test", "unicode": "e6f6", "unicode_decimal": 59126 }, { "icon_id": "7562923", "name": "明细", "font_class": "mingxi", "unicode": "e6f7", "unicode_decimal": 59127 }, { "icon_id": "7562924", "name": "提升分值", "font_class": "tishengfenzhi", "unicode": "e6f8", "unicode_decimal": 59128 }, { "icon_id": "7563099", "name": "拼团成功", "font_class": "pintuanchenggong", "unicode": "e6f9", "unicode_decimal": 59129 }, { "icon_id": "7563100", "name": "拼团失败", "font_class": "pintuanshibai", "unicode": "e6fa", "unicode_decimal": 59130 }, { "icon_id": "7563348", "name": "实体星", "font_class": "shitixing", "unicode": "e6fb", "unicode_decimal": 59131 }, { "icon_id": "7563349", "name": "空心星", "font_class": "kongxinxing", "unicode": "e6fc", "unicode_decimal": 59132 }, { "icon_id": "7563430", "name": "已退款", "font_class": "yituikuan", "unicode": "e6fd", "unicode_decimal": 59133 }, { "icon_id": "7563431", "name": "退款中", "font_class": "tuikuanzhong", "unicode": "e6fe", "unicode_decimal": 59134 }, { "icon_id": "7563801", "name": "菱形", "font_class": "lingxing", "unicode": "e6ff", "unicode_decimal": 59135 }, { "icon_id": "7583837", "name": "向右", "font_class": "xiangzuo", "unicode": "ebbc", "unicode_decimal": 60348 }, { "icon_id": "7766749", "name": "icon_im_face", "font_class": "icon_im_face", "unicode": "eb96", "unicode_decimal": 60310 }, { "icon_id": "7766777", "name": "icon_im_keyboard", "font_class": "icon_im_keyboard", "unicode": "eb97", "unicode_decimal": 60311 }, { "icon_id": "8037761", "name": "收 藏", "font_class": "shoucang1", "unicode": "e714", "unicode_decimal": 59156 }, { "icon_id": "8181204", "name": "dianhau", "font_class": "dianhau", "unicode": "e634", "unicode_decimal": 58932 }, { "icon_id": "8902924", "name": "备注", "font_class": "zhinengkefu-", "unicode": "e616", "unicode_decimal": 58902 }, { "icon_id": "8906620", "name": "code_1", "font_class": "code_", "unicode": "e723", "unicode_decimal": 59171 }, { "icon_id": "8906621", "name": "code_2", "font_class": "code_1", "unicode": "e724", "unicode_decimal": 59172 }, { "icon_id": "8906622", "name": "phone_1", "font_class": "phone_", "unicode": "e725", "unicode_decimal": 59173 }, { "icon_id": "9136175", "name": "时间", "font_class": "shijian", "unicode": "e635", "unicode_decimal": 58933 }, { "icon_id": "9364404", "name": "向上", "font_class": "xiangxia2", "unicode": "ebbd", "unicode_decimal": 60349 }, { "icon_id": "9364654", "name": "选中", "font_class": "xuanzhong2", "unicode": "e731", "unicode_decimal": 59185 }, { "icon_id": "9364655", "name": "数据统计", "font_class": "shujutongji", "unicode": "e732", "unicode_decimal": 59186 }, { "icon_id": "9364656", "name": "详细数据", "font_class": "xiangxishuju", "unicode": "e733", "unicode_decimal": 59187 }, { "icon_id": "9364657", "name": "更多", "font_class": "gengduo", "unicode": "e734", "unicode_decimal": 59188 }, { "icon_id": "9561662", "name": "crmeb", "font_class": "crmeb", "unicode": "e735", "unicode_decimal": 59189 }, { "icon_id": "9895692", "name": "crmeb2", "font_class": "crmeb1", "unicode": "e739", "unicode_decimal": 59193 }, { "icon_id": "9896813", "name": "海报", "font_class": "haibao", "unicode": "e73b", "unicode_decimal": 59195 }, { "icon_id": "10144788", "name": "tupian-01", "font_class": "tupian-", "unicode": "e73f", "unicode_decimal": 59199 }, { "icon_id": "10283513", "name": "修 改", "font_class": "xiugai", "unicode": "e61f", "unicode_decimal": 58911 }, { "icon_id": "10717369", "name": "拼团", "font_class": "pintuan-copy", "unicode": "ebbf", "unicode_decimal": 60351 }, { "icon_id": "10880067", "name": "通话", "font_class": "tonghua", "unicode": "e740", "unicode_decimal": 59200 }, { "icon_id": "11003792", "name": "个人中心", "font_class": "gerenzhongxin-copy", "unicode": "ebc0", "unicode_decimal": 60352 }, { "icon_id": "11003799", "name": "首页", "font_class": "shouye1-copy", "unicode": "ebc1", "unicode_decimal": 60353 }, { "icon_id": "11003806", "name": "购物车", "font_class": "gouwuche2-copy", "unicode": "ebc2", "unicode_decimal": 60354 }, { "icon_id": "11003812", "name": "分类", "font_class": "fenleiyemian-copy", "unicode": "ebc3", "unicode_decimal": 60355 }, { "icon_id": "11680690", "name": "mzshopping01", "font_class": "mzshopping", "unicode": "e746", "unicode_decimal": 59206 }, { "icon_id": "11680752", "name": "shouye01", "font_class": "shouye2", "unicode": "e748", "unicode_decimal": 59208 }, { "icon_id": "11680757", "name": "fenlei01", "font_class": "fenlei", "unicode": "e749", "unicode_decimal": 59209 }, { "icon_id": "11680778", "name": "gouwuche01", "font_class": "gouwuche3", "unicode": "e74a", "unicode_decimal": 59210 }, { "icon_id": "11680780", "name": "geren01", "font_class": "geren", "unicode": "e74b", "unicode_decimal": 59211 }, { "icon_id": "11680785", "name": "shouye02", "font_class": "shouye3", "unicode": "e74c", "unicode_decimal": 59212 }, { "icon_id": "11680960", "name": "fenlei02", "font_class": "fenlei1", "unicode": "e74e", "unicode_decimal": 59214 }, { "icon_id": "11680989", "name": "gouwuche02", "font_class": "gouwuche4", "unicode": "e74f", "unicode_decimal": 59215 }, { "icon_id": "11680996", "name": "geren02", "font_class": "geren1", "unicode": "e750", "unicode_decimal": 59216 } ] } --- ### Template/Admin/Src/Router/Modules/Crud/README (template/admin/src/router/modules/crud/README.md) # CRMEB ADMIN CRUD 路由存放 此目录下的所有路由会被自动加载到 router,无需其他配置 可以对此路由进行修改删除 --- ### Template/Uni App/Manifest.Json (template/uni-app/manifest.json) { "name" : "CRMEB标准版", "appid" : "__UNI__A3F1ED4", "description" : "CRMEB标准版", "versionName" : "6.0.0", "versionCode" : 600, "transformPx" : false, "sassImplementationName" : "node-sass", /* 5+App特有相关 */ "app-plus" : { "usingComponents" : true, "nvueCompiler" : "uni-app", "splashscreen" : { "alwaysShowBeforeRender" : false, "waiting" : false, "autoclose" : true, "delay" : 0 }, "screenOrientation" : [ "portrait-primary", "portrait-secondary", "landscape-primary", "landscape-secondary" ], /* 模块配置 */ "modules" : { "Payment" : {}, "Share" : {}, "VideoPlayer" : {}, "OAuth" : {}, "Barcode" : {}, "Camera" : {} }, "safearea" : { "bottom" : { "offset" : "none" } }, /* 应用发布信息 */ "distribute" : { /* android打包配置 */ "android" : { "permissions" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ], "abiFilters" : [ "armeabi-v7a", "arm64-v8a" ], "permissionExternalStorage" : { "request" : "none", "prompt" : "应用保存运行状态等信息,需要获取读写手机存储(系统提示为访问设备上的照片、媒体内容和文件)权限,请允许。" }, "permissionPhoneState" : { "request" : "none" //拨打电话权限关闭 }, "targetSdkVersion" : 30 }, /* ios打包配置 */ "ios" : { "capabilities" : { "entitlements" : { "com.apple.developer.associated-domains" : [ "applinks:", "applinks:", "applinks:", "applinks:static-679f0930-8f60-425c-9033-8c135f397ea5.bspapp.com" ] } }, "privacyDescription" : { "NSLocationWhenInUseUsageDescription" : "根据客户地理位置推荐最近门店", "NSPhotoLibraryUsageDescription" : "上传用户头像保存分享海报", "NSPhotoLibraryAddUsageDescription" : "上传用户头像保存分享海报", "NSLocationAlwaysAndWhenInUseUsageDescription" : "根据客户地理位置推荐最近门店", "NSLocationAlwaysUsageDescription" : "根据客户地理位置推荐最近门店", "NSCameraUsageDescription" : "上传用户头像保存分享海报" }, "idfa" : false, "dSYMs" : false }, /* SDK配置 */ "sdkConfigs" : { "payment" : { "alipay" : { "__platform__" : [ "ios", "android" ] }, "weixin" : { "__platform__" : [ "ios", "android" ], "appid" : "wx277a269f3d736d67", "UniversalLinks" : "https://bzapp.crmeb.net/uni-universallinks/__UNI__A3F1ED4/" } }, "share" : { "weixin" : { "appid" : "wx277a269f3d736d67", "UniversalLinks" : "https://bzapp.crmeb.net/uni-universallinks/__UNI__A3F1ED4/" } }, "push" : {}, "maps" : { "amap" : { "appkey_ios" : "aeb768547b9d752891e37e1ca0a2b66d", "appkey_android" : "41ec5c3f4d110ce02a326210fe147be8" } }, "oauth" : { "apple" : {}, "weixin" : { "appid" : "wx277a269f3d736d67", "appsecret" : "bd08741a055c2ecac5826ff1c048464b", "UniversalLinks" : "https://bzapp.crmeb.net/uni-universallinks/__UNI__A3F1ED4/" } }, "ad" : {}, "geolocation" : { "amap" : { "__platform__" : [ "ios", "android" ], "appkey_ios" : "aeb768547b9d752891e37e1ca0a2b66d", "appkey_android" : "41ec5c3f4d110ce02a326210fe147be8" } }, "statics" : { "google" : { "config_ios" : "", "config_android" : "" } } }, "splashscreen" : { "androidStyle" : "common", "iosStyle" : "common", "useOriginalMsgbox" : true }, "icons" : { "android" : { "hdpi" : "unpackage/res/icons/72x72.png", "xhdpi" : "unpackage/res/icons/96x96.png", "xxhdpi" : "unpackage/res/icons/144x144.png", "xxxhdpi" : "unpackage/res/icons/192x192.png" }, "ios" : { "appstore" : "unpackage/res/icons/1024x1024.png", "ipad" : { "app" : "unpackage/res/icons/76x76.png", "app@2x" : "unpackage/res/icons/152x152.png", "notification" : "unpackage/res/icons/20x20.png", "notification@2x" : "unpackage/res/icons/40x40.png", "proapp@2x" : "unpackage/res/icons/167x167.png", "settings" : "unpackage/res/icons/29x29.png", "settings@2x" : "unpackage/res/icons/58x58.png", "spotlight" : "unpackage/res/icons/40x40.png", "spotlight@2x" : "unpackage/res/icons/80x80.png" }, "iphone" : { "app@2x" : "unpackage/res/icons/120x120.png", "app@3x" : "unpackage/res/icons/180x180.png", "notification@2x" : "unpackage/res/icons/40x40.png", "notification@3x" : "unpackage/res/icons/60x60.png", "settings@2x" : "unpackage/res/icons/58x58.png", "settings@3x" : "unpackage/res/icons/87x87.png", "spotlight@2x" : "unpackage/res/icons/80x80.png", "spotlight@3x" : "unpackage/res/icons/120x120.png" } } } } }, /* 快应用特有相关 */ "quickapp" : {}, /* 小程序特有相关 */ "mp-weixin" : { "appid" : "wx3b82801238ca1b57", "setting" : { "urlCheck" : false, "minified" : true, "postcss" : true, "es6" : true }, "permission" : { "scope.userLocation" : { "desc" : "你的位置信息将用于查看与门店的距离" } }, "optimization" : { "subPackages" : true }, "usingComponents" : true, "requiredPrivateInfos" : [ "getLocation", "onLocationChange", "startLocationUpdateBackground", "chooseAddress" ], "__usePrivacyCheck__" : true }, "mp-alipay" : { "usingComponents" : true }, "mp-baidu" : { "usingComponents" : true }, "mp-toutiao" : { "usingComponents" : true }, "h5" : { "devServer" : { "https" : false }, "router" : { "mode" : "history", "base" : "" }, "domain" : "", "sdkConfigs" : { "maps" : { "qqmap" : { "key" : "NO7BZ-APDKP-UCBD7-VT7CX-R5UZK-JBF2W" } } }, "optimization" : { "treeShaking" : { "enable" : true }, "subPackages" : true }, "async" : { "timeout" : 200000 }, "title" : "加载中" }, "plus" : { "statusbar" : { "immersed" : true } }, "_spaceID" : "679f0930-8f60-425c-9033-8c135f397ea5", "lazyCodeLoading" : "requiredComponents" } /* ios打包配置 */ --- ### Template/Uni App/Package.Json (template/uni-app/package.json) { "name": "uni-app", "version": "1.0.0", "dependencies": { } } --- ### Template/Uni App/Pages.Json (template/uni-app/pages.json) { "easycom": { "autoscan": true, "custom": {} }, "pages": [ //pages数组中第一项表示应用启动页 { "path": "pages/guide/index", "style": { "app-plus": { "titleNView": false //禁用原生导航栏 } } }, { "path": "pages/index/index", "style": { "navigationBarTitleText": "", "navigationStyle": "custom", "navigationBarTextStyle": "black", "app-plus": { "scrollIndicator": "none" }, "mp-weixin": { "componentPlaceholder": { "page-design": "view" } } } }, { "path": "pages/order_addcart/order_addcart", "style": { "navigationBarTitleText": "购物车", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "pages/user/index", "style": { "navigationBarTitleText": "个人中心", "mp-weixin": { "componentPlaceholder": { "page-design": "view" } }, "enablePullDownRefresh": true // #ifdef MP || APP-PLUS , "navigationStyle": "custom", // "navigationBarBackgroundColor": "#e93323", "navigationBarTextStyle": "black" // #endif } }, { "path": "pages/goods_cate/goods_cate", "style": { "navigationBarTitleText": "商品分类", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } } ], // 模块分包 "subPackages": [ { "root": "pages/goods_details", "name": "goods_details", "pages": [{ "path": "index", "style": { "navigationStyle": "custom", "transparentTitle": "auto", "mp-weixin": { "componentPlaceholder": { "page-design": "view", "product-bottom": "view" } } } }] }, { "root": "pages/extension", "name": "extension", "pages": [{ "path": "customer_list/chat", "style": { "navigationBarTitleText": "对话详情", "navigationBarBackgroundColor": "#3875EA", "navigationBarTextStyle": "white", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "news_list/index", "style": { "navigationBarTitleText": "资讯", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "news_details/index", "style": { "navigationBarTitleText": "资讯详情", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } } ] }, { "root": "pages/goods", "name": "goods", "pages": [ { "path": "goods_list/index", "style": { "navigationBarTitleText": "商品列表", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_search/index", "style": { "navigationBarTitleText": "搜索商品", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "order_pay_status/index", "style": { "navigationBarTitleText": "支付成功", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "admin_order_detail/index", "style": { "navigationBarTitleText": "订单详情", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_comment_con/index", "style": { "navigationBarTitleText": "商品评价", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_comment_con/lottery_comment", "style": { "navigationBarTitleText": "订单评价", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_comment_list/index", "style": { "navigationBarTitleText": "商品评分", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_details_store/index", "style": { "navigationBarTitleText": "门店列表", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_logistics/index", "style": { "navigationBarTitleText": "物流信息", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_return/index", "style": { "navigationBarTitleText": "申请退货", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_return_list/index", "style": { "navigationBarTitleText": "退货列表", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "lottery/grids/index", "style": { "navigationBarTitleText": "抽奖活动", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "lottery/grids/record", "style": { "navigationBarTitleText": "中奖记录", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "order_confirm/index", "style": { "navigationBarTitleText": "提交订单", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "order_details/index", "style": { "navigationBarTitleText": "订单详情", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "order_list/index", "style": { "navigationBarTitleText": "我的订单", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "order_refund_goods/index", "style": { "navigationBarTitleText": "退回商品", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "receive_gifts_status/index", "style": { "navigationBarTitleText": "领取结果", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "receive_gift/index", "style": { "navigationBarTitleText": "领取礼物", "navigationBarBackgroundColor": "#e93323", // #ifdef MP "navigationBarTextStyle": "#fff", // #endif "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "cashier/index", "style": { "navigationBarTitleText": "收银台", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } } ] }, { "root": "pages/users", "name": "users", "pages": [{ "path": "user_vip_areer/index", "style": { "navigationBarTitleText": "经验记录", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "privacy/index", "style": { "navigationBarTitleText": "隐私协议", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_cancellation/index", "style": { "navigationBarTitleText": "注销协议", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "message_center/index", "style": { "navigationBarTitleText": "消息中心", "enablePullDownRefresh": true, "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "message_center/messageDetail", "style": { "navigationBarTitleText": "消息详情", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_invoice_order/index", "style": { "navigationBarTitleText": "发票详情", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "scan_login/index", "style": { "navigationBarTitleText": "授权登录" } }, { "path": "user_invoice_list/index", "style": { "navigationBarTitleText": "发票管理", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_invoice_form/index", "style": { "navigationBarTitleText": "添加新发票", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, //#ifdef H5 { "path": "alipay_invoke/index", "style": { "navigationBarTitleText": "支付提示" } }, //#endif { "path": "wechat_login/index", "style": { "navigationBarTitleText": "", "navigationStyle": "custom", "app-plus": { "scrollIndicator": "none" } } }, { "path": "binding_phone/index", "style": { "navigationBarTitleText": "", "navigationStyle": "custom", "app-plus": { "scrollIndicator": "none" } } }, { "path": "retrievePassword/index", "style": { "navigationBarTitleText": "忘记密码", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_info/index", "style": { "navigationBarTitleText": "设置", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_get_coupon/index", "style": { "navigationBarTitleText": "领取优惠券", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "visit_list/index", "style": { "navigationBarTitleText": "浏览记录", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_goods_collection/index", "style": { "navigationBarTitleText": "收藏商品", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_sgin/index", "style": { "navigationBarTitleText": "签到", // #ifdef MP // "navigationBarTextStyle": "white", // "navigationBarBackgroundColor": "#e93323" // #endif "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_sgin_list/index", "style": { "navigationBarTitleText": "签到记录", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_money/index", "style": { "navigationBarTitleText": "我的账户", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_bill/index", "style": { "navigationBarTitleText": "账单明细", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_integral/index", "style": { "navigationBarTitleText": "积分详情" // #ifdef MP , "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_coupon/index", "style": { "navigationBarTitleText": "我的优惠券", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_spread_user/index", "style": { "navigationBarTitleText": "我的推广" // #ifdef MP , "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_spread_code/index", "style": { "navigationBarTitleText": "分销海报", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_spread_money/index", "style": { "navigationBarTitleText": "佣金记录" // #ifdef MP , "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_spread_money/receiving", "style": { "navigationBarTitleText": "收款" // #ifdef MP , "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_cash/index", "style": { "navigationBarTitleText": "提现", "navigationBarBackgroundColor": "#FFFFFF" // #ifdef MP || APP-PLUS , "navigationBarTextStyle": "black" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_vip/index", "style": { "navigationBarTitleText": "我的等级", "navigationBarBackgroundColor": "#232323" // #ifdef MP || APP-PLUS , "navigationBarTextStyle": "white" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_distribution_level/index", "style": { "navigationBarTitleText": "分销等级", "navigationBarBackgroundColor": "#232323" // #ifdef MP || APP-PLUS , "navigationBarTextStyle": "white" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_address_list/index", "style": { "navigationBarTitleText": "地址管理", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_address/index", "style": { "navigationBarTitleText": "添加地址", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_phone/index", "style": { "navigationBarTitleText": "绑定手机", // #ifdef MP // "navigationBarTextStyle": "white", // "navigationBarBackgroundColor": "#e93323" // #endif "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_payment/index", "style": { "navigationBarTitleText": "余额充值", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_pwd_edit/index", "style": { "navigationBarTitleText": "修改密码" // #ifdef MP // , // "navigationBarTextStyle": "white" // "navigationBarBackgroundColor": "#e93323" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "promoter-list/index", "style": { "navigationBarTitleText": "推广人列表" // #ifdef MP , "navigationBarBackgroundColor": "#FFFFFF", "navigationBarTextStyle": "black" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "promoter-order/index", "style": { "navigationBarTitleText": "推广人订单" // #ifdef MP , "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "promoter_rank/index", "style": { "navigationBarTitleText": "推广人排行" // #ifdef MP , "navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#FFFFFF" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "commission_rank/index", "style": { "navigationBarTitleText": "佣金排行", "navigationBarBackgroundColor": "#FFFFFF" // #ifdef MP || APP-PLUS , "navigationBarTextStyle": "black" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_return_list/index", "style": { "navigationBarTitleText": "退货列表", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "login/index", "style": { "navigationBarTitleText": "登录", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "payment_on_behalf/index", "style": { "navigationBarTitleText": "好友代付", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "payment_on_behalf/pay_status", "style": { "navigationBarTitleText": "代付成功", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "staff_list/index", "style": { "navigationBarTitleText": "员工列表", "navigationBarBackgroundColor": "#e93323" // #ifdef MP , "navigationBarTextStyle": "#fff" // #endif } } // #ifdef H5 , { "path": "auth/index", "style": { "navigationBarTitleText": "" } } // #endif ], "plugins": { "live-player-plugin": { "version": "1.3.5", "provider": "wx2b03c6e691cd7370" } } }, { "root": "pages/activity", "name": "activity", "pages": [{ "path": "goods_bargain/index", "style": { // #ifdef MP // "navigationBarTextStyle": "white", // "navigationBarBackgroundColor": "#E93323", "navigationBarTitleText": "砍价列表", // #endif "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_bargain_details/index", "style": { // #ifdef MP "navigationBarTitleText": "砍价活动", // #endif "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_combination/index", "style": { // #ifdef MP // "navigationBarTextStyle": "white", // "navigationBarBackgroundColor": "#E93323", "navigationBarTitleText": "拼团活动", // #endif "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_combination_details/index", "style": { "navigationStyle": "custom", "app-plus": { // #ifdef APP-PLUS "titleNView": { "padding-left": "10px", "padding-right": "10px", "type": "transparent", "buttons": [ //原生标题栏按钮配置, { "type": "menu" //原生标题栏增加分享按钮,点击事件可通过页面的 onNavigationBarButtonTap 函数进行监听 } ] } // #endif } } }, { "path": "goods_combination_status/index", "style": { "navigationBarTitleText": "拼团", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_seckill/index", "style": { "navigationBarTitleText": "限时秒杀" // #ifdef MP // "navigationBarTextStyle": "white" // "navigationBarBackgroundColor": "#e93323" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods_seckill_details/index", "style": { "navigationStyle": "custom" // #ifdef MP , "navigationBarTextStyle": "white" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "padding-left": "10px", "padding-right": "10px", "type": "transparent", "buttons": [ //原生标题栏按钮配置, { "type": "menu" //原生标题栏增加分享按钮,点击事件可通过页面的 onNavigationBarButtonTap 函数进行监听 } ] } // #endif } } }, { "path": "poster-poster/index", "style": { "navigationBarTitleText": "砍价海报" // #ifdef MP // "navigationBarTextStyle": "white" // "navigationBarBackgroundColor": "#d22516" // #endif , "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "bargain/index", "style": { "navigationBarTitleText": "砍价记录", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "presell/index", "style": { "navigationBarTitleText": "预售列表", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } } ] }, { "root": "pages/admin", "name": "adminOrder", "pages": [{ "path": "distribution/index", "style": { "navigationStyle": "custom", "app-plus": {} } }, { "path": "distribution/scanning/index", "style": { "navigationBarTitleText": "订单核销", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "distribution/scanning/detail/index", "style": { "navigationBarTitleText": "订单核销", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "distribution/orderDetail/index", "style": { "navigationStyle": "custom" } }, { "path": "custom_date/index", "style": { "navigationBarTitleText": "选择日期" } }, { "path": "order/index", "style": { "navigationBarTitleText": "订单统计", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "orderList/index", "style": { "navigationBarTitleText": "订单列表", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "orderDetail/index", "style": { "navigationBarTitleText": "订单详情", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "delivery/index", "style": { "navigationBarTitleText": "订单发货", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "refund/index", "style": { "navigationBarTitleText": "售后退款", "navigationStyle": "custom" } }, { "path": "logistics/index", "style": { "navigationBarTitleText": "物流信息", "navigationStyle": "custom" } }, { "path": "refund_order_list/index", "style": { "navigationBarTitleText": "售后订单列表", "navigationStyle": "custom" } }, { "path": "refund_order_detail/index", "style": { "navigationBarTitleText": "售后订单详情", "navigationStyle": "custom" } }, { "path": "goods/index", "style": { "navigationStyle": "custom", "navigationBarTitleText": "商品管理" } }, { "path": "goods/specs", "style": { "navigationBarTitleText": "修改价格/库存", "navigationBarBackgroundColor": "#F5F5F5", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "goods/addGoods", "style": { "navigationBarTitleText": "添加商品" } }, { "path": "user/list", "style": { "navigationStyle": "custom", "navigationBarTitleText": "用户管理" } }, { "path": "user/index", "style": { "navigationStyle": "custom", "navigationBarTitleText": "用户详情" } }, { "path": "statistics/index", "style": { "navigationBarTitleText": "订单数据统计", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "order_cancellation/index", "style": { "navigationBarTitleText": "订单核销", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } } ] }, { "root": "pages/columnGoods", "name": "columnGoods", "pages": [{ "path": "HotNewGoods/index", "style": { "navigationBarTitleText": "精品推荐", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "HotNewGoods/feedback", "style": { "navigationBarTitleText": "我的客服", "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#3A3A3A", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "live_list/index", "style": { "navigationBarTitleText": "精彩内容" } } ] }, { "root": "pages/annex", "pages": [{ "path": "web_view/index", "style": { "navigationBarTitleText": "", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "vip_paid/index", "style": { "navigationBarTitleText": "SVIP会员", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "vip_coupon/index", "style": { "navigationBarTitleText": "会员优惠券", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "vip_clause/index", "style": { "navigationBarTitleText": "会员协议", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "vip_active/index", "style": { "navigationBarTitleText": "激活会员", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "offline_pay/index", "style": { "navigationBarTitleText": "支付", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "offline_result/index", "style": { "navigationBarTitleText": "支付结果", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "special/index", "style": { "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#333333", "navigationBarTitleText": "专题页", "app-plus": { "scrollIndicator": "none" }, "mp-weixin": { "componentPlaceholder": { "page-design": "view" } } } }, { "path": "settled/index", "style": { "navigationBarTitleText": "分销申请", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } } ] }, { "root": "pages/points_mall", "pages": [{ "path": "index", "style": { "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#333333", "navigationBarTitleText": "积分商城", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "integral_goods_list", "style": { "navigationBarTitleText": "商品列表", // "navigationBarTextStyle": "white", // "navigationBarBackgroundColor": "#E93323", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "integral_goods_details", "style": { "navigationStyle": "custom", "app-plus": { // #ifdef APP-PLUS "titleNView": { "padding-left": "10px", "padding-right": "10px", "type": "transparent", "buttons": [ //原生标题栏按钮配置, { "type": "menu" //原生标题栏增加分享按钮,点击事件可通过页面的 onNavigationBarButtonTap 函数进行监听 } ] } // #endif } } }, { "path": "exchange_record", "style": { "navigationBarTitleText": "兑换记录", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "integral_order", "style": { "navigationBarTitleText": "积分订单", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "user_address", "style": { "navigationBarTitleText": "选择地址", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "integral_order_status", "style": { "navigationBarTitleText": "兑换成功", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "integral_order_details", "style": { "navigationBarTitleText": "兑换订单详情", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } }, { "path": "logistics_details", "style": { "navigationBarTitleText": "兑换物流详情", "app-plus": { // #ifdef APP-PLUS "titleNView": { "type": "default" } // #endif } } } ] }, { "root": "subpackage/diyComponents", "name": "diyComponents", "pages": [{ "path": "pages/placeholder", "style": { "navigationBarTitleText": "" } }] } ], "tabBar": { // 底部菜单 "color": "#282828", "selectedColor": "#ff3366", "borderStyle": "white", "backgroundColor": "#ffffff", "list": [{ "pagePath": "pages/index/index", "iconPath": "static/images/1-001.png", "selectedIconPath": "static/images/1-002.png", "text": "首页" }, { "pagePath": "pages/goods_cate/goods_cate", "iconPath": "static/images/2-001.png", "selectedIconPath": "static/images/2-002.png", "text": "分类" }, { "pagePath": "pages/order_addcart/order_addcart", "iconPath": "static/images/3-001.png", "selectedIconPath": "static/images/3-002.png", "text": "购物车" }, { "pagePath": "pages/user/index", "iconPath": "static/images/4-001.png", "selectedIconPath": "static/images/4-002.png", "text": "我的" } ] }, "globalStyle": { "navigationBarTextStyle": "black", "navigationBarTitleText": "加载中", "navigationBarBackgroundColor": "#fff", "backgroundColor": "#F8F8F8", "titleNView": false, "pageOrientation": "portrait" // 全局设置为竖屏 }, "condition": { //模式配置,仅开发期间生效 "current": 0, //当前激活的模式(list 的索引项) "list": [{ "name": "", //模式名称 "path": "", //启动页面,必选 "query": "" //启动参数,在页面的onLoad函数里面得到 }] }, "embeddedAppIdList": ["wxef277996acc166c3"] //通联支付appid } --- ### .Codebuddy/Agents/接口开发 (.codebuddy/agents/接口开发.md) --- name: 接口开发 description: PHP接口开发智能体,专注于CRMEB电商系统的API接口开发、调试和维护 model: default tools: list_dir, search_file, search_content, read_file, read_lints, replace_in_file, write_to_file, execute_command, create_rule, delete_file, preview_url, web_fetch, use_skill, web_search agentMode: agentic enabled: true enabledAutoRun: true --- 你是一个专业的PHP接口开发智能体,专门服务于CRMEB电商系统。你的职责是帮助开发者快速理解项目架构、开发符合规范的API接口、调试和优化接口性能。 ## 🎯 核心职责 1. **接口开发**: 基于CRMEB架构快速开发符合规范的API接口 2. **代码生成**: 按照项目规范生成Controller、Service、DAO、Model代码 3. **调试支持**: 协助排查接口问题、分析错误日志 4. **性能优化**: 提供接口性能优化建议 5. **规范检查**: 确保代码符合CRMEB开发规范 ## 🏗️ CRMEB技术栈架构 ### 框架基础 - **核心框架**: ThinkPHP 6.x - **架构模式**: 多应用架构 (Multi-App) - **分层架构**: MVC + Service + DAO - **PHP版本**: 7.1-7.4 - **数据库**: MySQL 5.7+ - **缓存**: Redis (可选) ### 应用模块划分 ``` app/ ├── adminapi/ # 后台管理API (需要管理员权限) ├── api/ # 用户端API (需要用户登录) ├── kefuapi/ # 客服系统API ├── outapi/ # 外部API ├── dao/ # 数据访问层 ├── model/ # 数据模型层 ├── services/ # 业务逻辑层 ├── jobs/ # 队列任务 └── listener/ # 事件监听器 ``` ### 认证机制 - **后台管理**: AdminAuthTokenMiddleware (管理员Token) - **用户端**: AuthTokenMiddleware (用户Token) - **公共接口**: 无需认证 ## 📋 分层架构说明 ### Controller层 (控制器) **职责**: - 处理HTTP请求 - 参数验证和获取 - 调用Service层 - 统一返回响应格式 **规范要求**: ```php services = $services; } /** * 获取用户列表 */ public function getList() { $where = $this->request->getMore([ ['keywords', ''], ['status', ''], ['page', 1], ['limit', 15] ]); $list = $this->services->getUserList($where); return app('json')->success($list); } /** * 保存用户信息 */ public function save() { $data = $this->request->postMore([ ['nickname', ''], ['phone', ''], ['avatar', ''], ['status', 1] ]); $this->services->saveUser($data); return app('json')->success('保存成功'); } } ``` **命名规范**: - 控制器方法: 小写+下划线,如 `get_list`, `save_data` - 参数获取: 使用 `$this->request->getMore()` 或 `$this->request->postMore()` - 返回响应: `return app('json')->success($data)` 或 `app('json')->fail('错误信息')` ### Service层 (服务层) **职责**: - 实现核心业务逻辑 - 事务管理 - 调用DAO层 - 缓存处理 **规范要求**: ``` /* Detailed source-code truncated for AI context efficiency. */ ``` **命名规范**: - 服务方法: 驼峰法,如 `getUserList`, `saveUser` - 参数类型声明: 必须声明参数和返回值类型 - 异常处理: 使用项目异常类,如 `AdminException`, `ApiException` ### DAO层 (数据访问层) **职责**: - 封装数据库操作 - 提供数据查询方法 - 处理复杂的SQL查询 **规范要求**: ```php getModel()->where('is_del', 0); // 关键词搜索 if (!empty($where['keywords'])) { $query = $query->whereLike('nickname|phone', "%{$where['keywords']}%"); } // 状态筛选 if ($where['status'] !== '') { $query = $query->where('status', $where['status']); } return $query; } /** * 根据ID获取用户信息 * @param int $id * @return array|null */ public function getById(int $id): ?array { return $this->getModel()->where('id', $id)->find(); } } ``` **命名规范**: - DAO方法: 数据库操作相关,如 `search`, `getById`, `update`, `delete` - 查询构造: 必须返回 `\think\Model` 对象 - 模型绑定: 必须实现 `setModel()` 方法 ### Model层 (模型层) **职责**: - 定义数据模型 - 设置表名和主键 - 定义关联关系 - 定义访问器和修改器 **规范要求**: ```php hasMany(Order::class, 'uid', 'id'); } /** * 头像获取器 * @param $value * @return string */ public function getAvatarAttr($value): string { return $value ? $value : '/static/default_avatar.png'; } /** * 状态文本获取器 * @param $value * @return string */ public function getStatusTextAttr($value, $data): string { $status = [0 => '禁用', 1 => '启用']; return $status[$data['status']] ?? ''; } /** * 自动时间戳 * @var bool */ protected $autoWriteTimestamp = true; } ``` ## 📝 接口开发流程 ### 1. 创建新接口步骤 #### Step 1: 创建数据表 ```sql CREATE TABLE `eb_example` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL DEFAULT '' COMMENT '名称', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 0禁用 1启用', `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间', `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='示例表'; ``` #### Step 2: 创建Model ```bash # 创建Model php think make:model Example ``` #### Step 3: 创建DAO ```php // app/dao/ExampleDao.php getModel()->where('is_del', 0); if (!empty($where['keywords'])) { $query = $query->whereLike('name', "%{$where['keywords']}%"); } if ($where['status'] !== '') { $query = $query->where('status', $where['status']); } return $query; } } ``` #### Step 4: 创建Service ```php // app/services/ExampleServices.php dao = $dao; } public function getList(array $where): array { $query = $this->dao->search($where); $count = $query->count(); $list = $query->page($where['page'], $where['limit']) ->order('id', 'desc') ->select() ->toArray(); return compact('list', 'count'); } public function save(array $data): int { if (isset($data['id']) && $data['id']) { $id = $data['id']; unset($data['id']); $this->dao->update($id, $data); } else { $id = $this->dao->save($data); } return $id; } public function delete(int $id): bool { return $this->dao->update($id, ['is_del' => 1]); } } ``` #### Step 5: 创建Controller ```php // app/adminapi/controller/v1/ExampleController.php services = $services; } public function getList() { $where = $this->request->getMore([ ['keywords', ''], ['status', ''], ['page', 1], ['limit', 15] ]); $list = $this->services->getList($where); return app('json')->success($list); } public function save() { $data = $this->request->postMore([ ['id', 0], ['name', ''], ['status', 1] ]); $this->services->save($data); return app('json')->success('保存成功'); } public function delete() { $id = $this->request->param('id'); $this->services->delete($id); return app('json')->success('删除成功'); } } ``` #### Step 6: 创建路由 ```php // app/adminapi/route/example.php 'require|max:255', 'status' => 'require|in:0,1', ]; protected $message = [ 'name.require' => '名称不能为空', 'name.max' => '名称最多255个字符', 'status.require' => '状态不能为空', 'status.in' => '状态值不正确', ]; } ``` ### 2. 接口响应规范 #### 成功响应 ```json { "status": 200, "msg": "success", "data": { "list": [], "count": 100 }, "time": "2024-01-01 10:00:00" } ``` #### 失败响应 ```json { "status": 400, "msg": "错误信息", "data": null, "time": "2024-01-01 10:00:00" } ``` #### 分页响应 ```json { "status": 200, "msg": "success", "data": { "list": [...], "count": 100, "page": 1, "limit": 15 } } ``` ### 3. 错误码规范 | 错误码 | 说明 | |-------|------| | 200 | 成功 | | 400 | 参数错误 | | 401 | 未授权(未登录) | | 403 | 权限不足 | | 404 | 资源不存在 | | 422 | 验证失败 | | 500 | 服务器错误 | ### 4. 异常处理 ```php // 使用项目异常类 use crmeb\exceptions\AdminException; use crmeb\exceptions\ApiException; // 业务异常 if (empty($data)) { throw new AdminException('数据不存在'); } // 权限异常 if (!$hasPermission) { throw new AdminException('无权访问', 403); } // 参数验证失败 if (!$validated) { throw new ApiException('参数错误', 400); } ``` ## 🔧 常用开发工具类 ### 1. 配置获取 ```php // 获取系统配置 $configValue = \app\services\system\ConfigServices::get('config_key'); // 缓存配置 $cacheValue = Cache::get('cache_key'); Cache::set('cache_key', $value, 3600); ``` ### 2. 文件上传 ```php // 使用上传服务 use crmeb\services\upload\UploadService; $uploadService = UploadService::instance(); $result = $uploadService->to('oss')->move($file); $imageUrl = $result['url']; ``` ### 3. 日志记录 ```php // 记录日志 Log::info('操作日志', $data); Log::error('错误信息', $error); Log::debug('调试信息', $debug); ``` ### 4. 队列任务 ```php // 推送队列任务 use think\queue\Job; use app\jobs\OrderJob; // 异步执行 Queue::push(new OrderJob($orderData)); // 延迟执行(秒) Queue::later(3600, new OrderJob($orderData)); ``` ## 📊 核心业务模块 ### 1. 用户模块 - **用户管理**: 用户信息、等级、分组、标签 - **认证登录**: 账号密码、手机验证码、微信授权 - **余额积分**: 充值、提现、账单记录 - **收货地址**: 地址管理 ### 2. 商品模块 - **商品管理**: 商品信息、分类、属性、规格(SKU) - **库存管理**: 库存扣减、库存预警 - **商品评价**: 评价管理、评分统计 - **商品导入**: 淘宝商品采集 ### 3. 订单模块 - **订单创建**: 商品验证、价格计算、库存扣减 - **支付流程**: 调起支付、支付回调、状态更新 - **订单发货**: 物流信息、发货通知 - **订单售后**: 退款、退货、换货 ### 4. 营销模块 - **优惠券**: 优惠券模板、用户优惠券、使用验证 - **拼团活动**: 拼团商品、拼团记录、成团判断 - **砍价活动**: 砍价商品、砍价进度、完成判断 - **秒杀活动**: 秒杀商品、限购控制、库存管理 ### 5. 支付模块 - **微信支付**: 公众号支付、小程序支付、H5支付 - **支付宝支付**: APP支付、网页支付、扫码支付 - **余额支付**: 余额支付、密码验证 - **支付回调**: 异步通知处理、签名验证 ## 🚀 性能优化建议 ### 1. 数据库优化 - 为常用查询字段添加索引 - 避免使用 `SELECT *`,只查询需要的字段 - 使用 `EXPLAIN` 分析SQL执行计划 - 合理使用缓存减少数据库查询 ### 2. 缓存优化 - 使用Redis缓存热点数据 - 设置合理的缓存过期时间 - 使用缓存前缀防止冲突 - 缓存更新时注意一致性 ### 3. 代码优化 - 减少循环嵌套 - 优化算法复杂度 - 使用队列处理耗时操作 - 异步处理非关键业务 ### 4. 接口优化 - 合理使用分页 - 控制返回数据量 - 使用HTTP压缩 - 启用CDN加速 ## 🐛 常见问题排查 ### 1. 数据库连接失败 ```php // 错误信息 SQLSTATE[HY000] [2002] Connection refused // 排查步骤 1. 检查数据库服务是否启动 2. 检查 .env 配置文件中的数据库配置 3. 检查数据库用户权限 4. 检查防火墙设置 ``` ### 2. 队列任务不执行 ```bash # 排查步骤 1. 检查队列消费者是否启动: php think queue:work 2. 检查队列配置: config/queue.php 3. 检查Redis连接: redis-cli ping 4. 查看队列日志: runtime/log/ ``` ### 3. Token认证失败 ```php // 错误信息 401 Unauthorized // 排查步骤 1. 检查Token是否正确传递 2. 检查Token是否过期 3. 检查中间件配置 4. 检查JWT配置 ``` ## 📚 常用命令 ```bash # 生成控制器 php think make:controller UserController # 生成模型 php think make:model User # 生成验证器 php think make:validate UserValidate # 清除缓存 php think clear # 启动队列 php think queue:listen # 启动定时任务 php think timer start # 启动WebSocket php think workerman start ``` ## 🎯 开发检查清单 在提交代码前,请确保: - [ ] 代码符合CRMEB命名规范 - [ ] 方法有完整的PHPDoc注释 - [ ] 参数验证完整 - [ ] 异常处理完善 - [ ] 返回格式统一 - [ ] 日志记录合理 - [ ] 数据库操作使用DAO层 - [ ] 业务逻辑在Service层 - [ ] SQL查询已优化 - [ ] 测试通过 - [ ] 无敏感信息泄露 - [ ] 权限验证正确 ## 💡 最佳实践 1. **单一职责**: 每个类和方法只做一件事 2. **依赖注入**: 通过构造函数注入依赖 3. **接口隔离**: Controller不直接操作数据库 4. **事务管理**: Service层使用事务确保数据一致性 5. **异常处理**: 使用项目异常类,统一错误处理 6. **日志记录**: 记录关键操作和错误信息 7. **代码复用**: 抽象公共逻辑到基类或工具类 8. **性能优化**: 合理使用缓存和队列 9. **安全防护**: 参数验证、SQL注入防护、XSS防护 10. **文档完善**: 保持注释和文档的及时更新 ## 📖 参考文档 - [ThinkPHP 6 官方文档](https://www.kancloud.cn/manual/thinkphp6_0) - [CRMEB 开发文档](./dev-docs/phpapi/) - [数据库结构设计](./dev-docs/phpapi/数据库结构设计.md) - [开发规范说明](./dev-docs/phpapi/开发规范说明.md) - [API接口文档](./dev-docs/phpapi/API接口文档.md) - [业务流程说明](./dev-docs/phpapi/业务流程说明.md) --- **提示**: 在开发过程中,始终遵循CRMEB的开发规范,确保代码质量和系统稳定性。 --- ### .Codebuddy/Skills/Admin Element/References/Api Flow (.codebuddy/skills/admin-element/references/api_flow.md) # Admin-Element 接口请求流程文档 ## 1 API 请求流程概述 Admin-Element 项目的 API 请求流程遵循以下步骤: 1. **接口定义**: 在 `src/api/` 目录下按模块定义 API 接口 2. **请求封装**: 使用 `axios` 封装网络请求,添加拦截器 3. **接口调用**: 在组件或业务逻辑中调用 API 接口 4. **响应处理**: 统一处理 API 响应,包括成功和失败情况 5. **错误处理**: 统一处理网络错误、业务错误等异常情况 6. **数据管理**: 将获取的数据存储到状态管理或组件中 ## 2 网络请求封装 ### 2.1 axios 实例创建 在 `src/utils/request.js` 中创建 axios 实例并配置: ```javascript import axios from 'axios' import { Message, Loading } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' // 创建 axios 实例 const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // API 基础路径 timeout: 10000, // 请求超时时间 headers: { 'Content-Type': 'application/json;charset=utf-8' } }) ``` ### 2.2 请求拦截器 ```javascript // 请求拦截器 service.interceptors.request.use( config => { // 显示加载动画 if (config.loading !== false) { store.dispatch('app/showLoading') } // 自动添加 token if (store.getters.token) { config.headers['Authorization'] = `Bearer ${getToken()}` } return config }, error => { // 隐藏加载动画 store.dispatch('app/hideLoading') console.error('请求错误:', error) return Promise.reject(error) } ) ``` ### 2.3 响应拦截器 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 3 API 接口定义 ### 3.1 接口文件组织 API 接口按模块组织,存放在 `src/api/` 目录下: ``` src/api/ ├── index.js # API 入口文件 ├── user.js # 用户相关接口 ├── goods.js # 商品相关接口 ├── order.js # 订单相关接口 └── ... # 其他模块接口 ``` ### 3.2 接口定义示例 在 `src/api/user.js` 中定义用户相关接口: ```javascript import request from '@/utils/request' export default { // 登录 login(data) { return request({ url: '/admin/login', method: 'post', data }) }, // 获取用户信息 getUserInfo() { return request({ url: '/admin/user/info', method: 'get' }) }, // 获取用户列表 getUserList(params) { return request({ url: '/admin/user/list', method: 'get', params }) }, // 修改用户信息 updateUser(data) { return request({ url: '/admin/user/update', method: 'put', data }) }, // 删除用户 deleteUser(id) { return request({ url: `/admin/user/delete/${id}`, method: 'delete' }) } } ``` ### 3.3 API 入口文件 在 `src/api/index.js` 中导出所有 API 模块: ```javascript import user from './user' import goods from './goods' import order from './order' // 导出 API 模块 export default { user, goods, order } ``` ## 4 请求和响应处理 ### 4.1 请求参数处理 #### 4.1.1 GET 请求 ```javascript // 带查询参数的 GET 请求 api.user.getUserList({ page: 1, limit: 10, keyword: 'test' }) ``` #### 4.1.2 POST 请求 ```javascript // 带请求体的 POST 请求 api.user.login({ username: 'admin', password: '123456' }) ``` #### 4.1.3 PUT 请求 ```javascript // 带请求体的 PUT 请求 api.user.updateUser({ id: 1, username: 'newadmin', nickname: '新管理员' }) ``` #### 4.1.4 DELETE 请求 ```javascript // 路径参数的 DELETE 请求 api.user.deleteUser(1) ``` ### 4.2 响应数据结构 后端 API 响应数据结构应遵循以下规范: ```javascript { "code": 200, // 状态码,200 表示成功 "message": "操作成功", // 响应消息 "data": { ... } // 响应数据 } ``` ### 4.3 响应处理示例 ```javascript // 在组件中调用 API import api from '@/api' export default { methods: { async fetchUserList() { try { const res = await api.user.getUserList({ page: this.page, limit: this.limit }) // 处理成功响应 this.userList = res.data.list this.total = res.data.total } catch (error) { // 错误已在拦截器中处理,这里可以做额外处理 console.error('获取用户列表失败:', error) } } } } ``` ## 5 错误处理机制 ### 5.1 网络错误 - 网络连接失败 - 请求超时 - 服务器无响应 ### 5.2 业务错误 - 参数错误 (400) - 未授权 (401) - 拒绝访问 (403) - 请求地址不存在 (404) - 服务器内部错误 (500) ### 5.3 业务逻辑错误 - 状态码非 200 的响应 - 业务规则验证失败 ### 5.4 错误处理最佳实践 1. **统一错误处理**: 在响应拦截器中统一处理错误 2. **友好的错误提示**: 向用户显示清晰的错误消息 3. **错误日志记录**: 记录错误信息,便于排查问题 4. **特殊错误处理**: 对 token 过期等特殊情况进行处理 5. **降级处理**: 网络错误时提供合理的降级方案 ## 6 接口调用最佳实践 ### 6.1 使用 async/await ```javascript async fetchData() { try { const res = await api.goods.getGoodsList(this.queryParams) this.goodsList = res.data.list this.total = res.data.total } catch (error) { // 错误处理 } } ``` ### 6.2 加载状态管理 ```javascript export default { data() { return { loading: false, goodsList: [] } }, methods: { async fetchData() { this.loading = true try { const res = await api.goods.getGoodsList(this.queryParams) this.goodsList = res.data.list } catch (error) { // 错误处理 } finally { this.loading = false } } } } ``` ### 6.3 防抖和节流 对于频繁触发的请求,使用防抖或节流优化: ```javascript import { debounce } from 'lodash' export default { methods: { // 使用防抖优化搜索请求 search: debounce(async function(query) { try { const res = await api.goods.searchGoods({ keyword: query }) this.searchResults = res.data } catch (error) { // 错误处理 } }, 300) } } ``` ### 6.4 请求取消 对于可能重复触发的请求,使用取消令牌避免重复请求: ```javascript import axios from 'axios' export default { data() { return { cancelToken: null } }, methods: { async fetchData() { // 取消之前的请求 if (this.cancelToken) { this.cancelToken.cancel('取消重复请求') } // 创建新的取消令牌 this.cancelToken = axios.CancelToken.source() try { const res = await api.goods.getGoodsList({ page: this.page, limit: this.limit }, { cancelToken: this.cancelToken.token }) this.goodsList = res.data.list } catch (error) { if (axios.isCancel(error)) { console.log('请求已取消:', error.message) } else { // 错误处理 } } } } } ``` ## 7 接口安全 ### 7.1 认证与授权 - 使用 JWT 令牌进行身份认证 - 请求头中携带 Authorization 字段 - 定期刷新令牌,避免过期 ### 7.2 数据加密 - 敏感数据传输加密 - 密码等敏感信息使用 HTTPS 传输 ### 7.3 防止 CSRF 攻击 - 使用 CSRF Token - 验证请求来源 ### 7.4 接口速率限制 - 后端实现接口速率限制 - 前端避免频繁请求 ## 8 性能优化 ### 8.1 请求合并 对于多个相同类型的请求,合并为一个请求: ```javascript // 批量获取数据 api.goods.batchGetGoodsInfo(ids) ``` ### 8.2 缓存策略 - 对不常变化的数据进行缓存 - 使用 localStorage 或 sessionStorage 缓存数据 ### 8.3 懒加载 - 按需加载数据 - 滚动到底部加载更多数据 ### 8.4 预加载 - 预加载可能需要的数据 - 提升用户体验 ## 9 调试技巧 ### 9.1 接口调试工具 - 使用 Chrome DevTools 的 Network 面板 - 使用 Postman 等 API 调试工具 ### 9.2 日志记录 - 在开发环境下打印详细的请求和响应信息 - 在生产环境下只记录错误信息 ### 9.3 模拟数据 - 使用 Mock 数据进行前端开发 - 减少对后端接口的依赖 ## 10 总结 Admin-Element 项目的 API 请求流程采用了统一的封装和处理机制,通过 axios 拦截器实现了请求和响应的统一处理,提高了代码的可维护性和可扩展性。开发者应遵循接口定义规范和最佳实践,确保 API 调用的安全性、可靠性和性能。 --- ### .Codebuddy/Skills/Admin Element/References/Code Style (.codebuddy/skills/admin-element/references/code_style.md) # 管理端前端代码规范文档 ## 1. 概述 本文档描述了 CRMEB 项目中管理端前端的代码规范,包括命名规范、代码风格、文件结构、组件开发等方面的规范,旨在统一代码风格,提高代码质量和可维护性。 ## 2. 命名规范 ### 2.1 目录命名 - **目录名**: 小写字母,单词之间用连字符分隔 - **示例**: `components/common/`、`pages/user-management/`、`utils/` - **规范**: 简洁明了,反映目录的功能 ### 2.2 文件命名 - **组件文件**: 大写字母开头的 PascalCase 命名风格 - **示例**: `Button.vue`、`UserList.vue`、`Navbar.vue` - **页面文件**: 小写字母,单词之间用连字符分隔 - **示例**: `login.vue`、`user-list.vue`、`dashboard.vue` - **JS 文件**: 小写字母,单词之间用连字符分隔 - **示例**: `api.js`、`request.js`、`util.js` - **CSS/SCSS 文件**: 小写字母,单词之间用连字符分隔 - **示例**: `common.scss`、`theme.scss`、`variables.scss` ### 2.3 变量命名 - **普通变量**: 驼峰命名法 - **示例**: `userInfo`、`goodsList`、`isLoading` - **常量**: 全大写,单词之间用下划线分隔 - **示例**: `BASE_URL`、`MAX_COUNT`、`DEFAULT_PAGE_SIZE` - **布尔变量**: 以 `is` 开头的驼峰命名法 - **示例**: `isShow`、`isLoading`、`isLogin` - **数组变量**: 以复数形式命名 - **示例**: `users`、`goods`、`orders` - **对象变量**: 以单数形式命名 - **示例**: `user`、`good`、`order` ### 2.4 函数命名 - **函数名**: 驼峰命名法,动词开头 - **示例**: `getUserInfo`、`submitForm`、`handleClick` - **方法名**: 驼峰命名法 - **示例**: `data`、`methods`、`computed`、`watch` - **生命周期函数**: 按照 Vue 规范命名 - **示例**: `created`、`mounted`、`beforeDestroy` - **事件处理函数**: 以 `handle` 开头 - **示例**: `handleSubmit`、`handleClick`、`handleChange` ### 2.5 组件命名 - **组件名**: PascalCase 命名风格 - **示例**: `Button`、`UserList`、`Navbar` - **组件标签**: 小写字母,单词之间用连字符分隔 - **示例**: ``、``、`` - **组件文件名**: 与组件名一致,PascalCase 命名 - **示例**: `Button.vue`、`UserList.vue`、`Navbar.vue` ### 2.6 其他命名 - **路由命名**: 小写字母,单词之间用连字符分隔 - **示例**: `/login`、`/user/list`、`/dashboard` - **CSS 类名**: 小写字母,单词之间用连字符分隔 - **示例**: `.user-info`、`.goods-list`、`.btn-primary` - **ID 命名**: 小写字母,单词之间用连字符分隔 - **示例**: `#app`、`#header`、`#footer` - **Vuex 模块命名**: 小写字母,单词之间用连字符分隔 - **示例**: `user`、`goods`、`orders` ## 3. 代码风格 ### 3.1 缩进 - **缩进方式**: 4 个空格 - **示例**: ```vue ``` ### 3.2 换行 - **标签换行**: 多个属性的标签应该换行 - **示例**: ```vue 提交 ``` - **代码块换行**: 逻辑代码块应该换行 - **示例**: ```javascript if (condition) { // 代码块 } else { // 代码块 } ``` ### 3.3 空格 - **运算符空格**: 运算符两侧应该有空格 - **示例**: `a + b`、`x = y`、`i < 10` - **逗号空格**: 逗号后面应该有空格 - **示例**: `[1, 2, 3]`、`{ name: '张三', age: 18 }` - **括号空格**: 括号内侧不应该有空格 - **示例**: `if (condition)`、`function (param)` - **冒号空格**: 对象字面量中冒号后面应该有空格 - **示例**: `{ name: '张三', age: 18 }` ### 3.4 注释 - **单行注释**: 使用 `//` 注释 - **示例**: `// 这是单行注释` - **多行注释**: 使用 `/* */` 注释 - **示例**: ```javascript /* * 这是多行注释 * 第二行 */ ``` - **文档注释**: 使用 JSDoc 风格的注释 - **示例**: ```javascript /** * 获取用户信息 * @param {number} id - 用户ID * @returns {Promise} 用户信息 */ async function getUserInfo(id) { // 代码 } ``` - **组件注释**: 组件使用文档注释 - **示例**: ```vue /** * 用户列表组件 * @props {Array} users - 用户列表数据 * @props {Boolean} loading - 是否加载中 * @events {Function} select - 选择用户时触发 */ ``` ### 3.5 引号 - **字符串**: 使用单引号 `''` - **示例**: `const name = '张三'`、`Hello` - **模板字符串**: 使用反引号 `` ` `` - **示例**: `` const url = `${baseUrl}/api/user` `` - **HTML 属性**: 使用双引号 `""` - **示例**: `
`、`` ### 3.6 分号 - **语句结束**: 每个语句结束都应该加分号 - **示例**: `const name = '张三';`、`function() {};` ### 3.7 空行 - **代码块之间**: 代码块之间应该有空行 - **示例**: ```javascript function first() { // 代码 } function second() { // 代码 } ``` - **逻辑块之间**: 逻辑块之间应该有空行 - **示例**: ```javascript if (condition) { // 代码 } while (loop) { // 代码 } ``` ## 4. 文件结构 ### 4.1 组件文件结构 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 4.2 页面文件结构 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 4.3 JS 文件结构 ```javascript // 导入依赖 import axios from 'axios'; import { Message } from 'element-ui'; // 常量定义 const BASE_URL = process.env.VUE_APP_API_BASE_URL; const TIMEOUT = 10000; // 创建 axios 实例 const service = axios.create({ baseURL: BASE_URL, timeout: TIMEOUT }); // 请求拦截器 service.interceptors.request.use( config => { // 添加 token const token = localStorage.getItem('token'); if (token) { config.headers['Authorization'] = `Bearer ${token}`; } return config; }, error => { console.error('请求错误:', error); return Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( response => { const { data } = response; if (data.code !== 200) { Message.error(data.message || '请求失败'); return Promise.reject(data); } return data; }, error => { console.error('响应错误:', error); Message.error('网络错误,请稍后重试'); return Promise.reject(error); } ); // 工具函数 function formatDate(date) { const d = new Date(date); return d.toLocaleString(); } function deepClone(obj) { return JSON.parse(JSON.stringify(obj)); } // 导出 export { service, formatDate, deepClone }; // 默认导出 export default service; ``` ## 5. 组件开发规范 ### 5.1 组件设计 - **单一职责**: 每个组件只负责一个功能 - **可复用性**: 设计通用的、可复用的组件 - **可配置性**: 通过 props 提供配置选项 - **事件通信**: 通过事件与父组件通信 - **插槽支持**: 提供插槽,增强组件灵活性 ### 5.2 组件使用 - **组件导入**: 使用 import 导入组件 - **示例**: `import Button from '@/components/Button.vue'` - **组件注册**: 在 components 中注册组件 - **示例**: ```javascript components: { Button } ``` - **组件使用**: 使用组件标签 - **示例**: `` - **组件传值**: 通过 props 传递数据 - **示例**: `` - **事件监听**: 监听组件事件 - **示例**: `` ### 5.3 组件通信 - **props 向下传递**: 父组件通过 props 向子组件传递数据 - **events 向上传递**: 子组件通过 events 向父组件传递事件 - **refs 引用**: 通过 refs 引用子组件实例 - **provide/inject**: 祖先组件向后代组件传递数据 - **Vuex 全局状态**: 使用 Vuex 管理全局状态 - **EventBus**: 组件间事件总线 ### 5.4 组件生命周期 - **created**: 初始化数据,发送请求 - **mounted**: 操作 DOM,初始化第三方库 - **beforeUpdate**: 更新前的准备工作 - **updated**: 数据更新后的操作 - **beforeDestroy**: 清理定时器,取消订阅 - **destroyed**: 组件销毁后的清理工作 ### 5.5 组件命名规范 - **组件名**: PascalCase 命名风格 - **组件文件名**: 与组件名一致 - **组件目录**: 按功能分类存放 - **组件前缀**: 通用组件使用统一前缀 ## 6. 页面开发规范 ### 6.1 页面结构 - **模板结构**: 清晰明了,层次分明 - **脚本结构**: 按照 Vue 规范组织代码 - **样式结构**: 模块化,可维护 - **布局规范**: 遵循统一的布局规范 ### 6.2 数据管理 - **本地数据**: 使用 data 管理组件内部数据 - **计算数据**: 使用 computed 计算衍生数据 - **监听数据**: 使用 watch 监听数据变化 - **全局数据**: 使用 Vuex 管理全局数据 ### 6.3 路由管理 - **路由配置**: 在 router 目录中配置路由 - **路由跳转**: 使用 router.push、router.replace 等方法 - **路由参数**: 通过 $route.params 获取路由参数 - **路由守卫**: 使用全局/局部路由守卫 ### 6.4 API 调用 - **API 封装**: 统一封装 API 调用 - **异步处理**: 使用 async/await 处理异步请求 - **错误处理**: 使用 try/catch 捕获错误 - **加载状态**: 显示加载状态,提升用户体验 ### 6.5 用户体验 - **响应式设计**: 适配不同屏幕尺寸 - **加载状态**: 显示加载中提示 - **错误提示**: 显示错误信息 - **成功提示**: 显示操作成功提示 - **表单验证**: 实时表单验证 - **防抖节流**: 优化频繁触发的事件 ## 7. 性能优化 ### 7.1 代码优化 - **减少冗余代码**: 避免重复的代码 - **使用计算属性**: 对于复杂的计算,使用 computed - **使用 v-if 和 v-show 合理**: 根据场景选择合适的指令 - **使用 key**: 在 v-for 中使用 key,提高渲染性能 - **避免频繁更新**: 使用防抖和节流 ### 7.2 网络优化 - **合理使用缓存**: 缓存不经常变化的数据 - **减少请求次数**: 合并请求,批量操作 - **使用 CDN**: 静态资源使用 CDN - **压缩传输**: 使用 gzip 压缩传输数据 ### 7.3 构建优化 - **Tree Shaking**: 移除未使用的代码 - **代码分割**: 按路由分割代码 - **懒加载**: 路由懒加载,组件懒加载 - **预加载**: 预加载关键资源 ### 7.4 其他优化 - **减少 DOM 节点**: 简化 DOM 结构 - **优化图片**: 使用合适的图片格式和大小 - **使用虚拟列表**: 对于长列表,使用虚拟列表 - **避免内存泄漏**: 及时清理定时器、事件监听器等 ## 8. 常见问题 ### 8.1 代码风格问题 - **问题**: 代码风格不一致 - **解决方案**: 使用 ESLint 和 Prettier 统一代码风格 ### 8.2 性能问题 - **问题**: 页面加载慢,卡顿 - **解决方案**: 优化代码,减少 DOM 操作,使用虚拟列表等 ### 8.3 兼容性问题 - **问题**: 在不同浏览器上表现不一致 - **解决方案**: 遵循 Web 标准,使用 polyfill ### 8.4 维护性问题 - **问题**: 代码难以维护 - **解决方案**: 模块化开发,添加注释,遵循代码规范 ### 8.5 命名冲突问题 - **问题**: 命名冲突 - **解决方案**: 使用命名空间,避免全局变量 ## 9. 参考资源 - [Vue 官方风格指南](https://v2.vuejs.org/v2/style-guide/) - [Element UI 官方文档](https://element.eleme.io/#/zh-CN) - [ESLint 官方文档](https://eslint.org/docs/user-guide/) - [Prettier 官方文档](https://prettier.io/docs/en/) - [JavaScript 代码规范](https://github.com/airbnb/javascript) - [CSS 代码规范](https://github.com/airbnb/css) ## 10. 总结 本文档描述了 CRMEB 项目中管理端前端的代码规范,包括命名规范、代码风格、文件结构、组件开发等方面的规范。遵循本文档的规范,可以提高代码的可读性、可维护性和可扩展性,确保项目的质量和稳定性。 代码规范是团队协作的基础,建议开发团队成员严格遵循本文档的规范,共同维护一个高质量的代码库。 --- ### .Codebuddy/Skills/Admin Element/References/Deploy (.codebuddy/skills/admin-element/references/deploy.md) # 管理端前端部署文档 ## 1. 概述 本文档描述了 CRMEB 项目中管理端前端的部署流程,包括构建、部署、配置等环节,旨在规范前端部署流程,确保部署过程的顺利进行和系统的稳定运行。 ## 2. 部署环境 ### 2.1 服务器要求 - **操作系统**: Linux (Ubuntu 18.04+、CentOS 7+) - **Web 服务器**: Nginx 1.14+ 或 Apache 2.4+ - **Node.js**: v12.0.0+ (仅构建时需要) - **npm/yarn**: v6.0.0+ (仅构建时需要) - **内存**: 至少 2GB RAM - **CPU**: 至少 2 核 CPU - **磁盘空间**: 至少 20GB 可用空间 ### 2.2 环境准备 - **Web 服务器配置**: 配置虚拟主机,指向前端构建产物目录 - **SSL 证书**: 配置 HTTPS,使用 SSL 证书 - **防火墙**: 开放 80/443 端口 - **域名**: 配置域名解析,指向服务器 IP ## 3. 构建流程 ### 3.1 开发环境构建 - **命令**: `npm run dev` - **用途**: 本地开发,启动开发服务器 - **访问地址**: `http://localhost:8080` ### 3.2 测试环境构建 - **命令**: `npm run build:test` - **用途**: 测试环境部署 - **构建产物**: `dist/` 目录 ### 3.3 生产环境构建 - **命令**: `npm run build:prod` - **用途**: 生产环境部署 - **构建产物**: `dist/` 目录 ### 3.4 构建优化 - **代码压缩**: 压缩 JS/CSS/HTML 文件 - **资源压缩**: 压缩图片等静态资源 - **Tree Shaking**: 移除未使用的代码 - **代码分割**: 按路由分割代码 - **预加载**: 预加载关键资源 ## 4. 部署方式 ### 4.1 静态部署 #### 4.1.1 Nginx 配置 ```nginx server { listen 80; server_name admin.example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name admin.example.com; # SSL 配置 ssl_certificate /path/to/ssl/cert.pem; ssl_certificate_key /path/to/ssl/key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers on; # 静态文件配置 root /path/to/admin/dist; index index.html; # 路由重写,解决单页应用刷新 404 问题 location / { try_files $uri $uri/ /index.html; } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 30d; add_header Cache-Control "public, max-age=2592000"; } # 日志配置 access_log /var/log/nginx/admin_access.log; error_log /var/log/nginx/admin_error.log; } ``` #### 4.1.2 Apache 配置 ```apache ServerName admin.example.com Redirect permanent / https://admin.example.com/ ServerName admin.example.com # SSL 配置 SSLEngine on SSLCertificateFile /path/to/ssl/cert.pem SSLCertificateKeyFile /path/to/ssl/key.pem # 静态文件配置 DocumentRoot /path/to/admin/dist AllowOverride All Require all granted # 路由重写,解决单页应用刷新 404 问题 RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] # 日志配置 ErrorLog ${APACHE_LOG_DIR}/admin_error.log CustomLog ${APACHE_LOG_DIR}/admin_access.log combined ``` ### 4.2 容器部署 #### 4.2.1 Dockerfile ```dockerfile # 基础镜像 FROM node:12-alpine as build # 设置工作目录 WORKDIR /app # 复制依赖文件 COPY package*.json ./ # 安装依赖 RUN npm install # 复制源代码 COPY . . # 构建生产版本 RUN npm run build:prod # 生产镜像 FROM nginx:1.19-alpine # 复制构建产物 COPY --from=build /app/dist /usr/share/nginx/html # 复制 Nginx 配置 COPY nginx.conf /etc/nginx/conf.d/default.conf # 暴露端口 EXPOSE 80 # 启动 Nginx CMD ["nginx", "-g", "daemon off;"] ``` #### 4.2.2 Docker Compose ```yaml version: '3' services: admin: build: . ports: - "80:80" restart: always volumes: - ./ssl:/etc/nginx/ssl environment: - TZ=Asia/Shanghai ``` #### 4.2.3 部署命令 ```bash # 构建镜像 docker build -t crmeb-admin . # 运行容器 docker run -d --name crmeb-admin -p 80:80 crmeb-admin # 使用 Docker Compose docker-compose up -d ``` ### 4.3 CDN 部署 #### 4.3.1 配置 CDN - **源站设置**: 指向静态文件服务器 - **缓存策略**: 配置静态资源缓存时间 - **HTTPS**: 开启 HTTPS - **HTTP/2**: 开启 HTTP/2 #### 4.3.2 部署流程 1. 构建前端项目 2. 上传构建产物到 CDN 3. 配置 CDN 缓存策略 4. 验证部署结果 ## 5. 配置管理 ### 5.1 环境变量配置 - **开发环境**: `.env.development` - **测试环境**: `.env.test` - **生产环境**: `.env.production` ### 5.2 配置示例 ```env # API 基础地址 VUE_APP_API_BASE_URL=https://api.example.com # 静态资源 CDN 地址 VUE_APP_CDN_BASE_URL=https://cdn.example.com # 应用名称 VUE_APP_TITLE=CRMEB 管理后台 # 构建环境 NODE_ENV=production # 构建版本 VUE_APP_VERSION=1.0.0 ``` ### 5.3 运行时配置 - **API 地址**: 可通过环境变量或配置文件修改 - **主题配置**: 可通过配置文件修改 - **权限配置**: 可通过后端 API 动态获取 ## 6. 部署流程 ### 6.1 手动部署 1. **拉取代码**: `git pull origin master` 2. **安装依赖**: `npm install` 3. **构建项目**: `npm run build:prod` 4. **部署文件**: 将 `dist/` 目录复制到服务器 5. **配置 Web 服务器**: 配置虚拟主机 6. **重启服务**: 重启 Web 服务器 7. **验证部署**: 访问管理端地址 ### 6.2 自动化部署 #### 6.2.1 CI/CD 配置 - **Jenkins**: 配置 Jenkins 任务,实现自动构建和部署 - **GitLab CI**: 配置 `.gitlab-ci.yml`,实现自动构建和部署 - **GitHub Actions**: 配置 `.github/workflows/deploy.yml`,实现自动构建和部署 #### 6.2.2 GitHub Actions 示例 ```yaml name: Deploy Admin Frontend on: push: branches: - master jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: '12' - name: Install dependencies run: npm install - name: Build project run: npm run build:prod - name: Deploy to server uses: easingthemes/ssh-deploy@v2.1.5 env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} ARGS: '-rltgoDzvO --delete' SOURCE: 'dist/' REMOTE_HOST: ${{ secrets.REMOTE_HOST }} REMOTE_USER: ${{ secrets.REMOTE_USER }} REMOTE_PORT: ${{ secrets.REMOTE_PORT }} TARGET: ${{ secrets.REMOTE_TARGET }} - name: Restart Nginx uses: appleboy/ssh-action@master with: host: ${{ secrets.REMOTE_HOST }} username: ${{ secrets.REMOTE_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: ${{ secrets.REMOTE_PORT }} script: sudo systemctl restart nginx ``` ## 7. 监控与维护 ### 7.1 监控 - **访问日志**: 分析 Web 服务器访问日志 - **错误日志**: 监控 Web 服务器错误日志 - **性能监控**: 监控页面加载速度、响应时间 - **可用性监控**: 监控服务可用性,设置告警 ### 7.2 维护 - **定期更新**: 定期更新前端代码,修复漏洞 - **缓存清理**: 定期清理 CDN 缓存 - **日志清理**: 定期清理日志文件 - **备份**: 定期备份构建产物和配置文件 ### 7.3 常见问题 #### 7.3.1 404 问题 - **问题**: 刷新页面出现 404 错误 - **解决方案**: 配置 Web 服务器,将所有请求重定向到 index.html #### 7.3.2 静态资源加载失败 - **问题**: 静态资源(JS/CSS/图片)加载失败 - **解决方案**: 检查静态资源路径,确保 CDN 配置正确 #### 7.3.3 API 调用失败 - **问题**: 前端无法调用后端 API - **解决方案**: 检查 API 地址配置,确保后端服务正常运行 #### 7.3.4 性能问题 - **问题**: 页面加载慢,卡顿 - **解决方案**: 优化前端代码,使用 CDN,启用 HTTP/2 ## 8. 回滚策略 ### 8.1 版本管理 - **版本号**: 遵循语义化版本规范 - **发布记录**: 记录每次发布的版本和变更内容 - **备份**: 备份每次发布的构建产物 ### 8.2 回滚流程 1. **停止服务**: 停止当前版本的服务 2. **恢复备份**: 恢复到上一个稳定版本 3. **重启服务**: 启动恢复后的服务 4. **验证回滚**: 验证服务是否正常运行 ### 8.3 回滚方案 - **手动回滚**: 手动复制备份文件到部署目录 - **自动化回滚**: 通过 CI/CD 工具实现自动回滚 - **容器回滚**: 通过 Docker 镜像版本回滚 ## 9. 安全部署 ### 9.1 HTTPS 配置 - **SSL 证书**: 使用正规 CA 签发的 SSL 证书 - **证书续期**: 定期续期 SSL 证书 - **HTTP 重定向**: 将 HTTP 请求重定向到 HTTPS ### 9.2 安全头部 - **Content-Security-Policy**: 配置内容安全策略 - **X-Content-Type-Options**: 防止 MIME 类型嗅探 - **X-Frame-Options**: 防止点击劫持 - **X-XSS-Protection**: 启用 XSS 过滤 ### 9.3 访问控制 - **IP 白名单**: 限制管理端访问 IP - **登录验证**: 强制登录验证 - **权限控制**: 基于角色的权限控制 - **会话管理**: 安全的会话管理 ### 9.4 漏洞防护 - **依赖扫描**: 定期扫描依赖包漏洞 - **代码审计**: 定期进行代码安全审计 - **渗透测试**: 定期进行渗透测试 ## 10. 最佳实践 ### 10.1 构建优化 - **使用缓存**: 缓存依赖包和构建产物 - **并行构建**: 使用多线程并行构建 - **增量构建**: 只构建变更的文件 - **构建日志**: 保存构建日志,便于排查问题 ### 10.2 部署优化 - **灰度发布**: 采用灰度发布策略 - **蓝绿部署**: 采用蓝绿部署策略 - **滚动部署**: 采用滚动部署策略 - **金丝雀发布**: 采用金丝雀发布策略 ### 10.3 监控优化 - **实时监控**: 实时监控系统运行状态 - **告警机制**: 设置合理的告警阈值 - **日志聚合**: 聚合多服务器日志 - **性能分析**: 定期分析系统性能 ### 10.4 安全优化 - **最小权限**: 遵循最小权限原则 - **定期更新**: 定期更新依赖和系统 - **安全扫描**: 定期进行安全扫描 - **应急响应**: 建立安全应急响应机制 ## 11. 总结 本文档描述了 CRMEB 项目中管理端前端的部署流程,包括构建、部署、配置等环节,以及相关的最佳实践和常见问题解决方案。 遵循本文档的部署流程和规范,可以确保前端部署的顺利进行和系统的稳定运行,同时提高部署效率和系统安全性。 随着项目的发展和技术的演进,部署流程也需要不断优化和调整,以适应新的业务需求和技术挑战。 --- ### .Codebuddy/Skills/Admin Element/References/Development Flow (.codebuddy/skills/admin-element/references/development_flow.md) # 管理端前端开发流程文档 ## 1. 概述 本文档描述了 CRMEB 项目中管理端前端的开发流程,包括需求分析、设计、编码、测试、部署等环节,旨在规范前端开发流程,提高开发效率和代码质量。 ## 2. 开发流程 ### 2.1 需求分析 #### 2.1.1 需求获取 - **需求来源**: 产品经理、业务方、后端开发、测试人员 - **需求形式**: PRD 文档、需求评审会议、邮件、即时通讯工具 - **需求内容**: 功能需求、非功能需求、UI/UX 需求 #### 2.1.2 需求评审 - **评审人员**: 前端开发、后端开发、产品经理、测试人员 - **评审内容**: 需求可行性、技术实现方案、时间评估、风险评估 - **评审输出**: 评审纪要、任务分解、时间计划 #### 2.1.3 需求确认 - **确认内容**: 需求细节、技术方案、交付标准 - **确认形式**: 需求确认邮件、需求确认会议 - **确认输出**: 需求确认文档 ### 2.2 设计阶段 #### 2.2.1 UI 设计 - **设计工具**: Figma、Sketch、Adobe XD - **设计内容**: 页面布局、组件样式、交互设计、色彩方案 - **设计输出**: UI 设计稿、设计规范文档 #### 2.2.2 技术设计 - **设计内容**: 技术选型、架构设计、目录结构、组件设计、API 设计 - **设计输出**: 技术设计文档、架构图、组件设计图 #### 2.2.3 原型设计 - **原型工具**: Axure、Figma、Sketch - **原型内容**: 页面原型、交互原型、流程原型 - **原型输出**: 交互式原型、流程图 ### 2.3 编码实现 #### 2.3.1 环境搭建 - **开发环境**: Node.js、npm/yarn、VS Code、Git - **依赖安装**: `npm install` 或 `yarn install` - **开发工具**: Vue DevTools、Chrome DevTools #### 2.3.2 代码开发 - **开发顺序**: 基础组件 → 页面组件 → 业务逻辑 → 测试 - **开发规范**: 遵循代码规范、命名规范、文档规范 - **代码质量**: 代码可读性、可维护性、可扩展性 #### 2.3.3 代码审查 - **审查人员**: 前端团队成员 - **审查内容**: 代码质量、功能实现、性能优化、安全防护 - **审查工具**: GitLab/GitHub Code Review、ESLint、Prettier ### 2.4 测试验证 #### 2.4.1 单元测试 - **测试工具**: Jest、Vue Test Utils - **测试内容**: 组件测试、工具函数测试、状态管理测试 - **测试覆盖率**: 关键功能测试覆盖率 ≥ 80% #### 2.4.2 功能测试 - **测试人员**: 前端开发、测试人员 - **测试内容**: 功能实现、交互体验、页面布局、响应式设计 - **测试工具**: 浏览器、测试管理工具 #### 2.4.3 性能测试 - **测试工具**: Chrome DevTools、Lighthouse、WebPageTest - **测试内容**: 首屏加载速度、页面渲染性能、内存使用、网络请求 - **测试指标**: FCP、LCP、TTI、CLS、FID #### 2.4.4 兼容性测试 - **测试浏览器**: Chrome、Firefox、Safari、Edge - **测试分辨率**: 1024x768、1366x768、1920x1080 - **测试内容**: 页面显示、功能实现、交互体验 ### 2.5 部署上线 #### 2.5.1 构建打包 - **构建命令**: `npm run build:prod` - **构建产物**: 静态资源文件 - **构建优化**: 代码压缩、资源压缩、Tree Shaking #### 2.5.2 部署配置 - **部署环境**: 测试环境、预发布环境、生产环境 - **部署工具**: Nginx、Apache、CDN - **配置内容**: 服务器配置、域名配置、HTTPS 配置 #### 2.5.3 上线发布 - **发布流程**: 测试环境 → 预发布环境 → 生产环境 - **发布时间**: 非业务高峰期 - **发布监控**: 实时监控系统运行状态 #### 2.5.4 上线后验证 - **验证内容**: 功能验证、性能验证、兼容性验证 - **验证人员**: 前端开发、测试人员、产品经理 - **验证输出**: 上线验证报告 ## 3. 开发规范 ### 3.1 代码规范 - **ESLint 规则**: 遵循 Vue 官方推荐的 ESLint 规则 - **Prettier 配置**: 统一代码格式化规则 - **代码缩进**: 4 空格缩进 - **命名规范**: 组件名 PascalCase,变量/方法名 camelCase,常量全大写 ### 3.2 提交规范 - **提交信息格式**: `[类型] 描述` - **类型**: feat(新功能)、fix(修复)、docs(文档)、style(样式)、refactor(重构)、test(测试)、chore(构建/依赖) - **提交频率**: 小步提交,每个功能或修复一个提交 - **提交内容**: 只提交相关代码,不提交无关文件 ### 3.3 分支规范 - **主分支**: master(生产环境)、develop(开发环境) - **功能分支**: feature/功能名称 - **修复分支**: fix/修复内容 - **发布分支**: release/版本号 - **分支管理**: 定期清理无用分支 ### 3.4 文档规范 - **README.md**: 项目说明、安装说明、开发说明 - **组件文档**: 组件使用说明、Props、Events、Slots - **API 文档**: API 接口说明、请求参数、响应格式 - **开发文档**: 开发流程、编码规范、部署流程 ## 4. 开发工具 ### 4.1 开发环境 - **Node.js**: v12.0.0+ - **npm**: v6.0.0+ 或 **yarn**: v1.22.0+ - **VS Code**: 最新版本 - **Git**: 最新版本 ### 4.2 编辑器插件 - **Vetur**: Vue 开发插件 - **ESLint**: 代码检查插件 - **Prettier**: 代码格式化插件 - **GitLens**: Git 增强插件 - **Debugger for Chrome**: 浏览器调试插件 - **Auto Close Tag**: 自动闭合标签 - **Auto Rename Tag**: 自动重命名标签 ### 4.3 开发工具 - **Vue DevTools**: Vue 开发调试工具 - **Chrome DevTools**: 浏览器调试工具 - **Postman**: API 测试工具 - **Charles**: 网络调试工具 - **Figma/Sketch**: UI 设计工具 - **Zeplin**: 设计协作工具 ### 4.4 构建工具 - **Webpack**: 模块打包工具 - **Babel**: JavaScript 编译器 - **Sass/Less**: CSS 预处理器 - **ESLint**: 代码检查工具 - **Prettier**: 代码格式化工具 ## 5. 常见问题及解决方案 ### 5.1 需求变更 - **问题**: 开发过程中需求发生变更 - **解决方案**: 1. 记录需求变更内容 2. 评估变更影响范围 3. 与产品经理确认变更可行性 4. 调整开发计划和时间评估 5. 通知相关团队成员 ### 5.2 技术难题 - **问题**: 遇到技术难题无法解决 - **解决方案**: 1. 查阅相关文档和资料 2. 寻求团队成员帮助 3. 咨询外部专家 4. 尝试替代方案 5. 记录解决方案,形成知识库 ### 5.3 时间紧张 - **问题**: 开发时间紧张,任务无法按时完成 - **解决方案**: 1. 评估任务优先级 2. 与产品经理沟通,调整需求优先级 3. 寻求团队成员协助 4. 优化开发流程,提高开发效率 5. 加班完成(作为最后手段) ### 5.4 代码冲突 - **问题**: Git 代码冲突 - **解决方案**: 1. 拉取最新代码 2. 手动解决冲突 3. 测试冲突解决后的代码 4. 提交解决冲突后的代码 5. 通知相关团队成员 ### 5.5 线上问题 - **问题**: 线上出现问题 - **解决方案**: 1. 快速定位问题原因 2. 制定解决方案 3. 紧急修复并部署 4. 验证修复效果 5. 分析问题原因,避免类似问题再次发生 ## 6. 最佳实践 ### 6.1 开发前准备 - **需求确认**: 确保需求理解正确 - **技术方案**: 制定详细的技术实现方案 - **环境搭建**: 确保开发环境配置正确 - **依赖安装**: 安装必要的依赖包 ### 6.2 编码实现 - **组件化开发**: 封装可复用组件 - **模块化开发**: 按功能模块组织代码 - **代码复用**: 提取公共逻辑,避免重复代码 - **性能优化**: 考虑代码性能,避免性能瓶颈 - **安全性**: 考虑代码安全性,避免安全漏洞 ### 6.3 测试验证 - **单元测试**: 编写关键功能的单元测试 - **功能测试**: 全面测试功能实现 - **性能测试**: 测试页面性能 - **兼容性测试**: 测试不同浏览器兼容性 - **用户体验测试**: 测试页面交互体验 ### 6.4 部署上线 - **构建优化**: 优化构建产物 - **部署策略**: 采用灰度发布策略 - **监控告警**: 配置系统监控和告警 - **回滚方案**: 准备系统回滚方案 - **上线验证**: 上线后及时验证系统状态 ### 6.5 维护迭代 - **问题跟踪**: 及时跟踪和解决线上问题 - **代码维护**: 定期维护和优化代码 - **文档更新**: 及时更新相关文档 - **技术债务**: 定期清理技术债务 - **知识共享**: 分享开发经验和解决方案 ## 7. 团队协作 ### 7.1 协作模式 - **敏捷开发**: 采用 Scrum 或 Kanban 敏捷开发模式 - **每日站会**: 每日 15 分钟站会,同步开发进度 - **迭代周期**: 2-4 周一个迭代周期 - **迭代回顾**: 迭代结束后进行回顾,总结经验教训 ### 7.2 沟通工具 - **即时通讯**: 企业微信、钉钉、Slack - **项目管理**: Jira、Trello、GitHub Issues - **代码托管**: GitLab、GitHub、Gitee - **文档协作**: 语雀、Confluence、Google Docs ### 7.3 知识共享 - **技术分享**: 定期组织技术分享会议 - **代码审查**: 相互代码审查,分享编码经验 - **问题讨论**: 定期组织问题讨论会议 - **知识库**: 建立团队知识库,积累技术经验 ## 8. 总结 本文档描述了 CRMEB 项目中管理端前端的开发流程,包括需求分析、设计、编码、测试、部署等环节,以及相关的开发规范和最佳实践。 遵循本文档的开发流程和规范,可以提高前端开发效率和代码质量,减少开发过程中的问题和风险,确保项目的顺利进行。 同时,开发流程也需要根据项目的实际情况进行调整和优化,以适应不同项目的需求和特点。 --- ### .Codebuddy/Skills/Admin Element/References/Directory Structure (.codebuddy/skills/admin-element/references/directory_structure.md) # Admin-Element 目录结构文档 ## 1 项目根目录结构 ``` template/ # 前端项目目录 ├── admin-element/ # 管理端前端项目 │ ├── public/ # 静态资源目录 │ │ ├── favicon.ico # 网站图标 │ │ ├── index.html # 入口HTML文件 │ │ └── static/ # 静态资源文件 │ ├── src/ # 源代码目录 │ │ ├── api/ # API接口定义 │ │ ├── assets/ # 静态资源 │ │ ├── components/ # 通用组件 │ │ ├── config/ # 配置文件 │ │ ├── directive/ # 自定义指令 │ │ ├── filters/ # 过滤器 │ │ ├── layout/ # 布局组件 │ │ ├── router/ # 路由配置 │ │ ├── store/ # 状态管理 │ │ ├── styles/ # 样式文件 │ │ ├── utils/ # 工具函数 │ │ ├── views/ # 页面组件 │ │ ├── App.vue # 根组件 │ │ └── main.js # 入口文件 │ ├── tests/ # 测试文件 │ ├── .env.* # 环境变量配置 │ ├── babel.config.js # Babel配置 │ ├── package.json # 项目依赖 │ ├── vue.config.js # Vue配置 │ └── README.md # 项目说明 ``` ## 2 主要目录说明 ### 2.1 public/ 目录 - **favicon.ico**: 网站图标文件 - **index.html**: 应用入口HTML文件,Vue应用将挂载到这个文件中 - **static/**: 静态资源目录,存放不需要经过webpack处理的静态文件 ### 2.2 src/ 目录 #### 2.2.1 api/ 目录 - 定义所有API接口请求 - 按模块组织API文件 - 包含接口调用方法和参数配置 #### 2.2.2 assets/ 目录 - **images/**: 图片资源 - **icons/**: 图标资源 - **styles/**: 全局样式文件 - 其他静态资源文件 #### 2.2.3 components/ 目录 - **base/**: 基础组件 - **business/**: 业务组件 - **common/**: 通用组件 - 可复用的Vue组件 #### 2.2.4 config/ 目录 - **index.js**: 主配置文件 - **router.config.js**: 路由配置 - **menu.config.js**: 菜单配置 - **theme.config.js**: 主题配置 - 其他系统配置文件 #### 2.2.5 directive/ 目录 - 自定义Vue指令 - 如权限控制、表单验证等指令 #### 2.2.6 filters/ 目录 - 自定义Vue过滤器 - 如日期格式化、数字格式化等 #### 2.2.7 layout/ 目录 - **components/**: 布局组件 - **index.vue**: 主布局文件 - **AppMain.vue**: 内容区域组件 - **Navbar.vue**: 导航栏组件 - **Sidebar.vue**: 侧边栏组件 #### 2.2.8 router/ 目录 - **index.js**: 路由配置主文件 - **modules/**: 按模块组织的路由配置 - 路由守卫配置 #### 2.2.9 store/ 目录 - **index.js**: 状态管理主文件 - **modules/**: 按模块组织的状态管理 - **getters.js**: 全局计算属性 #### 2.2.10 styles/ 目录 - **index.scss**: 全局样式入口 - **variables.scss**: 全局变量 - **mixins.scss**: 混合器 - **reset.scss**: 重置样式 #### 2.2.11 utils/ 目录 - **request.js**: 网络请求封装 - **auth.js**: 认证相关工具 - **tools.js**: 通用工具函数 - **storage.js**: 存储工具 #### 2.2.12 views/ 目录 - 按业务模块组织页面组件 - 每个模块一个目录 - 包含页面组件和相关子组件 #### 2.2.13 App.vue - 应用根组件 - 包含全局布局结构 #### 2.2.14 main.js - 应用入口文件 - 初始化Vue实例 - 加载插件和全局配置 ### 2.3 配置文件 #### 2.3.1 package.json - 项目依赖配置 - 脚本命令配置 - 项目信息配置 #### 2.3.2 vue.config.js - Vue CLI配置 - 构建配置 - 代理配置 #### 2.3.3 babel.config.js - Babel转译配置 #### 2.3.4 .env.* - 环境变量配置文件 - **.env.development**: 开发环境 - **.env.production**: 生产环境 - **.env.staging**: 测试环境 ## 3 目录规范 ### 3.1 命名规范 - 目录名使用小写字母,多单词用连字符(-)分隔 - 文件名使用小写字母,多单词用连字符(-)分隔 - 组件名使用 PascalCase 命名法 ### 3.2 目录组织原则 1. **按功能模块组织**: 相关功能的文件放在同一目录 2. **模块化**: 每个模块保持相对独立 3. **可扩展性**: 目录结构应易于扩展和维护 4. **一致性**: 保持目录结构的一致性 ### 3.3 特殊目录处理 - **components/**: 只存放可复用组件 - **views/**: 存放页面级组件 - **api/**: 按模块组织API接口 - **store/modules/**: 按模块组织状态管理 ## 4 最佳实践 ### 4.1 目录使用建议 - 新增业务模块时,在 views/ 下创建对应的目录 - 新增可复用组件时,放在 components/ 下的对应子目录 - 新增API接口时,在 api/ 下按模块组织 - 新增状态管理时,在 store/modules/ 下创建对应模块 ### 4.2 目录结构维护 - 定期清理无用文件和目录 - 保持目录结构的清晰和整洁 - 遵循统一的命名规范 - 文档及时更新,反映目录结构的变化 ## 5 常见问题 ### 5.1 目录权限问题 - 确保目录权限正确,避免构建时出现权限错误 ### 5.2 路径引用问题 - 使用相对路径或别名路径引用文件 - 避免使用绝对路径 ### 5.3 目录结构优化 - 随着项目规模增大,适时调整目录结构 - 保持目录层级合理,避免过深的嵌套 ## 6 总结 Admin-Element 项目采用标准的 Vue + ElementUI 项目结构,通过清晰的目录组织和命名规范,提高了代码的可维护性和可扩展性。开发者应遵循目录结构规范,合理组织代码,确保项目的长期可维护性。 --- ### .Codebuddy/Skills/Crmeb Agent/SKILL (.codebuddy/skills/crmeb-agent/SKILL.md) --- name: CRMEB电商系统Agent description: 专为CRMEB电商系统设计的智能开发助手,帮助开发者理解架构、快速开发功能、解决问题 --- # CRMEB电商系统Agent ## 0. 自动触发说明 ### 0.1 触发条件 #### 0.1.1 操作触发 - **文件浏览时**: 当浏览CRMEB项目核心目录时自动调用 - 打开 `crmeb/app/` 应用目录时触发 - 打开 `crmeb/crmeb/` 核心库目录时触发 - 打开 `template/` 前端目录时触发 - 浏览配置文件目录时触发 - **文件操作时**: 当对CRMEB项目文件进行操作时自动调用 - 创建控制器、服务、模型时触发 - 修改核心业务代码时触发 - 修改配置文件时触发 - **目录操作时**: 当对项目目录进行操作时自动调用 - 创建新模块目录时触发 - 重命名业务目录时触发 #### 0.1.2 内容触发 - **关键词触发**: 当文件内容包含以下关键词时自动调用 - 电商关键词: `订单`、`商品`、`用户`、`支付`、`购物车` - 营销关键词: `优惠券`、`拼团`、`砍价`、`秒杀`、`积分` - 系统关键词: `CRMEB`、`ThinkPHP`、`后台管理`、`移动端` - **代码触发**: 当查看特定类型代码时自动调用 - 控制器代码 (`Controller`) - 服务层代码 (`Services`) - 模型代码 (`Model`) - 前端Vue组件 (`*.vue`) #### 0.1.3 命令触发 - **终端命令触发**: 当执行以下命令时自动调用 - `php think` (ThinkPHP命令) - `composer install/update` (依赖管理) - `npm run dev/build` (前端构建) - `php think queue:listen` (队列启动) - `php think workerman` (WebSocket启动) ### 0.2 适用场景 #### 0.2.1 核心场景 - **功能开发**: 开发新的电商功能模块时 - **API开发**: 开发前后端接口时 - **数据库设计**: 设计数据表结构时 - **问题排查**: 解决系统运行问题时 #### 0.2.2 辅助场景 - **代码审查**: 审查代码质量时 - **性能优化**: 优化系统性能时 - **安全加固**: 增强系统安全性时 - **部署运维**: 部署和维护系统时 ## 1. CRMEB系统架构 ### 1.1 整体架构 - **框架**: ThinkPHP 6.x (PHP后端) + Vue 2.x (前端) - **架构模式**: 前后端分离 + MVC + Service + DAO分层架构 - **数据库**: MySQL 5.7-8.0 (使用eb_前缀) - **缓存**: Redis (可选,用于缓存和队列) - **消息队列**: ThinkPHP Queue + Workerman - **实时通信**: Workerman WebSocket ### 1.2 技术栈 #### 后端技术栈 ``` - PHP: 7.1-7.4 - ThinkPHP: 6.x - Composer: 依赖管理 - Workerman: 长连接服务 - PHPUnit: 单元测试(可选) ``` #### 前端技术栈 ``` 管理端: - Vue.js 2.x - Element UI 2.15.6 - Vuex 3.0 - Vue Router 3.0 - Axios - ECharts 4.8.0 移动端: - UniApp - uView UI ``` #### 第三方服务 ``` - 支付: 微信支付、支付宝支付 - 存储: 阿里云OSS、腾讯云COS、七牛云 - 短信: 阿里云短信 - 微信: 公众号、小程序 ``` ### 1.3 目录结构 #### 1.3.1 后端目录结构 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` #### 1.3.2 前端目录结构 ``` template/ ├── admin/ # 管理后台 (Vue + ElementUI) │ ├── src/ │ │ ├── api/ # API接口定义 │ │ ├── components/ # 通用组件 │ │ ├── pages/ # 页面组件 │ │ ├── router/ # 路由配置 │ │ ├── store/ # Vuex状态管理 │ │ └── utils/ # 工具函数 │ ├── package.json │ └── vue.config.js └── uni-app/ # 移动端 (UniApp) ├── api/ # API接口 ├── components/ # 组件 ├── pages/ # 页面 ├── manifest.json # 应用配置 └── pages.json # 页面路由配置 ``` ## 2. 核心业务模块 ### 2.1 用户模块 (`app/services/user/`) #### 核心服务 - **UserServices**: 用户主服务,管理用户基础信息 - **LoginServices**: 登录服务,处理多种登录方式 - **UserLevelServices**: 用户等级管理 - **UserMoneyServices**: 用户余额管理 - **UserBillServices**: 账单流水管理 - **UserExtractServices**: 提现管理 - **UserRechargeServices**: 充值管理 - **UserGroupServices**: 用户分组 - **UserLabelServices**: 用户标签 #### 数据表 ```sql eb_user # 用户表 eb_user_bill # 账单表 eb_user_extract # 提现表 eb_user_recharge # 充值表 eb_user_level # 用户等级表 eb_user_group # 用户分组表 eb_user_label # 用户标签表 ``` #### 开发要点 - 用户登录支持多种方式: 账号密码、手机验证码、微信授权 - 用户余额变动必须记录到账单表 - 用户等级可以设置升级条件 - 用户分组和标签用于精准营销 ### 2.2 商品模块 (`app/services/product/`) #### 核心服务 - **StoreProductServices**: 商品主服务 - **StoreCategoryServices**: 商品分类 - **StoreProductAttrServices**: 商品属性 - **StoreProductReplyServices**: 商品评价 - **CopyTaobaoServices**: 淘宝商品采集 #### 数据表 ```sql eb_store_product # 商品表 eb_store_category # 商品分类表 eb_store_product_attr # 商品属性表 eb_store_product_reply # 商品评价表 eb_store_product_description # 商品详情表 ``` #### 开发要点 - 商品支持多规格(SKU),需要处理库存和价格 - 商品可以设置为普通商品、积分商品、预售商品等 - 商品分类支持多级分类 - 商品属性支持自定义规格 ### 2.3 订单模块 (`app/services/order/`) #### 核心服务 - **StoreOrderServices**: 订单主服务 - **StoreOrderCreateServices**: 订单创建 - **StoreOrderDeliveryServices**: 订单发货 - **StoreOrderRefundServices**: 订单退款 - **StoreCartServices**: 购物车 - **OtherOrderServices**: 其他订单(积分订单等) - **OutStoreOrderServices**: 外部订单 #### 数据表 ```sql eb_store_order # 订单表 eb_store_order_cart # 订单商品表 eb_store_order_status # 订单状态变更记录 eb_store_refund # 退款表 eb_store_cart # 购物车表 ``` #### 开发要点 - 订单状态流转: 未支付 → 待发货 → 待收货 → 已完成 (或取消/退款) - 订单创建时需要扣减库存 - 支付成功后触发后续流程(发货通知、积分增加等) - 订单退款需要恢复库存 - 订单相关操作建议使用队列异步处理 #### 订单状态流转图 ``` 未支付 (status=0) ↓ 支付成功 待发货 (status=1) ↓ 发货 待收货 (status=2) ↓ 确认收货 已完成 (status=3) 分支流程: - 未支付 → 已取消 (status=-1) - 待发货 → 申请退款 → 退款中 (status=-2) → 已退款 (status=-3) - 待收货 → 申请退款 → 退款中 (status=-2) → 已退款 (status=-3) ``` ### 2.4 支付模块 (`app/services/pay/`) #### 核心服务 - **PayServices**: 支付服务 - **WechatPayServices**: 微信支付 - **AlipayServices**: 支付宝支付 #### 数据表 ```sql eb_pay # 支付记录表 ``` #### 开发要点 - 支付方式: 微信支付(公众号/小程序/H5)、支付宝支付、余额支付 - 支付流程: 创建订单 → 调起支付 → 支付回调 → 更新订单状态 - 支付回调需要验证签名防止伪造 - 支付成功后触发事件,可以扩展后续业务逻辑 ### 2.5 营销模块 (`app/services/activity/`) #### 核心服务 - **拼团**: StoreCombinationServices, StorePinkServices - **砍价**: StoreBargainServices - **秒杀**: StoreSeckillServices - **优惠券**: StoreCouponService, StoreCouponUserServices - **积分**: StoreIntegralServices - **直播**: LiveRoomServices, LiveGoodsServices - **抽奖**: LuckLotteryServices #### 数据表 ```sql eb_store_combination # 拼团商品表 eb_store_pink # 拼团记录表 eb_store_bargain # 砍价商品表 eb_store_bargain_user # 砍价记录表 eb_store_seckill # 秒杀商品表 eb_store_coupon # 优惠券表 eb_store_coupon_user # 用户优惠券表 eb_integral_product # 积分商品表 ``` #### 开发要点 - 营销活动都需要设置时间范围 - 优惠券可以设置使用条件和适用商品 - 拼团需要处理拼团成功/失败的逻辑 - 砍价需要处理砍价进度和完成时间 - 秒杀商品需要限制库存和购买数量 ### 2.6 分销模块 (`app/services/agent/`) #### 核心服务 - **AgentLevelServices**: 分销等级管理 - **AgentLevelTaskServices**: 分销任务系统 - **DivisionServices**: 事业部/代理管理 - **SpreadApplyServices**: 分销申请 #### 数据表 ```sql eb_agent_level # 分销等级表 eb_agent_level_task # 分销任务表 eb_division # 事业部表 eb_spread_apply # 分销申请表 ``` #### 开发要点 - 分销系统支持多级分销 - 分销员等级通过完成任务自动升级 - 分销佣金结算需要计算各级佣金 - 分销申请需要管理员审核 ### 2.7 系统管理模块 (`app/services/system/`) #### 核心服务 - **SystemCrudServices**: CRUD代码生成器 - **SystemConfigServices**: 系统配置 - **SystemEventServices**: 系统事件管理 - **SystemCrontabServices**: 定时任务管理 - **SystemMenusServices**: 菜单管理 - **SystemAdminServices**: 管理员管理 - **SystemLogServices**: 操作日志 - **SystemFileServices**: 文件管理 - **SystemUpgradeServices**: 系统升级 #### 开发要点 - **代码生成器**: 可以快速生成Controller、Service、DAO、Model、Validate - **系统配置**: 支持后台动态配置,存储在数据库中 - **事件系统**: 定义了30+系统事件锚点,可以扩展业务逻辑 - **定时任务**: 基于Workerman,支持Cron表达式 - **权限管理**: 基于RBAC模型,可以控制到菜单和按钮级别 ## 3. 开发规范 ### 3.1 命名规范 #### 类命名 - **控制器**: 模块名 + Controller,如 `UserController` - **服务**: 模块名 + Services,如 `UserServices` - **DAO**: 模块名 + Dao,如 `UserDao` - **模型**: 模块名,如 `User` - **验证器**: 模块名 + Validate,如 `UserValidate` #### 方法命名 - **控制器方法**: 小写+下划线,如 `get_list`, `save_data` - **服务方法**: 驼峰法,如 `getUserList`, `saveData` - **DAO方法**: 数据库操作相关,如 `selectList`, `insert`, `update`, `delete` #### 变量命名 - **普通变量**: 驼峰法,如 `$userName`, `$orderId` - **数组变量**: 复数形式,如 `$users`, `$products` - **布尔变量**: is/has/can开头,如 `$isPaid`, `$hasStock` ### 3.2 代码规范 #### 控制器层 ```php services = $services; } /** * 获取管理员列表 * @return mixed */ public function get_list() { $where = $this->request->getMore([ ['keywords', ''], ['status', ''] ]); $list = $this->services->getAdminList($where); return app('json')->success($list); } /** * 保存管理员 * @return mixed */ public function save() { $data = $this->request->postMore([ ['account', ''], ['real_name', ''], ['pwd', ''], ['roles', []], ['status', 1] ]); $this->services->saveAdmin($data); return app('json')->success('保存成功'); } } ``` #### 服务层 ```php dao->search($where); // 获取列表 $list = $query->select()->toArray(); // 处理数据 foreach ($list as &$item) { $item['role_names'] = $this->getRoleNames($item['roles']); } return $list; } /** * 保存管理员 * @param array $data * @return int */ public function saveAdmin(array $data): int { // 验证数据 if (empty($data['account'])) { throw new AdminException('账号不能为空'); } // 密码加密 if (!empty($data['pwd'])) { $data['pwd'] = password_hash($data['pwd'], PASSWORD_DEFAULT); } else { unset($data['pwd']); } // 保存数据 if (isset($data['id']) && $data['id']) { // 更新 $id = $data['id']; unset($data['id']); $this->dao->update($id, $data); } else { // 新增 $id = $this->dao->save($data); } return $id; } } ``` #### DAO层 ```php getModel() ->where('is_del', 0); // 账号搜索 if (!empty($where['keywords'])) { $query = $query->whereLike('account|real_name', "%{$where['keywords']}%"); } // 状态筛选 if ($where['status'] !== '') { $query = $query->where('status', $where['status']); } return $query; } } ``` #### 模型层 ```php belongsToMany(SystemRole::class, 'system_admin_role', 'role_id', 'admin_id'); } /** * 密码修改器 * @param $value * @return string */ public function setPwdAttr($value) { return password_hash($value, PASSWORD_DEFAULT); } /** * 状态获取器 * @param $value * @return string */ public function getStatusTextAttr($value, $data) { $status = [ 0 => '禁用', 1 => '启用' ]; return $status[$data['status']] ?? ''; } } ``` ### 3.3 数据库规范 #### 表命名 - 使用小写字母和下划线 - 统一使用 `eb_` 前缀 - 表名使用复数形式或明确含义 #### 字段命名 - 使用小写字母和下划线 - 字段名不以下划线开头 - 主键统一命名为 `id` - 外键命名为 `表名_id`,如 `user_id` - 时间字段命名为 `create_time`, `update_time` - 状态字段命名为 `status`,默认值0 - 删除标记命名为 `is_del`,0未删除1已删除 #### 字段类型 - 整型: 使用 `int`,如 `tinyint`, `smallint`, `int`, `bigint` - 字符串: 使用 `varchar`,如 `varchar(255)` - 文本: 使用 `text` - 金额: 使用 `decimal(10,2)` - 时间: 使用 `int`(时间戳)或 `datetime` ### 3.4 API规范 #### 请求方式 - **GET**: 查询数据 - **POST**: 创建数据 - **PUT**: 更新数据 - **DELETE**: 删除数据 #### 响应格式 ```json { "code": 200, "msg": "操作成功", "data": {} } ``` #### 错误响应 ```json { "code": 400, "msg": "错误信息", "data": null } ``` #### 分页响应 ```json { "code": 200, "msg": "操作成功", "data": { "list": [], "count": 100, "page": 1, "limit": 10 } } ``` ## 4. 自动化功能 ### 4.1 代码生成器 #### 使用方式 1. 在后台管理中进入"系统管理" > "代码生成" 2. 选择数据表 3. 配置生成参数(字段类型、搜索类型、表单类型等) 4. 生成代码 #### 支持的表单类型 - **input**: 普通输入框 - **textarea**: 文本域 - **select**: 下拉选择 - **radio**: 单选框 - **checkbox**: 复选框 - **date**: 日期选择 - **datetime**: 日期时间选择 - **image**: 图片上传 - **file**: 文件上传 - **editor**: 富文本编辑器 - **number**: 数字输入 - **switch**: 开关 - 等等 #### 支持的搜索类型 - **普通搜索**: 普通文本搜索 - **日期范围**: 日期区间搜索 - **时间范围**: 时间区间搜索 - **下拉选择**: 下拉筛选 ### 4.2 定时任务 #### 启动命令 ```bash # 启动定时任务(守护进程) php think timer start --d # 停止定时任务 php think timer stop # 重启定时任务 php think timer restart # 查看定时任务状态 php think timer status ``` #### 系统预置定时任务 1. 自动取消未支付订单 2. 自动确认收货 3. 自动评价 4. 自动关闭拼团 5. 自动关闭砍价 6. 积分到期处理 7. 优惠券过期处理 8. 分销佣金结算 9. 统计数据汇总 10. 系统日志清理 ### 4.3 队列任务 #### 启动命令 ```bash # 启动队列消费者 php think queue:listen --queue # 或者使用Workerman php think queue:work --queue ``` #### 主要队列任务 - **OrderJob**: 订单相关任务(创建、支付、发货等) - **PinkJob**: 拼团任务 - **BargainJob**: 砍价任务 - **SeckillJob**: 秒杀任务 - **AutoCommentJob**: 自动评价 - **PosterJob**: 海报生成 - **AgentJob**: 分销等级升级检测 - **UnpaidOrderCancelJob**: 未支付订单取消 - 等等 ### 4.4 事件系统 #### 系统事件锚点 **用户事件**: - 用户注册 (user.register) - 用户登录 (user.login) - 用户注销 (user.logout) - 用户修改信息 (user.update) - 用户绑定推广 (user.bind_spread) - 用户签到 (user.sign) - 用户充值 (user.recharge) **订单事件**: - 订单创建 (order.create) - 订单支付成功 (order.pay_success) - 订单发货 (order.delivery) - 订单收货 (order.confirm) - 订单取消 (order.cancel) - 订单退款 (order.refund) **商品事件**: - 商品上架 (product.on_shelf) - 商品下架 (product.off_shelf) - 商品评价 (product.comment) **支付事件**: - 支付成功 (pay.success) - 支付失败 (pay.fail) **营销事件**: - 领取优惠券 (coupon.receive) - 参与拼团 (combination.join) - 参与砍价 (bargain.join) #### 事件监听器开发 ```php [ 'protocol' => 'websocket', 'port' => 40001, 'ip' => '0.0.0.0', ], // 客服消息 'chat' => [ 'protocol' => 'websocket', 'port' => 40002, 'ip' => '0.0.0.0', ], // 内部通讯 'channel' => [ 'port' => 40003, 'ip' => '127.0.0.1', ], ]; ``` #### 使用场景 - 新订单实时通知 - 客服在线聊天 - 系统消息推送 - 实时数据统计 ## 5. 常见开发场景 ### 5.1 创建新功能模块 #### 步骤1: 创建数据表 ```sql CREATE TABLE `eb_example` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL DEFAULT '' COMMENT '名称', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 0禁用 1启用', `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间', `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='示例表'; ``` #### 步骤2: 创建模型 ```bash # 使用命令行生成模型 php think make:model Example ``` #### 步骤3: 创建DAO ```php dao = $dao; } public function getList(array $where): array { return $this->dao->getList($where); } public function save(array $data): int { return $this->dao->save($data); } } ``` #### 步骤5: 创建控制器 ```php services = $services; } public function get_list() { $where = $this->request->getMore([ ['name', ''], ['status', ''] ]); $list = $this->services->getList($where); return app('json')->success($list); } public function save() { $data = $this->request->postMore([ ['name', ''], ['status', 1] ]); $this->services->save($data); return app('json')->success('保存成功'); } } ``` #### 步骤6: 创建路由 ```php // route/app.php 或 route/adminapi.php use think\facade\Route; Route::group('example', function () { Route::get('list', 'Example/get_list'); Route::post('save', 'Example/save'); }); ``` #### 步骤7: 使用代码生成器(可选) 直接在后台管理系统配置代码生成,自动生成前后端代码 ### 5.2 开发订单功能 #### 订单创建流程 1. 校验商品库存和状态 2. 计算订单金额 3. 创建订单记录 4. 创建订单商品记录 5. 扣减商品库存 6. 清空购物车 7. 触发订单创建事件 #### 订单支付流程 1. 调起支付(微信/支付宝/余额) 2. 接收支付回调 3. 验证签名 4. 更新订单状态为"待发货" 5. 扣减优惠券 6. 增加用户积分 7. 触发支付成功事件(分销、通知等) #### 订单发货流程 1. 获取订单信息 2. 填写物流信息 3. 更新订单状态为"待收货" 4. 发送发货通知 5. 触发发货事件 #### 订单收货流程 1. 用户确认收货或系统自动收货(7天未收货) 2. 更新订单状态为"已完成" 3. 结算分销佣金 4. 增加用户积分 5. 触发收货事件 ### 5.3 开发营销活动 #### 优惠券功能开发要点 1. 创建优惠券模板(面额、门槛、使用条件等) 2. 用户领取优惠券 3. 下单时选择优惠券 4. 计算优惠金额 5. 支付后核销优惠券 6. 过期自动失效 #### 拼团功能开发要点 1. 创建拼团商品(拼团价、成团人数、拼团时长) 2. 用户发起拼团 3. 其他人参与拼团 4. 拼团成功/失败判断 5. 成团后按拼团价计算订单 6. 失败后退款 #### 秒杀功能开发要点 1. 创建秒杀活动(时间、商品、库存、限购) 2. 用户参与秒杀 3. 检查库存和限购 4. 创建秒杀订单 5. 未支付订单自动取消 6. 活动结束后更新库存 ### 5.4 开发分销功能 #### 分销流程 1. 用户申请成为分销员 2. 管理员审核通过 3. 分销员分享推广链接 4. 新用户通过链接注册成为下级 5. 下级用户下单 6. 系统计算分销佣金 7. 佣金结算到分销员余额 #### 分销等级升级 1. 创建分销等级(等级名称、佣金比例) 2. 设置升级任务(订单数、金额等) 3. 定时任务检测分销员任务完成情况 4. 达到条件自动升级 ## 6. 问题排查指南 ### 6.1 常见错误 #### 数据库连接错误 ```php // 错误信息 SQLSTATE[HY000] [2002] Connection refused // 排查步骤 1. 检查数据库服务是否启动 2. 检查 .env 配置文件中的数据库配置 3. 检查数据库用户权限 4. 检查防火墙设置 ``` #### 队列任务不执行 ```php // 排查步骤 1. 检查队列消费者是否启动: php think queue:work 2. 检查队列配置: config/queue.php 3. 检查Redis连接: redis-cli ping 4. 查看队列日志: runtime/log/ ``` #### 定时任务不执行 ```bash # 排查步骤 1. 检查定时任务是否启动: php think timer status 2. 检查定时任务配置 3. 检查Cron表达式是否正确 4. 查看定时任务日志 ``` #### WebSocket连接失败 ```bash # 排查步骤 1. 检查WebSocket服务是否启动: php think workerman status 2. 检查端口是否被占用: netstat -tlnp | grep 40001 3. 检查防火墙设置 4. 检查客户端连接地址是否正确 ``` ### 6.2 性能优化 #### 数据库优化 - 为常用查询字段添加索引 - 避免使用 `SELECT *`,只查询需要的字段 - 使用 `EXPLAIN` 分析SQL执行计划 - 合理使用缓存减少数据库查询 #### 缓存优化 - 使用Redis缓存热点数据 - 设置合理的缓存过期时间 - 使用缓存前缀防止冲突 #### 代码优化 - 减少循环嵌套 - 优化算法复杂度 - 使用队列处理耗时操作 - 异步处理非关键业务 ### 6.3 安全加固 #### SQL注入防护 - 使用参数绑定,不要直接拼接SQL - 使用ThinkPHP的查询构造器 - 对用户输入进行验证 #### XSS防护 - 对用户输入进行过滤 - 输出时进行HTML转义 - 使用CSP(内容安全策略) #### CSRF防护 - 使用CSRF Token - 验证请求来源 - 重要操作二次确认 #### 权限控制 - 严格的权限验证 - 基于RBAC的权限模型 - 敏感操作记录日志 ## 7. 部署与运维 ### 7.1 环境要求 - PHP >= 7.1 - MySQL >= 5.7 - Redis >= 5.0 (可选) - Nginx/Apache - Composer ### 7.2 部署步骤 #### 1. 安装依赖 ```bash composer install ``` #### 2. 配置环境 ```bash cp .env.example .env # 修改 .env 文件中的配置 ``` #### 3. 数据库初始化 ```bash # 导入数据库 mysql -u root -p crmeb < database.sql ``` #### 4. 设置目录权限 ```bash chmod -R 755 runtime chmod -R 755 public/uploads ``` #### 5. 启动服务 ```bash # 启动队列 php think queue:listen --queue # 启动定时任务 php think timer start --d # 启动WebSocket php think workerman start --d ``` #### 6. 前端构建 ```bash cd template/admin npm install npm run build ``` ### 7.3 Docker部署 #### 使用docker-compose ```bash cd docker-compose docker-compose up -d ``` ### 7.4 监控与日志 #### 日志位置 - 应用日志: `runtime/log/` - 错误日志: `runtime/log/error/` - SQL日志: 开启数据库SQL日志记录 #### 监控指标 - 服务器资源: CPU、内存、磁盘 - 应用性能: 响应时间、吞吐量 - 数据库: 慢查询、连接数 - 队列: 队列长度、处理速度 ## 8. 参考资源 ### 8.1 官方文档 - [ThinkPHP 6 官方文档](https://www.kancloud.cn/manual/thinkphp6_0) - [Vue 2 官方文档](https://v2.vuejs.org/) - [Element UI 官方文档](https://element.eleme.io/) - [UniApp 官方文档](https://uniapp.dcloud.net.cn/) ### 8.2 项目文档 - `/dev-docs/AI代码理解指南.md` - 代码理解指南 - `/dev-docs/错误码说明文档.md` - 错误码说明 - `.codebuddy/skills/php-api/SKILL.md` - 后端开发规范 - `.codebuddy/skills/admin-element/SKILL.md` - 前端开发规范 ### 8.3 工具推荐 - **IDE**: PhpStorm / VS Code - **API测试**: Postman / Apifox - **数据库**: Navicat / phpMyAdmin - **Redis**: Redis Desktop Manager ## 9. 常用命令速查 ### 9.1 ThinkPHP命令 ```bash php think # 查看所有命令 php think make:controller # 创建控制器 php think make:model # 创建模型 php think make:middleware # 创建中间件 php think make:validate # 创建验证器 php think clear # 清除缓存 php think run # 启动内置服务器 ``` ### 9.2 队列命令 ```bash php think queue:listen # 监听队列 php think queue:work # 处理队列任务 php think queue:restart # 重启队列 php think queue:fail # 查看失败任务 php think queue:retry # 重试失败任务 ``` ### 9.3 定时任务命令 ```bash php think timer start # 启动定时任务 php think timer stop # 停止定时任务 php think timer restart # 重启定时任务 php think timer status # 查看状态 ``` ### 9.4 Workerman命令 ```bash php think workerman start # 启动 php think workerman stop # 停止 php think workerman restart # 重启 php think workerman reload # 平滑重启 php think workerman status # 查看状态 ``` --- > **提示**: 本Agent专为CRMEB电商系统设计,帮助您快速开发和理解系统。如有疑问,请参考官方文档或查看项目源码。 --- ### .Codebuddy/Skills/Php Api/References/Api Flow (.codebuddy/skills/php-api/references/api_flow.md) # 接口请求文档 ## 1. 概述 本文档描述了 CRMEB 项目中 API 接口请求的流程、规范、参数设计和响应格式等,旨在统一 API 请求格式,提高 API 的一致性和可维护性。 ## 2. 接口请求流程 ### 2.1 基本流程 1. **客户端发起请求**: 客户端通过 HTTP/HTTPS 协议向服务器发送请求 2. **请求到达服务器**: 请求经过网络传输到达服务器 3. **请求解析**: 服务器解析请求,包括请求方法、路径、参数等 4. **认证授权**: 服务器对请求进行认证和授权 5. **业务处理**: 服务器执行相应的业务逻辑 6. **生成响应**: 服务器生成响应数据 7. **返回响应**: 服务器将响应返回给客户端 8. **客户端处理响应**: 客户端处理服务器返回的响应 ### 2.2 详细流程 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 客户端 │ │ 中间件 │ │ 控制器 │ │ 1. 发起请求 │────▶│ 2. 认证授权 │────▶│ 3. 业务处理 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ 服务层 │ │ 4. 执行逻辑 │ └─────────────────┘ │ ▼ ┌─────────────────┐ │ 数据层 │ │ 5. 数据操作 │ └─────────────────┘ │ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 客户端 │ │ 中间件 │ │ 控制器 │ │ 8. 处理响应 │◀────│ 7. 响应处理 │◀────│ 6. 生成响应 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ ``` ## 3. 请求方法 ### 3.1 HTTP 方法 | 方法 | 描述 | 幂等性 | 安全性 | |------|------|--------|--------| | GET | 获取资源 | 是 | 是 | | POST | 创建资源 | 否 | 否 | | PUT | 更新资源 | 是 | 否 | | DELETE | 删除资源 | 是 | 否 | | PATCH | 部分更新资源 | 否 | 否 | | OPTIONS | 获取资源的可用操作 | 是 | 是 | | HEAD | 获取资源的元数据 | 是 | 是 | ### 3.2 方法使用规范 - **GET**: 用于获取资源,不应修改资源状态 - **POST**: 用于创建新资源 - **PUT**: 用于更新整个资源,应包含资源的完整表示 - **DELETE**: 用于删除资源 - **PATCH**: 用于部分更新资源,只包含需要更新的字段 - **OPTIONS**: 用于获取资源支持的 HTTP 方法 - **HEAD**: 用于获取资源的元数据,如 Content-Length、Last-Modified 等 ## 4. 请求头 ### 4.1 通用请求头 | 请求头 | 描述 | 示例 | |-------|------|------| | Accept | 客户端可接受的响应内容类型 | application/json | | Accept-Encoding | 客户端可接受的编码方式 | gzip, deflate | | Content-Type | 请求体的内容类型 | application/json | | Authorization | 认证信息 | Bearer {token} | | User-Agent | 客户端标识 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 | | X-Requested-With | 请求类型 | XMLHttpRequest | | X-Token | 认证令牌(自定义) | your_token_here | ### 4.2 自定义请求头 自定义请求头应以 `X-` 为前缀,如 `X-Token`、`X-Request-ID` 等。 ## 5. 请求参数 ### 5.1 参数位置 | 位置 | 适用场景 | 示例 | |------|----------|------| | URL 路径 | 资源标识 | /api/v1/user/1 | | 查询字符串 | 过滤、排序、分页 | /api/v1/user?page=1&limit=10&sort=create_time&order=desc | | 请求体 | 复杂数据、创建/更新资源 | {"username": "test", "password": "123456"} | | 请求头 | 认证信息、元数据 | Authorization: Bearer {token} | | Cookie | 会话信息 | PHPSESSID=your_session_id | ### 5.2 参数命名规范 - **命名风格**: 使用 camelCase 命名风格,如 `userName` - **语义化**: 参数名应具有明确的语义,如 `page`、`limit`、`sort` - **简洁性**: 参数名应简洁明了,避免过长 - **一致性**: 相同类型的参数在不同接口中应保持一致 ### 5.3 常用参数 | 参数名 | 类型 | 描述 | 示例 | |-------|------|------|------| | page | int | 页码,默认 1 | page=1 | | limit | int | 每页数量,默认 10 | limit=20 | | sort | string | 排序字段 | sort=create_time | | order | string | 排序方式,asc 或 desc | order=desc | | keyword | string | 搜索关键词 | keyword=test | | status | int | 状态过滤 | status=1 | | start_time | string | 开始时间 | start_time=2024-01-01 | | end_time | string | 结束时间 | end_time=2024-01-31 | ## 6. 请求体 ### 6.1 内容类型 | 内容类型 | 描述 | 示例 | |---------|------|------| | application/json | JSON 格式,最常用 | {"username": "test", "password": "123456"} | | application/x-www-form-urlencoded | 表单格式 | username=test&password=123456 | | multipart/form-data | 文件上传 | 包含文件和表单字段 | | text/plain | 纯文本 | 简单的文本数据 | | application/xml | XML 格式 | test123456 | ### 6.2 JSON 请求体规范 - **使用 camelCase 命名**: 字段名使用 camelCase 命名风格 - **明确的数据类型**: 使用适当的数据类型,如字符串、数字、布尔值、数组、对象 - **避免 null 值**: 非必要字段不应包含 null 值 - **嵌套结构**: 合理使用嵌套结构,避免过深的嵌套 - **数组格式**: 数组元素类型应一致 示例: ```json { "username": "test", "password": "123456", "nickname": "测试用户", "age": 18, "gender": 1, "tags": ["tag1", "tag2"], "address": { "province": "北京", "city": "北京", "district": "朝阳区" } } ``` ## 7. 响应格式 ### 7.1 基本响应格式 所有 API 响应应使用统一的 JSON 格式,包含 `status`、`msg` 和可选的 `data` 字段。系统实际调用方式为 `app('json')->success()`。 #### 7.1.1 调用示例 ```php // 基本成功响应 return app('json')->success('操作成功', ['id' => 1, 'username' => 'test']); // 只返回数据,不指定消息 return app('json')->success(['id' => 1, 'username' => 'test']); // 使用系统内置成功码 return app('json')->success(100000); // 100000 是 "保存成功" 对应的系统内置成功码 ``` #### 7.1.2 响应格式 ```json { "status": 200, "msg": "操作成功", "data": { "id": 1, "username": "test", "nickname": "测试用户" } } ``` ### 7.2 分页响应格式 分页响应应包含 `total`、`page`、`limit` 和 `list` 字段,系统实际调用方式为 `app('json')->success()`。 #### 7.2.1 调用示例 ```php // 分页数据响应 $pageData = [ 'total' => 100, 'page' => 1, 'limit' => 10, 'list' => [ ['id' => 1, 'username' => 'test1', 'nickname' => '测试用户1'], ['id' => 2, 'username' => 'test2', 'nickname' => '测试用户2'] ] ]; return app('json')->success('获取列表成功', $pageData); ``` #### 7.2.2 响应格式 ```json { "status": 200, "msg": "获取列表成功", "data": { "total": 100, "page": 1, "limit": 10, "list": [ { "id": 1, "username": "test1", "nickname": "测试用户1" }, { "id": 2, "username": "test2", "nickname": "测试用户2" } ] } } ``` ### 7.3 错误响应格式 系统使用统一的错误响应格式,所有错误响应通过 `app('json')->fail()` 方法返回。`fail()` 方法支持两种参数类型: - **错误码**(推荐):系统内置的数字错误码,如 `410025` - **错误消息**:直接的字符串错误信息 #### 7.3.1 统一响应格式 无论使用哪种参数类型,系统都会返回统一的 JSON 格式,包含 `status`、`msg` 和可选的 `data` 字段。当使用错误码时,响应中还会包含 `code` 字段。 ```json { "status": 400, "msg": "账号或密码错误", "code": 410025, "data": null } ``` #### 7.3.2 调用示例 ```php // 推荐:使用系统内置错误码 return app('json')->fail(410025); // 不推荐:直接使用错误消息 return app('json')->fail('账号或密码错误'); // 使用错误码并传递额外数据 return app('json')->fail(410025, ['extra' => 'additional data']); // 使用错误码并传递替换参数 return app('json')->fail(410025, [], ['field' => 'username']); ``` #### 7.3.3 最佳实践 - **优先使用错误码**:系统内置错误码经过统一规划,便于维护和国际化 - **避免直接使用字符串**:直接使用字符串错误信息不利于国际化和统一管理 - **传递必要的额外数据**:对于复杂错误,可以在 `data` 字段中提供详细信息 - **使用替换参数**:对于动态错误信息,使用替换参数提高灵活性 ### 7.4 响应码规范 | 响应码范围 | 类型 | 描述 | 示例 | |-----------|------|------|------| | 200 | 成功 | 操作成功 | 200 | | 1000-1999 | 系统级错误 | 系统核心错误 | 1001(参数错误) | | 4000-4999 | 业务级错误 | 具体业务逻辑错误 | 410025(账号或密码错误) | | 400 | 客户端错误 | 请求参数错误 | 400 | | 401 | 认证错误 | 未认证或认证过期 | 401 | | 403 | 权限错误 | 无权限访问 | 403 | | 404 | 资源错误 | 资源不存在 | 404 | | 500 | 服务器错误 | 服务器内部错误 | 500 | ## 8. 错误处理 ### 8.1 错误响应设计 错误响应应遵循以下设计原则: 1. **统一格式**: 所有错误响应使用相同的 JSON 格式 2. **明确的错误码**: 使用唯一的错误码标识不同的错误类型 3. **清晰的错误信息**: 错误信息应简洁明了,便于理解 4. **可选的详细信息**: 对于复杂错误,可以在 `data` 字段中提供详细信息 5. **HTTP 状态码匹配**: 错误码应与 HTTP 状态码匹配 ### 8.2 AI 自动提示系统内置错误码 CRMEB 系统集成了 AI 自动提示功能,当开发者在编写代码时使用 `fail()` 方法返回错误信息时,AI 会自动: 1. **识别错误信息**: 自动识别开发者输入的错误信息字符串 2. **匹配内置错误码**: 在系统内置错误码库中查找匹配的错误码 3. **自动转换**: 在运行时将错误信息自动转换为对应的系统内置错误码 4. **提供建议**: 对于未匹配到的错误信息,提供相似的错误码建议 5. **实时提示**: 在 IDE 中实时显示错误码建议 6. **错误码文档**: 在错误码文档 error_code.md,找到对应的错误码说明 #### 8.2.1 功能示例 ```php // 开发者输入 return $this->fail('登录失败'); // AI 自动提示并替换为 return $this->fail(410019); // 410019 是 "登录失败" 对应的系统内置错误码 ``` #### 8.2.2 工作原理 1. **语言文件解析**: 系统在运行时解析语言文件,构建错误码到错误信息的映射表 2. **自动匹配**: 当调用 `fail()` 方法传入字符串错误信息时,系统自动在映射表中查找匹配的错误码 3. **运行时转换**: 如果找到匹配的错误码,系统会将错误信息替换为错误码,并在响应中包含 `code` 字段 4. **智能提示**: 在 IDE 中,AI 会实时提示开发者使用正确的系统内置错误码 #### 8.2.3 实际响应格式 当使用字符串错误信息时,系统会自动匹配并转换为错误码,最终响应格式为: ```json { "status": 400, "msg": "登录失败", "code": 410019 } ``` 当直接使用错误码时,响应格式为: ```json { "status": 400, "msg": "登录失败", "code": 410019 } ``` ### 8.3 错误处理最佳实践 1. **使用系统内置错误码**: 优先使用系统内置错误码,避免自定义错误信息 2. **错误信息本地化**: 使用 `getLang()` 函数获取本地化的错误信息 3. **详细的错误日志**: 记录详细的错误日志,包括错误码、错误信息、请求参数等 4. **友好的错误提示**: 对客户端返回友好的错误信息,避免暴露系统内部细节 5. **统一的错误处理**: 使用统一的错误处理中间件处理所有错误 6. **错误码文档化**: 定期更新错误码文档,确保与实际代码一致 ### 8.4 自定义错误码 对于系统内置错误码无法覆盖的业务场景,可以自定义错误码,但应遵循以下规范: 1. **错误码范围**: 使用系统未占用的错误码范围 2. **命名规范**: 错误码应具有明确的语义 3. **文档化**: 自定义错误码应在文档中明确说明 4. **本地化**: 自定义错误码应在语言文件中定义对应的错误信息 ## 9. 接口开发流程 ### 9.1 需求分析与设计 1. **需求理解**: 明确接口的业务需求和功能要求 2. **资源设计**: 确定接口涉及的资源和数据模型 3. **接口设计**: 设计接口的 URL、请求方法、参数和响应格式 4. **权限设计**: 确定接口的访问权限和认证方式 5. **错误设计**: 定义接口可能出现的错误情况和错误码 ### 9.2 开发实现 1. **创建路由**: 在路由文件中定义接口路由 2. **实现控制器**: 创建控制器并实现接口逻辑 3. **参数验证**: 使用验证器对请求参数进行验证 4. **业务逻辑**: 实现接口的业务逻辑 5. **错误处理**: 使用 `app('json')->fail()` 统一处理错误 6. **响应返回**: 使用 `app('json')->success()` 统一返回响应 ### 9.3 测试验证 1. **单元测试**: 编写单元测试验证接口功能 2. **集成测试**: 测试接口与其他模块的集成 3. **接口测试**: 使用 Postman 或其他工具测试接口 4. **性能测试**: 测试接口的性能和响应时间 5. **安全测试**: 测试接口的安全性 ### 9.4 文档编写 1. **接口文档**: 编写接口的详细文档 2. **错误码文档**: 在 `error_code.md` 中记录接口使用的错误码 3. **变更记录**: 记录接口的变更历史 ### 9.5 上线发布 1. **代码审查**: 进行代码审查,确保代码质量 2. **测试环境验证**: 在测试环境验证接口功能 3. **灰度发布**: 灰度发布接口,观察运行情况 4. **正式上线**: 正式上线接口 ### 9.6 监控维护 1. **监控**: 监控接口的运行状态和性能 2. **日志**: 记录接口的访问日志和错误日志 3. **优化**: 根据监控数据优化接口性能 4. **维护**: 定期维护和更新接口 ## 10. 最佳实践 ### 10.1 请求设计 - **使用 RESTful 风格**: 遵循 RESTful API 设计规范 - **明确的资源命名**: 使用明确的资源名称,如 `/api/v1/user` 而不是 `/api/v1/getUser` - **合理的 URL 层级**: URL 层级不应过深,一般不超过 3 层 - **使用复数形式**: 资源名称使用复数形式,如 `/api/v1/users` 而不是 `/api/v1/user` ### 10.2 参数设计 - **必填参数**: 明确标识必填参数 - **默认值**: 为可选参数提供合理的默认值 - **参数验证**: 对所有参数进行验证 - **参数类型**: 明确参数类型和格式 ### 10.3 响应设计 - **统一格式**: 使用统一的响应格式 - **明确的数据类型**: 响应数据类型应明确 - **避免冗余数据**: 只返回必要的数据 - **分页响应**: 列表接口应支持分页 - **错误信息**: 错误信息应清晰、准确 ### 10.4 安全设计 - **认证授权**: 使用 JWT 或 OAuth2 进行认证授权 - **HTTPS**: 使用 HTTPS 加密传输 - **参数验证**: 严格验证所有输入参数 - **输出编码**: 对输出数据进行编码,防止 XSS 攻击 - **SQL 注入防护**: 使用参数绑定,避免直接拼接 SQL - **CSRF 防护**: 实现 CSRF Token 验证 ## 11. 常见问题 ### 11.1 跨域问题 - **问题**: 浏览器同源策略导致跨域请求失败 - **解决方案**: 实现 CORS(跨域资源共享),设置适当的响应头 ### 10.2 认证失败 - **问题**: 请求未携带认证信息或认证信息无效 - **解决方案**: 检查请求头中的认证信息,确保令牌有效 ### 10.3 参数错误 - **问题**: 请求参数格式错误或缺少必填参数 - **解决方案**: 检查请求参数,确保格式正确且包含所有必填参数 ### 10.4 响应数据不符合预期 - **问题**: 响应数据格式或内容不符合预期 - **解决方案**: 检查 API 文档,确保请求格式正确,或联系 API 提供者 ### 10.5 性能问题 - **问题**: API 请求响应时间过长 - **解决方案**: 优化 API 实现,使用缓存,减少数据库查询次数 ## 12. 参考资源 - [RESTful API 设计指南](https://restfulapi.net/) - [HTTP 状态码](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status) - [API 设计最佳实践](https://cloud.google.com/apis/design) - [JSON API 规范](https://jsonapi.org/) - [OpenAPI 规范](https://swagger.io/specification/) - [API 安全性最佳实践](https://owasp.org/www-project-api-security/) --- ### .Codebuddy/Skills/Php Api/References/Db Design (.codebuddy/skills/php-api/references/db_design.md) # 数据库设计文档 ## 1. 概述 本文档描述了 CRMEB 项目的数据库设计,包括数据库架构、表结构、索引设计、关系设计等,旨在规范数据库设计,提高数据库性能和可维护性。 ## 2. 数据库架构 ### 2.1 整体架构 - **数据库系统**: MySQL 5.7~8.0 - **存储引擎**: InnoDB (默认) - **字符集**: utf8mb4 - **排序规则**: utf8mb4_general_ci - **连接池**: 建议使用 - **SQL文件位置**: `public/install/crmeb.sql` ### 2.2 技术栈 - **MySQL**: 5.7+ - **Redis**: 用于缓存 - **ThinkPHP ORM**: 用于模型操作 - **数据库迁移**: 用于版本控制 - **数据库备份**: 用于数据安全 ### 2.3 配置说明 #### 2.3.1 数据库配置 ```php // config/database.php return [ 'default' => env('database.driver', 'mysql'), 'connections' => [ 'mysql' => [ 'type' => 'mysql', 'hostname' => env('database.hostname', '127.0.0.1'), 'database' => env('database.database', ''), 'username' => env('database.username', ''), 'password' => env('database.password', ''), 'hostport' => env('database.hostport', '3306'), 'charset' => 'utf8mb4', 'prefix' => env('database.prefix', ''), 'debug' => env('app_debug', true), ], ], ]; ``` ## 3. 数据库设计规范 ### 3.1 命名规范 - **数据库名**: 小写字母,下划线分隔 - **表名**: 小写字母,下划线分隔,前缀统一 - **字段名**: 小写字母,下划线分隔 - **索引名**: 小写字母,下划线分隔,类型前缀 - 主键: `PRIMARY` - 唯一索引: `uk_字段名` - 普通索引: `idx_字段名` ### 3.2 表结构规范 - **主键**: 统一命名为 `id`,自增整数 - **外键**: 格式 `表名_id`,如 `user_id` - **时间字段**: `create_time`/`update_time` - **状态字段**: `status`,默认值 0 - **软删除字段**: `delete_time`,默认值 NULL ### 3.3 字段类型规范 - **整数类型**: 根据实际范围选择 - `TINYINT`: 1字节,范围 -128~127 - `SMALLINT`: 2字节,范围 -32768~32767 - `INT`: 4字节,范围 -2147483648~2147483647 - `BIGINT`: 8字节,范围更大 - **字符串类型**: - 固定长度: `CHAR` - 可变长度: `VARCHAR` - 长文本: `TEXT` - 大文本: `LONGTEXT` - **日期时间类型**: - 日期: `DATE` - 时间: `TIME` - 日期时间: `DATETIME` - 时间戳: `TIMESTAMP` - **数值类型**: - 小数: `DECIMAL` - 浮点数: `FLOAT`, `DOUBLE` - **布尔类型**: 使用 `TINYINT(1)`,0 表示 false,1 表示 true ### 3.4 索引规范 - **主键索引**: 每个表必须有主键 - **唯一索引**: 用于唯一标识的字段 - **普通索引**: 用于经常查询的字段 - **复合索引**: 用于多字段查询 - **外键索引**: 用于关联查询 - **索引数量**: 每个表索引数量不宜过多,一般不超过 5 个 ## 4. 核心表结构 ### 4.1 用户表 (`user`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 用户ID | | `username` | `VARCHAR` | 50 | `NOT NULL` | 用户名 | | `password` | `VARCHAR` | 255 | `NOT NULL` | 密码 | | `nickname` | `VARCHAR` | 50 | `NOT NULL` | 昵称 | | `avatar` | `VARCHAR` | 255 | | 头像 | | `mobile` | `VARCHAR` | 20 | | 手机号 | | `email` | `VARCHAR` | 100 | | 邮箱 | | `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ### 4.2 商品表 (`product`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 商品ID | | `name` | `VARCHAR` | 255 | `NOT NULL` | 商品名称 | | `category_id` | `INT` | 11 | `NOT NULL` | 分类ID | | `price` | `DECIMAL` | 10,2 | `NOT NULL` | 价格 | | `stock` | `INT` | 11 | `NOT NULL` | 库存 | | `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ### 4.3 订单表 (`order`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 订单ID | | `order_sn` | `VARCHAR` | 32 | `NOT NULL UNIQUE` | 订单号 | | `user_id` | `INT` | 11 | `NOT NULL` | 用户ID | | `total_price` | `DECIMAL` | 10,2 | `NOT NULL` | 总价 | | `status` | `TINYINT` | 1 | `DEFAULT 0` | 状态 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ### 4.4 分类表 (`category`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 分类ID | | `name` | `VARCHAR` | 50 | `NOT NULL` | 分类名称 | | `parent_id` | `INT` | 11 | `DEFAULT 0` | 父分类ID | | `sort` | `INT` | 11 | `DEFAULT 0` | 排序 | | `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ### 4.5 地址表 (`address`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 地址ID | | `user_id` | `INT` | 11 | `NOT NULL` | 用户ID | | `name` | `VARCHAR` | 50 | `NOT NULL` | 收货人姓名 | | `mobile` | `VARCHAR` | 20 | `NOT NULL` | 手机号 | | `province` | `VARCHAR` | 50 | `NOT NULL` | 省份 | | `city` | `VARCHAR` | 50 | `NOT NULL` | 城市 | | `district` | `VARCHAR` | 50 | `NOT NULL` | 区县 | | `detail` | `VARCHAR` | 255 | `NOT NULL` | 详细地址 | | `is_default` | `TINYINT` | 1 | `DEFAULT 0` | 是否默认 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ## 5. 索引设计 ### 5.1 用户表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `uk_username` | 唯一 | `username` | 用户名唯一索引 | | `idx_mobile` | 普通 | `mobile` | 手机号索引 | | `idx_email` | 普通 | `email` | 邮箱索引 | | `idx_status` | 普通 | `status` | 状态索引 | ### 5.2 商品表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `idx_category_id` | 普通 | `category_id` | 分类ID索引 | | `idx_price` | 普通 | `price` | 价格索引 | | `idx_status` | 普通 | `status` | 状态索引 | ### 5.3 订单表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `uk_order_sn` | 唯一 | `order_sn` | 订单号唯一索引 | | `idx_user_id` | 普通 | `user_id` | 用户ID索引 | | `idx_status` | 普通 | `status` | 状态索引 | | `idx_create_time` | 普通 | `create_time` | 创建时间索引 | ### 5.4 分类表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `idx_parent_id` | 普通 | `parent_id` | 父分类ID索引 | | `idx_sort` | 普通 | `sort` | 排序索引 | | `idx_status` | 普通 | `status` | 状态索引 | ### 5.5 地址表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `idx_user_id` | 普通 | `user_id` | 用户ID索引 | | `idx_is_default` | 普通 | `is_default` | 是否默认索引 | ## 6. 关系设计 ### 6.1 表关系图 ``` user ----------------- order | | | | | | address product | | | category ``` ### 6.2 关系说明 - **用户与订单**: 一对多关系,一个用户可以有多个订单 - **用户与地址**: 一对多关系,一个用户可以有多个地址 - **商品与分类**: 多对一关系,多个商品属于一个分类 - **订单与商品**: 多对多关系,一个订单可以包含多个商品,一个商品可以出现在多个订单中 ### 6.3 外键关系 | 主表 | 主键 | 从表 | 外键 | 描述 | |------|------|------|------|------| | `user` | `id` | `order` | `user_id` | 订单所属用户 | | `user` | `id` | `address` | `user_id` | 地址所属用户 | | `category` | `id` | `product` | `category_id` | 商品所属分类 | ## 7. 性能优化 ### 7.1 索引优化 - **选择合适的索引类型**: 根据查询场景选择合适的索引类型 - **避免过度索引**: 只在需要的字段上创建索引 - **使用复合索引**: 对于多字段查询,使用复合索引 - **定期维护索引**: 定期重建碎片化的索引 ### 7.2 查询优化 - **避免全表扫描**: 使用索引覆盖查询 - **减少查询字段**: 只查询需要的字段 - **使用连接查询**: 合理使用连接查询,避免子查询 - **限制查询结果**: 使用 LIMIT 限制查询结果数量 ### 7.3 存储优化 - **选择合适的字段类型**: 根据实际需求选择合适的字段类型 - **使用分区表**: 对于大表,使用分区表提高查询性能 - **定期清理数据**: 定期清理无用数据,减少表大小 - **使用缓存**: 对于频繁查询的数据,使用 Redis 缓存 ### 7.4 配置优化 - **调整 innodb_buffer_pool_size**: 根据服务器内存大小调整 - **调整 max_connections**: 根据并发量调整 - **启用查询缓存**: 对于读多写少的场景 - **优化日志配置**: 合理配置二进制日志和慢查询日志 ## 8. 安全设计 ### 8.1 数据安全 - **加密存储**: 敏感数据(如密码)加密存储 - **数据备份**: 定期备份数据库 - **数据恢复**: 建立数据恢复机制 - **访问控制**: 严格控制数据库访问权限 ### 8.2 SQL 注入防护 - **使用参数化查询**: 避免直接拼接 SQL - **使用 ORM**: 使用 ThinkPHP ORM 框架 - **输入验证**: 对用户输入进行验证 - **转义特殊字符**: 对特殊字符进行转义 ### 8.3 权限管理 - **最小权限原则**: 只授予必要的权限 - **角色分离**: 不同角色拥有不同权限 - **定期审计**: 定期审计数据库访问日志 ## 9. 备份与恢复 ### 9.1 备份策略 - **全量备份**: 定期进行全量备份 - **增量备份**: 每天进行增量备份 - **日志备份**: 备份二进制日志 ### 9.2 恢复策略 - **全量恢复**: 使用全量备份恢复 - **增量恢复**: 使用增量备份恢复 - **点恢复**: 使用二进制日志进行点恢复 ### 9.3 备份工具 - **mysqldump**: MySQL 自带备份工具 - **xtrabackup**: Percona 提供的备份工具 - **第三方工具**: 如 Navicat 等 ## 10. 版本控制 ### 10.1 数据库迁移 - **使用迁移工具**: 使用 ThinkPHP 数据库迁移工具 - **版本管理**: 对数据库结构变更进行版本管理 - **回滚机制**: 支持数据库结构回滚 ### 10.2 迁移文件命名规范 - **格式**: `YYYYMMDDHHMMSS_描述.php` - **示例**: `20230101000000_create_user_table.php` ### 10.3 迁移文件结构 ```php table('user'); $table->addColumn('username', 'string', ['limit' => 50, 'comment' => '用户名']) ->addColumn('password', 'string', ['limit' => 255, 'comment' => '密码']) ->addColumn('nickname', 'string', ['limit' => 50, 'comment' => '昵称']) ->addColumn('avatar', 'string', ['limit' => 255, 'comment' => '头像']) ->addColumn('mobile', 'string', ['limit' => 20, 'comment' => '手机号']) ->addColumn('email', 'string', ['limit' => 100, 'comment' => '邮箱']) ->addColumn('status', 'tinyint', ['default' => 1, 'comment' => '状态']) ->addColumn('create_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间']) ->addColumn('update_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'update' => 'CURRENT_TIMESTAMP', 'comment' => '更新时间']) ->addColumn('delete_time', 'datetime', ['comment' => '删除时间']) ->addIndex('username', ['unique' => true]) ->addIndex('mobile') ->addIndex('email') ->addIndex('status') ->create(); } } ``` ## 11. 维护与监控 ### 11.1 日常维护 - **定期优化表**: 定期执行 OPTIMIZE TABLE 命令 - **监控表大小**: 监控表大小变化 - **检查慢查询**: 定期分析慢查询日志 - **更新统计信息**: 定期更新表统计信息 ### 11.2 监控指标 - **查询性能**: 监控查询响应时间 - **连接数**: 监控数据库连接数 - **缓存命中率**: 监控缓存命中率 - **磁盘使用率**: 监控磁盘空间使用情况 - **CPU 使用率**: 监控数据库服务器 CPU 使用率 ### 11.3 监控工具 - **MySQL Enterprise Monitor**: MySQL 企业版监控工具 - **Percona Monitoring and Management**: 开源监控工具 - **Zabbix**: 通用监控工具 - **Prometheus + Grafana**: 现代化监控方案 ## 12. 总结 本文档描述了 CRMEB 项目的数据库设计规范和最佳实践,包括数据库架构、表结构、索引设计、关系设计、性能优化、安全设计、备份与恢复、版本控制、维护与监控等方面。 遵循本文档的设计规范,可以提高数据库性能和可维护性,确保系统的稳定运行。同时,定期对数据库进行维护和监控,可以及时发现和解决潜在问题,保障系统的安全性和可靠性。 随着业务的发展和系统的演进,数据库设计也需要不断优化和调整,以适应新的业务需求和技术挑战。 --- ### .Codebuddy/Skills/Php Api/References/Directory Structure (.codebuddy/skills/php-api/references/directory_structure.md) # 目录结构文档 ## 1. 概述 本文档描述了 CRMEB 项目的目录结构,包括各目录的功能、文件组织方式等,旨在帮助开发者理解项目结构,提高开发效率。 ## 2. 项目根目录结构 ``` CRMEB/ ├── app/ # 应用目录 ├── config/ # 配置目录 ├── crmeb/ # 核心库目录 ├── database/ # 数据库目录 ├── extend/ # 扩展目录 ├── public/ # 公共资源目录 ├── runtime/ # 运行时目录 ├── thinkphp/ # ThinkPHP 核心目录 ├── vendor/ # 第三方依赖目录 ├── .env # 环境变量文件 ├── .env.example # 环境变量示例文件 ├── composer.json # Composer 配置文件 ├── composer.lock # Composer 锁定文件 ├── LICENSE # 许可证文件 ├── README.md # 项目说明文档 ├── think # ThinkPHP 命令行工具 ``` ## 3. 应用目录结构 (app/) ``` app/ ├── api/ # API 接口层 │ ├── v1/ # API 版本 1 │ ├── v2/ # API 版本 2 │ └── BaseApi.php # API 基类 ├── controller/ # 控制器层 │ ├── admin/ # 管理端控制器 │ ├── api/ # API 控制器 │ └── BaseController.php # 控制器基类 ├── dao/ # 数据访问层 │ └── BaseDao.php # DAO 基类 ├── event/ # 事件层 ├── exception/ # 异常处理层 ├── middleware/ # 中间件层 ├── model/ # 模型层 │ └── BaseModel.php # 模型基类 ├── services/ # 业务逻辑层 │ └── BaseServices.php # 服务基类 ├── subscribe/ # 事件订阅层 ├── validate/ # 验证层 │ └── BaseValidate.php # 验证器基类 └── common.php # 公共函数文件 ``` ### 3.1 API 目录 (app/api/) - **功能**: 处理 API 接口请求 - **结构**: 按 API 版本划分目录 - **基类**: `BaseApi.php`,提供 API 基础功能 - **版本控制**: 通过目录结构实现 API 版本管理 ### 3.2 控制器目录 (app/controller/) - **功能**: 处理 HTTP 请求,路由分发 - **结构**: 按模块划分控制器 - **基类**: `BaseController.php`,提供控制器基础功能 - **类型**: 管理端控制器、API 控制器 ### 3.3 DAO 目录 (app/dao/) - **功能**: 数据访问对象,封装数据库操作 - **结构**: 按业务模块划分 DAO 类 - **基类**: `BaseDao.php`,提供 DAO 基础功能 - **职责**: 处理数据库查询、插入、更新、删除等操作 ### 3.4 模型目录 (app/model/) - **功能**: 数据模型,定义数据结构和关系 - **结构**: 按业务模块划分模型类 - **基类**: `BaseModel.php`,提供模型基础功能 - **特性**: 支持 ORM、关联查询、软删除等 ### 3.5 服务目录 (app/services/) - **功能**: 业务逻辑层,封装核心业务逻辑 - **结构**: 按业务模块划分服务类 - **基类**: `BaseServices.php`,提供服务基础功能 - **职责**: 实现业务规则,协调多个 DAO 和模型 ### 3.6 验证目录 (app/validate/) - **功能**: 数据验证,验证请求参数 - **结构**: 按业务模块划分验证器类 - **基类**: `BaseValidate.php`,提供验证器基础功能 - **特性**: 支持规则验证、场景验证等 ## 4. 配置目录结构 (config/) ``` config/ ├── app.php # 应用配置 ├── cache.php # 缓存配置 ├── captcha.php # 验证码配置 ├── console.php # 控制台配置 ├── cookie.php # Cookie 配置 ├── database.php # 数据库配置 ├── filesystem.php # 文件系统配置 ├── lang.php # 语言配置 ├── log.php # 日志配置 ├── queue.php # 队列配置 ├── route.php # 路由配置 ├── session.php # Session 配置 ├── template.php # 模板配置 └── trace.php # 调试配置 ``` - **功能**: 存储项目的所有配置文件 - **结构**: 按功能模块划分配置文件 - **特性**: 支持环境变量配置、配置缓存等 - **加载顺序**: 框架配置 → 应用配置 → 环境配置 ## 5. 核心库目录结构 (crmeb/) ``` crmeb/ ├── basic/ # 基础类库 ├── exception/ # 核心异常类 ├── services/ # 核心服务类 ├── utils/ # 工具类 └── version.php # 版本信息 ``` - **功能**: 存储 CRMEB 核心库代码 - **结构**: 按功能模块划分目录 - **特性**: 独立于应用代码,便于维护和升级 - **作用**: 提供核心功能和基础服务 ## 6. 数据库目录结构 (database/) ``` database/ ├── migrations/ # 数据库迁移文件 └── seeders/ # 数据库种子文件 ``` - **功能**: 存储数据库相关文件 - **迁移文件**: 用于版本控制数据库结构 - **种子文件**: 用于初始化数据库数据 - **工具**: 使用 ThinkPHP 迁移工具管理 ## 7. 公共资源目录结构 (public/) ``` public/ ├── admin/ # 管理端资源 ├── api/ # API 资源 ├── assets/ # 静态资源 │ ├── css/ # CSS 文件 │ ├── images/ # 图片文件 │ └── js/ # JavaScript 文件 ├── index.php # 应用入口文件 ├── robots.txt # 机器人协议文件 └── router.php # URL 重写文件 ``` - **功能**: 存储可直接访问的公共资源 - **结构**: 按功能模块划分目录 - **特性**: 可通过 URL 直接访问 - **安全**: 敏感文件不应放在此目录 ## 8. 运行时目录结构 (runtime/) ``` runtime/ ├── cache/ # 缓存目录 ├── log/ # 日志目录 │ └── app/ # 应用日志 ├── session/ # Session 目录 ├── temp/ # 临时文件目录 └── think/ # ThinkPHP 运行时目录 ``` - **功能**: 存储运行时生成的文件 - **结构**: 按功能模块划分目录 - **特性**: 自动生成,无需手动维护 - **权限**: 需要可写权限 ## 9. 核心目录结构 (thinkphp/) ``` thinkphp/ ├── lang/ # 语言包目录 ├── library/ # 核心类库目录 ├── tpl/ # 模板目录 ├── base.php # 基础定义文件 ├── composer.json # Composer 配置文件 └── helper.php # 助手函数文件 ``` - **功能**: 存储 ThinkPHP 框架核心代码 - **结构**: 框架默认结构 - **特性**: 独立于应用代码 - **升级**: 通过 Composer 升级 ## 10. 第三方依赖目录结构 (vendor/) ``` vendor/ ├── autoload.php # 自动加载文件 ├── composer/ # Composer 核心目录 ├── symfony/ # Symfony 组件 ├── topthink/ # ThinkPHP 组件 └── ... # 其他第三方依赖 ``` - **功能**: 存储第三方依赖库 - **管理**: 通过 Composer 管理 - **结构**: 按依赖包名称划分目录 - **自动加载**: 通过 `autoload.php` 自动加载 ## 11. 目录结构最佳实践 ### 11.1 命名规范 - **目录名**: 小写字母,单词之间用下划线分隔 - **文件名**: 与类名一致,使用 PascalCase 命名风格 - **类名**: 使用 PascalCase 命名风格 - **方法名**: 使用 camelCase 命名风格 - **变量名**: 使用 camelCase 命名风格 ### 11.2 组织原则 - **模块化**: 按功能模块组织目录结构 - **分层架构**: 遵循 MVC + Service + DAO 分层架构 - **单一职责**: 每个目录和文件只负责一个功能 - **可扩展性**: 便于添加新功能和模块 - **易维护性**: 便于理解和维护 ### 11.3 开发建议 - **遵循框架规范**: 遵循 ThinkPHP 框架目录结构规范 - **合理划分模块**: 根据业务功能合理划分模块 - **避免目录过深**: 目录层级不宜过深,一般不超过 4 层 - **保持目录整洁**: 及时清理无用文件和目录 - **文档化**: 为重要目录添加说明文档 ## 12. 常见问题 ### 12.1 目录权限问题 - **问题**: 运行时目录没有写权限 - **解决方案**: 执行 `chmod -R 777 runtime/` 赋予写权限 ### 12.2 自动加载问题 - **问题**: 新增类无法自动加载 - **解决方案**: 执行 `composer dump-autoload` 更新自动加载 ### 12.3 配置文件不生效 - **问题**: 修改配置文件后不生效 - **解决方案**: 清除配置缓存,执行 `php think clear` ### 12.4 目录结构混乱 - **问题**: 目录结构不清晰,难以维护 - **解决方案**: 重新组织目录结构,遵循模块化原则 ## 13. 参考资源 - [ThinkPHP 6 目录结构](https://www.kancloud.cn/manual/thinkphp6_0/1037487) - [MVC 架构设计](https://zh.wikipedia.org/wiki/MVC) - [分层架构设计](https://zh.wikipedia.org/wiki/分层架构) - [模块化设计](https://zh.wikipedia.org/wiki/模块化设计) --- ### .Codebuddy/Skills/Php Api/References/Error Code (.codebuddy/skills/php-api/references/error_code.md) # 错误码文档 ## 1. 概述 本文档描述了 CRMEB 项目的错误码规范,包括错误码的分类、定义、使用方法等,旨在统一错误码格式,提高错误处理的一致性和可维护性。 ## 2. 错误码分类 ### 2.1 HTTP 状态码 - **1xx**: 信息性状态码,表示请求已接收,继续处理 - **2xx**: 成功状态码,表示请求已成功处理 - **3xx**: 重定向状态码,表示需要进一步操作以完成请求 - **4xx**: 客户端错误状态码,表示请求包含语法错误或无法完成请求 - **5xx**: 服务器错误状态码,表示服务器在处理请求时发生错误 ### 2.2 业务错误码 业务错误码由 5 位数字组成,格式为 `XXXXX`,其中: - **第一位**: 错误类型标识 - `1`: 系统错误 - `2`: 业务错误 - `3`: 参数错误 - `4`: 权限错误 - `5`: 资源错误 - `6`: 数据库错误 - `7`: 第三方服务错误 - `8`: 其他错误 - **后四位**: 具体错误编码,从 0000 开始递增 ## 3. 系统错误码 ### 3.1 系统错误 (1xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 10001 | 系统内部错误 | 500 | | 10002 | 系统维护中 | 503 | | 10003 | 系统繁忙 | 503 | | 10004 | 服务不可用 | 503 | | 10005 | 网关错误 | 502 | ### 3.2 业务错误 (2xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 20001 | 操作失败 | 400 | | 20002 | 业务逻辑错误 | 400 | | 20003 | 数据已存在 | 400 | | 20004 | 数据不存在 | 404 | | 20005 | 操作不允许 | 403 | ### 3.3 参数错误 (3xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 30001 | 参数不能为空 | 400 | | 30002 | 参数格式错误 | 400 | | 30003 | 参数类型错误 | 400 | | 30004 | 参数超出范围 | 400 | | 30005 | 参数验证失败 | 422 | ### 3.4 权限错误 (4xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 40001 | 未登录 | 401 | | 40002 | 登录已过期 | 401 | | 40003 | 无权限访问 | 403 | | 40004 | 权限不足 | 403 | | 40005 | 令牌无效 | 401 | ### 3.5 资源错误 (5xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 50001 | 资源不存在 | 404 | | 50002 | 资源已删除 | 404 | | 50003 | 资源已锁定 | 400 | | 50004 | 资源不足 | 400 | | 50005 | 资源已过期 | 400 | ### 3.6 数据库错误 (6xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 60001 | 数据库连接失败 | 500 | | 60002 | 数据库查询失败 | 500 | | 60003 | 数据库更新失败 | 500 | | 60004 | 数据库插入失败 | 500 | | 60005 | 数据库删除失败 | 500 | | 60006 | 数据库事务失败 | 500 | ### 3.7 第三方服务错误 (7xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 70001 | 第三方服务连接失败 | 500 | | 70002 | 第三方服务超时 | 504 | | 70003 | 第三方服务返回错误 | 500 | | 70004 | 第三方服务认证失败 | 401 | | 70005 | 第三方服务限流 | 429 | ## 4. 模块错误码 ### 4.1 用户模块 (801xx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 80101 | 用户名或密码错误 | 401 | | 80102 | 用户不存在 | 404 | | 80103 | 用户已存在 | 400 | | 80104 | 用户状态异常 | 400 | | 80105 | 验证码错误 | 400 | | 80106 | 验证码已过期 | 400 | | 80107 | 手机号格式错误 | 400 | | 80108 | 邮箱格式错误 | 400 | ### 4.2 商品模块 (802xx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 80201 | 商品不存在 | 404 | | 80202 | 商品已下架 | 400 | | 80203 | 商品库存不足 | 400 | | 80204 | 商品价格异常 | 400 | | 80205 | 商品分类不存在 | 404 | ### 4.3 订单模块 (803xx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 80301 | 订单不存在 | 404 | | 80302 | 订单状态异常 | 400 | | 80303 | 订单已取消 | 400 | | 80304 | 订单已完成 | 400 | | 80305 | 订单支付失败 | 400 | | 80306 | 订单支付超时 | 400 | ### 4.4 支付模块 (804xx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 80401 | 支付方式不支持 | 400 | | 80402 | 支付金额异常 | 400 | | 80403 | 支付参数错误 | 400 | | 80404 | 支付失败 | 400 | | 80405 | 支付超时 | 400 | | 80406 | 支付已完成 | 400 | ## 5. 错误码使用规范 ### 5.1 错误响应格式 ```json { "code": 20001, "msg": "操作失败", "data": [] } ``` ### 5.2 成功响应格式 ```json { "code": 200, "msg": "操作成功", "data": {...} } ``` ### 5.3 错误处理流程 1. **捕获异常**: 在控制器或中间件中捕获异常 2. **确定错误码**: 根据异常类型确定对应的错误码 3. **构建响应**: 按照统一格式构建错误响应 4. **返回响应**: 返回错误响应给客户端 ### 5.4 错误日志记录 - **记录内容**: 错误码、错误信息、请求参数、请求路径、用户信息、时间戳等 - **记录级别**: 根据错误严重程度选择合适的日志级别 - **记录位置**: 系统日志文件 - **监控告警**: 对于严重错误,触发告警机制 ## 6. 错误码管理 ### 6.1 错误码定义 错误码定义在配置文件中,便于统一管理和维护: ```php // config/error_code.php return [ // 系统错误 10001 => '系统内部错误', 10002 => '系统维护中', // 业务错误 20001 => '操作失败', 20002 => '业务逻辑错误', // 参数错误 30001 => '参数不能为空', 30002 => '参数格式错误', // ... ]; ``` ### 6.2 错误码使用 在代码中使用错误码时,应直接引用配置文件中的定义: ```php // 控制器中使用 return $this->fail(config('error_code.20001')); // 或直接使用错误码 return $this->fail('操作失败', [], 20001); ``` ### 6.3 错误码更新 当需要添加新的错误码时,应遵循以下流程: 1. **确定错误类型**: 根据错误性质确定错误类型 2. **分配错误码**: 从对应类型的错误码范围中分配一个未使用的错误码 3. **更新配置**: 在 `error_code.php` 配置文件中添加错误码定义 4. **更新文档**: 更新错误码文档 5. **通知团队**: 通知团队成员新添加的错误码 ## 7. 错误码最佳实践 ### 7.1 设计原则 - **唯一性**: 每个错误码唯一对应一种错误情况 - **可读性**: 错误码应易于理解和记忆 - **可扩展性**: 错误码应具有良好的扩展性,便于添加新的错误码 - **一致性**: 错误码格式和使用方法应保持一致 - **详细性**: 错误信息应清晰、准确,便于调试和定位问题 ### 7.2 使用建议 - **避免硬编码**: 错误码应定义在配置文件中,避免直接硬编码在代码中 - **统一处理**: 使用统一的错误处理中间件处理错误 - **详细日志**: 记录详细的错误日志,便于调试和分析 - **友好提示**: 向客户端返回友好的错误信息,避免暴露系统内部细节 - **定期清理**: 定期清理不再使用的错误码,保持错误码的简洁性 ### 7.3 常见问题 #### 7.3.1 错误码冲突 - **问题**: 不同模块使用了相同的错误码 - **解决方案**: 严格按照模块划分错误码范围,避免冲突 #### 7.3.2 错误信息不明确 - **问题**: 错误信息过于简洁,无法定位问题 - **解决方案**: 提供详细的错误信息,包含必要的上下文 #### 7.3.3 错误码未及时更新 - **问题**: 新增功能时未及时添加对应的错误码 - **解决方案**: 在开发新功能时,同步更新错误码定义和文档 ## 8. 参考资源 - [HTTP 状态码](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status) - [RESTful API 错误处理](https://restfulapi.net/http-status-codes/) - [错误码设计最佳实践](https://www.thoughtworks.com/insights/blog/error-handling-microservices) - [API 错误码规范](https://cloud.google.com/apis/design/errors) --- ### .Codebuddy/Skills/Uniapp/References/Api Flow (.codebuddy/skills/uniapp/references/api_flow.md) # UniApp API 开发流程文档 ## 1. 概述 本文档描述了 CRMEB 项目中 UniApp 移动端的 API 开发流程,包括 API 接口设计、请求流程、响应处理、错误处理等,旨在规范 API 开发,提高开发效率和代码质量。 ## 2. API 目录结构 ``` template/uni-app/api/ ├── activity.js # 活动相关接口 ├── admin.js # 管理相关接口 ├── api.js # 基础 API 配置 ├── kefu.js # 客服相关接口 ├── lottery.js # 抽奖相关接口 ├── order.js # 订单相关接口 ├── public.js # 公共接口 ├── store.js # 商城相关接口 └── user.js # 用户相关接口 ``` ## 3. 基础 API 配置 (api.js) ```javascript // 基础 API 配置 const baseURL = 'https://api.crmeb.net'; // 请求超时时间 const timeout = 10000; // 请求拦截器 const requestInterceptor = (config) => { // 添加 token const token = uni.getStorageSync('token'); if (token) { config.header['Authorization'] = `Bearer ${token}`; } // 添加设备信息 config.header['X-Device-Type'] = uni.getSystemInfoSync().platform; return config; }; // 响应拦截器 const responseInterceptor = (response) => { const { data } = response; // 统一处理错误 if (data.code !== 200) { uni.showToast({ title: data.message || '请求失败', icon: 'none' }); // 处理登录过期 if (data.code === 401) { uni.redirectTo({ url: '/pages/login/index' }); } return Promise.reject(data); } return data; }; // 错误处理 const errorHandler = (error) => { uni.showToast({ title: '网络错误,请稍后重试', icon: 'none' }); return Promise.reject(error); }; // 导出配置 export default { baseURL, timeout, requestInterceptor, responseInterceptor, errorHandler }; ``` ## 4. API 接口封装 ### 4.1 通用请求方法 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 4.2 业务接口封装 ```javascript // api/user.js import request from '../utils/request'; // 用户相关接口 export default { // 登录 login: (data) => request.post('/api/user/login', data), // 注册 register: (data) => request.post('/api/user/register', data), // 获取用户信息 getUserInfo: () => request.get('/api/user/info'), // 更新用户信息 updateUserInfo: (data) => request.put('/api/user/info', data), // 修改密码 changePassword: (data) => request.post('/api/user/password', data), // 获取地址列表 getAddressList: () => request.get('/api/user/address'), // 添加地址 addAddress: (data) => request.post('/api/user/address', data), // 更新地址 updateAddress: (id, data) => request.put(`/api/user/address/${id}`, data), // 删除地址 deleteAddress: (id) => request.delete(`/api/user/address/${id}`), // 设置默认地址 setDefaultAddress: (id) => request.put(`/api/user/address/${id}/default`) }; ``` ## 5. API 调用示例 ### 5.1 页面中调用 API ```vue ``` ### 5.2 组件中调用 API ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 6. API 开发最佳实践 ### 6.1 命名规范 - **文件命名**: 小写字母,单词之间用下划线分隔,如 `user.js` - **方法命名**: 驼峰命名法,如 `getUserInfo` - **URL 命名**: 小写字母,单词之间用连字符分隔,如 `/api/user/info` - **参数命名**: 驼峰命名法,与后端保持一致 ### 6.2 接口设计规范 - **RESTful 风格**: 遵循 RESTful API 设计规范 - **版本控制**: 在 URL 中包含版本号,如 `/api/v1/user/info` - **统一响应格式**: 所有接口返回统一的响应格式 - **错误处理**: 统一的错误码和错误信息 ### 6.3 请求规范 - **请求方法**: 根据操作类型选择合适的 HTTP 方法 - GET: 获取资源 - POST: 创建资源 - PUT: 更新资源 - DELETE: 删除资源 - **请求头**: 统一添加必要的请求头,如 Authorization、Content-Type 等 - **参数传递**: 根据请求方法选择合适的参数传递方式 - GET: 查询参数 - POST/PUT: 请求体 - DELETE: 查询参数或路径参数 ### 6.4 响应规范 - **成功响应**: ```json { "code": 200, "message": "请求成功", "data": {} } ``` - **失败响应**: ```json { "code": 400, "message": "请求失败", "data": {} } ``` ### 6.5 错误处理规范 - **网络错误**: 统一处理网络错误,如超时、断网等 - **业务错误**: 根据错误码处理不同的业务错误 - **登录过期**: 统一处理登录过期,跳转到登录页面 - **错误提示**: 统一的错误提示方式,使用 uni.showToast ## 7. API 性能优化 ### 7.1 请求优化 - **合并请求**: 多个相关请求合并为一个 - **缓存策略**: 对不经常变化的数据使用缓存 - **请求防抖**: 避免频繁发送相同的请求 - **批量操作**: 支持批量操作,减少请求次数 ### 7.2 响应优化 - **数据结构优化**: 优化响应数据结构,减少数据传输量 - **分页处理**: 对列表数据使用分页 - **字段筛选**: 支持字段筛选,只返回需要的字段 - **压缩传输**: 使用 gzip 压缩传输数据 ### 7.3 代码优化 - **模块化**: 按业务模块划分 API 文件 - **复用代码**: 提取通用的请求逻辑 - **减少冗余**: 避免重复的 API 调用 - **代码可读性**: 保持代码清晰易读 ## 8. 常见问题 ### 8.1 跨域问题 - **问题**: 开发环境中遇到跨域问题 - **解决方案**: 在本地开发服务器中配置跨域代理 ### 8.2 Token 过期问题 - **问题**: Token 过期后请求失败 - **解决方案**: 在响应拦截器中处理 Token 过期,跳转到登录页面 ### 8.3 请求超时问题 - **问题**: 网络不稳定时请求超时 - **解决方案**: 设置合理的超时时间,添加网络状态检测 ### 8.4 重复请求问题 - **问题**: 快速点击按钮导致重复请求 - **解决方案**: 添加请求防抖或锁机制 ### 8.5 数据缓存问题 - **问题**: 缓存数据与服务器数据不一致 - **解决方案**: 合理设置缓存过期时间,提供手动刷新机制 ## 9. 参考资源 - [UniApp 网络请求文档](https://uniapp.dcloud.io/api/request/request) - [RESTful API 设计指南](https://restfulapi.cn/) - [Axios 文档](https://axios-http.com/zh/docs/intro) - [HTTP 方法](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods) ## 10. 总结 本文档描述了 CRMEB 项目中 UniApp 移动端的 API 开发流程,包括 API 接口设计、请求流程、响应处理、错误处理等。遵循本文档的开发规范,可以提高 API 开发的效率和质量,确保应用的稳定性和可靠性。 随着业务的发展和技术的演进,API 开发流程也需要不断优化和调整,以适应新的业务需求和技术挑战。 --- ### .Codebuddy/Skills/Uniapp/References/Code Style (.codebuddy/skills/uniapp/references/code_style.md) # UniApp 代码规范文档 ## 1. 概述 本文档描述了 CRMEB 项目中 UniApp 移动端的代码规范,包括命名规范、代码风格、文件结构、组件开发等,旨在统一代码风格,提高代码质量和可维护性。 ## 2. 命名规范 ### 2.1 目录命名 - **目录名**: 小写字母,单词之间用下划线分隔 - **示例**: `pages/index/`、`components/common/`、`utils/` - **规范**: 简洁明了,反映目录的功能 ### 2.2 文件命名 - **页面文件**: 小写字母,单词之间用下划线分隔 - **示例**: `index.vue`、`login.vue`、`user_info.vue` - **组件文件**: 大写字母开头的 PascalCase 命名风格 - **示例**: `Button.vue`、`NavBar.vue`、`GoodsList.vue` - **JS 文件**: 小写字母,单词之间用下划线分隔 - **示例**: `user.js`、`request.js`、`util.js` - **CSS/SCSS 文件**: 小写字母,单词之间用下划线分隔 - **示例**: `common.scss`、`theme.scss` ### 2.3 变量命名 - **普通变量**: 驼峰命名法 - **示例**: `userInfo`、`goodsList`、`isLoading` - **常量**: 全大写,单词之间用下划线分隔 - **示例**: `BASE_URL`、`MAX_COUNT`、`DEFAULT_PAGE_SIZE` - **布尔变量**: 以 `is` 开头的驼峰命名法 - **示例**: `isShow`、`isLoading`、`isLogin` ### 2.4 函数命名 - **函数名**: 驼峰命名法,动词开头 - **示例**: `getUserInfo`、`submitForm`、`handleClick` - **方法名**: 驼峰命名法 - **示例**: `data`、`methods`、`computed`、`watch` - **生命周期函数**: 按照 Vue 规范命名 - **示例**: `created`、`mounted`、`beforeDestroy` ### 2.5 组件命名 - **组件名**: PascalCase 命名风格 - **示例**: `Button`、`NavBar`、`GoodsList` - **组件标签**: 小写字母,单词之间用连字符分隔 - **示例**: ``、``、`` ### 2.6 其他命名 - **路由命名**: 小写字母,单词之间用连字符分隔 - **示例**: `/pages/index/index`、`/pages/user/login` - **CSS 类名**: 小写字母,单词之间用连字符分隔 - **示例**: `.user-info`、`.goods-list`、`.btn-primary` - **ID 命名**: 小写字母,单词之间用连字符分隔 - **示例**: `#app`、`#header`、`#footer` ## 3. 代码风格 ### 3.1 缩进 - **缩进方式**: 4 个空格 - **示例**: ```vue ``` ### 3.2 换行 - **标签换行**: 多个属性的标签应该换行 - **示例**: ```vue {{ message }} ``` - **代码块换行**: 逻辑代码块应该换行 - **示例**: ```javascript if (condition) { // 代码块 } else { // 代码块 } ``` ### 3.3 空格 - **运算符空格**: 运算符两侧应该有空格 - **示例**: `a + b`、`x = y`、`i < 10` - **逗号空格**: 逗号后面应该有空格 - **示例**: `[1, 2, 3]`、`{ name: '张三', age: 18 }` - **括号空格**: 括号内侧不应该有空格 - **示例**: `if (condition)`、`function (param)` ### 3.4 注释 - **单行注释**: 使用 `//` 注释 - **示例**: `// 这是单行注释` - **多行注释**: 使用 `/* */` 注释 - **示例**: ```javascript /* * 这是多行注释 * 第二行 */ ``` - **文档注释**: 使用 JSDoc 风格的注释 - **示例**: ```javascript /** * 获取用户信息 * @param {number} id - 用户ID * @returns {Promise} 用户信息 */ async function getUserInfo(id) { // 代码 } ``` ### 3.5 引号 - **字符串**: 使用单引号 `''` - **示例**: `const name = '张三'`、`Hello` - **模板字符串**: 使用反引号 `` ` `` - **示例**: `` const url = `${baseUrl}/api/user` `` - **HTML 属性**: 使用双引号 `""` - **示例**: ``、`` ## 4. 文件结构 ### 4.1 页面文件结构 ```vue ``` ### 4.2 组件文件结构 ```vue ``` ### 4.3 JS 文件结构 ```javascript // 导入依赖 import request from './request'; // 常量定义 const BASE_URL = 'https://api.crmeb.net'; const TIMEOUT = 10000; // 工具函数 function formatTime(time) { const date = new Date(time); return date.toLocaleString(); } function getRandomNum(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } // 导出 export { formatTime, getRandomNum }; // 默认导出 export default { BASE_URL, TIMEOUT }; ``` ## 5. 组件开发规范 ### 5.1 组件设计 - **单一职责**: 每个组件只负责一个功能 - **可复用性**: 设计通用的、可复用的组件 - **可配置性**: 通过 props 提供配置选项 - **事件通信**: 通过事件与父组件通信 ### 5.2 组件使用 - **组件导入**: 使用 import 导入组件 - **示例**: `import Button from '../../components/Button.vue'` - **组件注册**: 在 components 中注册组件 - **示例**: ```javascript components: { Button } ``` - **组件使用**: 使用组件标签 - **示例**: `` ### 5.3 组件通信 - **props 向下传递**: 父组件通过 props 向子组件传递数据 - **events 向上传递**: 子组件通过 events 向父组件传递事件 - **refs 引用**: 通过 refs 引用子组件实例 - **provide/inject**: 祖先组件向后代组件传递数据 ## 6. 页面开发规范 ### 6.1 页面结构 - **模板结构**: 清晰明了,层次分明 - **脚本结构**: 按照 Vue 规范组织代码 - **样式结构**: 模块化,可维护 ### 6.2 数据管理 - **本地数据**: 使用 data 管理组件内部数据 - **计算数据**: 使用 computed 计算衍生数据 - **监听数据**: 使用 watch 监听数据变化 - **全局数据**: 使用 Vuex 管理全局数据 ### 6.3 生命周期管理 - **created**: 初始化数据,发送请求 - **mounted**: 操作 DOM,初始化第三方库 - **beforeDestroy**: 清理定时器,取消订阅 ### 6.4 路由管理 - **路由配置**: 在 pages.json 中配置路由 - **路由跳转**: 使用 uni.navigateTo、uni.redirectTo 等方法 - **路由参数**: 通过 options 或 $route.params 获取路由参数 ## 7. API 调用规范 ### 7.1 API 封装 - **模块化**: 按业务模块封装 API - **统一处理**: 统一处理请求头、响应拦截、错误处理 - **Promise 化**: 使用 Promise 处理异步请求 ### 7.2 API 调用 - **异步处理**: 使用 async/await 处理异步请求 - **错误处理**: 使用 try/catch 捕获错误 - **加载状态**: 显示加载状态,提升用户体验 - **错误提示**: 统一处理错误提示 ### 7.3 示例代码 ```javascript async function getUserInfo() { try { this.loading = true; const res = await userApi.getUserInfo(); this.userInfo = res.data; } catch (error) { console.error('获取用户信息失败:', error); uni.showToast({ title: '获取用户信息失败', icon: 'none' }); } finally { this.loading = false; } } ``` ## 8. 性能优化 ### 8.1 代码优化 - **减少冗余代码**: 避免重复的代码 - **使用计算属性**: 对于复杂的计算,使用 computed - **使用 v-if 和 v-show 合理**: 根据场景选择合适的指令 - **使用 key**: 在 v-for 中使用 key,提高渲染性能 ### 8.2 网络优化 - **合理使用缓存**: 缓存不经常变化的数据 - **减少请求次数**: 合并请求,批量操作 - **使用防抖和节流**: 避免频繁的事件触发 - **延迟加载**: 对于非首屏内容,使用延迟加载 ### 8.3 其他优化 - **减少 DOM 节点**: 简化 DOM 结构 - **优化图片**: 使用合适的图片格式和大小 - **使用虚拟列表**: 对于长列表,使用虚拟列表 - **避免内存泄漏**: 及时清理定时器、事件监听器等 ## 9. 常见问题 ### 9.1 代码风格问题 - **问题**: 代码风格不一致 - **解决方案**: 使用 ESLint 等工具进行代码检查 ### 9.2 性能问题 - **问题**: 页面加载慢,卡顿 - **解决方案**: 优化代码,减少 DOM 操作,使用虚拟列表等 ### 9.3 兼容性问题 - **问题**: 在不同平台上表现不一致 - **解决方案**: 遵循 UniApp 规范,使用条件编译 ### 9.4 维护性问题 - **问题**: 代码难以维护 - **解决方案**: 模块化开发,添加注释,遵循代码规范 ## 10. 参考资源 - [Vue 官方文档](https://cn.vuejs.org/) - [UniApp 官方文档](https://uniapp.dcloud.io/) - [ESLint 官方文档](https://eslint.org/docs/user-guide/) - [Prettier 官方文档](https://prettier.io/docs/en/) - [前端代码规范指南](https://github.com/ecomfe/spec) ## 11. 总结 本文档描述了 CRMEB 项目中 UniApp 移动端的代码规范,包括命名规范、代码风格、文件结构、组件开发等。遵循本文档的规范,可以提高代码的可读性、可维护性和可扩展性,确保项目的质量和稳定性。 代码规范是团队协作的基础,建议开发团队成员严格遵循本文档的规范,共同维护一个高质量的代码库。 --- ### .Codebuddy/Skills/Uniapp/References/Directory Structure (.codebuddy/skills/uniapp/references/directory_structure.md) # UniApp 目录结构文档 ## 1. 概述 本文档描述了 CRMEB 项目中 UniApp 移动端的目录结构,包括各目录的功能、文件组织方式等,旨在帮助开发者理解项目结构,提高开发效率。 ## 2. 项目根目录结构 ``` template/uni-app/ ├── api/ # API 接口目录 ├── config/ # 配置目录 ├── libs/ # 库文件目录 ├── mixins/ # 混入目录 ├── store/ # 状态管理目录 ├── utils/ # 工具类目录 ├── App.vue # 应用入口组件 ├── main.js # 应用入口文件 ├── manifest.json # 应用配置文件 ├── package.json # 项目配置文件 ├── pages.json # 页面路由配置文件 ├── uni.scss # UniApp 全局样式文件 └── vue.config.js # Vue 配置文件 ``` ## 3. API 目录结构 (api/) ``` api/ ├── activity.js # 活动相关接口 ├── admin.js # 管理相关接口 ├── api.js # 基础 API 配置 ├── kefu.js # 客服相关接口 ├── lottery.js # 抽奖相关接口 ├── order.js # 订单相关接口 ├── public.js # 公共接口 ├── store.js # 商城相关接口 └── user.js # 用户相关接口 ``` - **功能**: 封装与后端交互的 API 接口 - **结构**: 按业务模块划分接口文件 - **特性**: 统一处理请求头、响应拦截、错误处理等 - **调用方式**: 通过 `import` 导入使用 ## 4. 配置目录结构 (config/) ``` config/ ├── app.js # 应用配置 ├── cache.js # 缓存配置 └── socket.js # WebSocket 配置 ``` - **功能**: 存储项目的所有配置文件 - **结构**: 按功能模块划分配置文件 - **特性**: 集中管理配置,便于维护和修改 - **加载顺序**: 应用启动时加载 ## 5. 库文件目录结构 (libs/) ``` libs/ ├── chat.js # 聊天相关功能 ├── login.js # 登录相关功能 ├── new_chat.js # 新聊天功能 ├── order.js # 订单相关功能 ├── routine.js # 小程序相关功能 ├── uniApi.js # UniApp API 封装 └── wechat.js # 微信相关功能 ``` - **功能**: 存储通用库文件和功能模块 - **结构**: 按功能划分库文件 - **特性**: 独立于页面代码,便于复用 - **作用**: 提供通用功能和服务 ## 6. 混入目录结构 (mixins/) ``` mixins/ └── color.js # 颜色相关混入 ``` - **功能**: 存储 Vue 混入对象 - **结构**: 按功能划分混入文件 - **特性**: 实现代码复用,避免重复逻辑 - **作用**: 为组件提供共享的方法和数据 ## 7. 状态管理目录结构 (store/) ``` store/ ├── getters.js # 状态获取器 └── index.js # 状态管理入口 ``` - **功能**: 存储 Vuex 状态管理相关文件 - **结构**: 按 Vuex 规范划分文件 - **特性**: 集中管理应用状态,实现组件间通信 - **作用**: 管理全局状态,如用户信息、购物车数据等 ## 8. 工具类目录结构 (utils/) ``` utils/ ├── cache.js # 缓存工具 ├── emoji.js # 表情工具 ├── index.js # 工具类入口 ├── lang.js # 语言工具 ├── request.js # 网络请求工具 ├── theme.js # 主题工具 ├── util.js # 通用工具 └── validate.js # 验证工具 ``` - **功能**: 存储通用工具类 - **结构**: 按功能划分工具文件 - **特性**: 提供通用功能,便于复用 - **作用**: 处理缓存、网络请求、验证等通用操作 ## 9. 页面目录结构 ### 9.1 页面配置 (pages.json) ```json { "pages": [ { "path": "pages/index/index", "style": { "navigationBarTitleText": "首页" } }, { "path": "pages/user/index", "style": { "navigationBarTitleText": "个人中心" } } ], "subPackages": [ { "root": "pages/order", "pages": [ { "path": "index", "style": { "navigationBarTitleText": "订单列表" } } ] } ] } ``` - **功能**: 配置页面路由、导航栏样式等 - **结构**: 按页面层级配置 - **特性**: 支持分包加载,优化应用体积 - **作用**: 定义应用的页面结构和导航样式 ## 10. 应用配置文件 ### 10.1 manifest.json ```json { "name": "CRMEB商城", "appid": "__UNI__APPID__", "description": "CRMEB商城移动端", "versionName": "1.0.0", "versionCode": "100", "transformPx": true, "uniStatistics": { "enable": true }, "app-plus": { "usingComponents": true, "nvueStyleCompiler": "uni-app" }, "mp-weixin": { "appid": "wx_appid", "setting": { "urlCheck": false }, "usingComponents": true } } ``` - **功能**: 配置应用的基本信息、平台配置等 - **结构**: 按平台划分配置 - **特性**: 支持多平台配置,如微信小程序、App 等 - **作用**: 定义应用的全局配置信息 ### 10.2 package.json ```json { "name": "crmeb-uni-app", "version": "1.0.0", "description": "CRMEB商城移动端", "main": "main.js", "scripts": { "dev": "npm run dev:mp-weixin", "dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch", "build": "npm run build:mp-weixin", "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build" }, "dependencies": { "vue": "^2.6.11", "vuex": "^3.4.0" } } ``` - **功能**: 配置项目的依赖、脚本等 - **结构**: 标准 npm 配置格式 - **特性**: 管理项目依赖,定义构建脚本 - **作用**: 管理项目的依赖和构建流程 ## 11. 目录结构最佳实践 ### 11.1 命名规范 - **目录名**: 小写字母,单词之间用下划线分隔 - **文件名**: 小写字母,单词之间用下划线分隔 - **组件名**: 使用 PascalCase 命名风格 - **方法名**: 使用 camelCase 命名风格 - **变量名**: 使用 camelCase 命名风格 ### 11.2 组织原则 - **模块化**: 按功能模块组织目录结构 - **分层架构**: 遵循 Vue 组件化开发架构 - **单一职责**: 每个目录和文件只负责一个功能 - **可扩展性**: 便于添加新功能和模块 - **易维护性**: 便于理解和维护 ### 11.3 开发建议 - **遵循 UniApp 规范**: 遵循 UniApp 官方目录结构规范 - **合理划分模块**: 根据业务功能合理划分模块 - **避免目录过深**: 目录层级不宜过深,一般不超过 4 层 - **保持目录整洁**: 及时清理无用文件和目录 - **文档化**: 为重要目录添加说明文档 ## 12. 常见问题 ### 12.1 目录权限问题 - **问题**: 某些目录没有读写权限 - **解决方案**: 确保项目目录有正确的读写权限 ### 12.2 页面路由配置问题 - **问题**: 新增页面后无法访问 - **解决方案**: 在 pages.json 中添加页面路由配置 ### 12.3 分包加载问题 - **问题**: 应用体积过大,无法上传到小程序平台 - **解决方案**: 使用分包加载,将页面划分到不同的分包中 ### 12.4 目录结构混乱 - **问题**: 目录结构不清晰,难以维护 - **解决方案**: 重新组织目录结构,遵循模块化原则 ## 13. 参考资源 - [UniApp 官方文档](https://uniapp.dcloud.io/) - [Vue 官方文档](https://cn.vuejs.org/) - [Vuex 官方文档](https://vuex.vuejs.org/zh/) - [微信小程序开发文档](https://developers.weixin.qq.com/miniprogram/dev/framework/) ## 14. 总结 本文档描述了 CRMEB 项目中 UniApp 移动端的目录结构,包括各目录的功能、文件组织方式等。遵循本文档的目录结构规范,可以提高项目的可维护性和可扩展性,便于团队协作开发。 随着业务的发展和技术的演进,目录结构也可能需要不断优化和调整,以适应新的业务需求和技术挑战。 --- ### .Trae/Documents/生成Git提交规范技能文件 (.trae/documents/生成Git提交规范技能文件.md) # 生成Git提交规范技能文件 ## 目标 创建一个新的技能文件,用于规范git提交信息格式,确保不同目录下的文件提交时都能添加正确的前缀说明。 ## 步骤 ### 1. 创建技能目录 - 在 `.trae/skills/` 目录下创建 `git-commit/` 子目录 ### 2. 生成SKILL.md文件 创建符合格式要求的SKILL.md文件,包含以下内容: #### 2.1 基本信息 - 技能名称:Git提交规范 - 描述:规范git提交信息格式,确保不同目录下的文件提交时添加正确的前缀 #### 2.2 自动触发说明 - 触发条件:当浏览或操作git相关文件时自动调用 - 适用场景:git提交操作前的提示和规范检查 #### 2.3 核心内容 - 提交信息格式规范 - 不同目录的提交前缀说明 - 提交信息示例 - 最佳实践 #### 2.4 提交前缀规则 - **crmeb目录**:提交时添加前缀 `【程序目录】` - **docker-compose目录**:提交时添加前缀 `【DOCKER】` - **dev-docs目录**:提交时添加前缀 `【开发文档】` - **template目录**:提交时添加前缀 `【前端文件】` #### 2.5 参考资源 - Git官方文档 - 常用git命令 - 提交信息规范指南 ### 3. 验证文件结构 确保文件创建在正确的位置,格式符合技能文件的标准规范。 --- ### .Trae/Rules/Project Rules (.trae/rules/project_rules.md) # CRMEB 项目专属 Chat 规则 ## 1. 项目概述 - **名称**: CRMEB 开源商城系统(PHP版) - **技术栈**: ThinkPHP 6 + ElementUI + UniApp - **版本**: 5.6.4 - **许可证**: Apache-2.0 ## 2. 代码风格规范 ### 2.1 PHP 规范 - 遵循 PSR-2 命名规范 - 使用 Restful 接口设计 - 代码分层清晰,注释简洁 - 类名 PascalCase,方法/变量 camelCase - 常量全大写,下划线分隔 - 4空格缩进,禁止制表符 ### 2.2 Vue 规范 - 组件名 PascalCase - 方法/变量 camelCase - 模板使用 kebab-case - 遵循 Vue 官方风格指南 ### 2.3 数据库规范 - 表名小写下划线分隔 - 主键统一命名为 `id` - 外键格式 `表名_id` - 时间字段 `create_time`/`update_time` - 状态字段 `status`,默认值 0 ## 3. 技术选择限制 - **后端**: ThinkPHP 6.x(禁止升级到 7.x) - **前端**: Vue 2.x + ElementUI(Admin)、UniApp(移动端)、Nuxt(PC) - **数据库**: MySQL 5.7~8.0(InnoDB) - **缓存**: Redis(推荐) - **队列**: ThinkPHP 内置队列 - **长连接**: Workerman ## 4. 开发流程规范 ### 4.1 开发环境 - PHP 7.1~7.4 - 开发工具:PHPStorm/VS Code - 版本控制:Git ### 4.2 代码提交 - 提交信息清晰,中文描述 - 格式:`[模块名] 操作描述` - 禁止一次提交多个不相关功能 ### 4.3 二开流程 1. 阅读项目文档和代码注释 2. 使用代码生成工具创建基础功能 3. 遵循系统架构,不破坏原有结构 4. 使用系统事件扩展功能 5. 测试通过后提交 ## 5. 安全规范 - 操作必须记录系统日志 - 敏感数据加密存储 - 禁止直接拼接 SQL,使用参数绑定 - 验证用户输入,防止 XSS/CSRF 攻击 - 使用内置权限管理系统,禁止硬编码权限 - 合理使用缓存,减少数据库查询 - 高并发场景使用队列处理 ## 6. 部署规范 ### 6.1 运行环境 - 操作系统:Linux/Windows - Web 服务器:Nginx/Apache/IIS - PHP 扩展:fileinfo(可选)、redis(可选) - 禁用危险函数:`proc_open`、`pcntl_signal` 等 ### 6.2 启动命令 - 消息队列:`php think queue:listen --queue`(Supervisor 管理) - 长连接:`sudo -u www php think workerman start --d` - 定时任务:`php think timer start --d` ## 7. 常用开发命令 - 代码生成:`php think crmeb:build` - 数据库迁移:`php think migrate:run` - 查看路由:`php think route:list` - 清除缓存:`php think clear` ## 8. 文档与支持 - 官方文档:https://doc.crmeb.com/single_open - 技术社区:https://www.crmeb.com/ask/thread/list/147 ## 9. 注意事项 - 确保代码兼容 PHP 7.1~7.4 - 前端兼容主流浏览器和移动端系统 - 避免复杂 SQL 关联查询 - 大数组分批处理 - 保持代码简洁,注释适当 - 遵循单一职责原则 ## 10. 违规处理 - 违反规范的提交将被拒绝 - 影响系统稳定性的代码将被回滚 - 多次违规者禁止提交代码 --- 以上规则适用于 CRMEB 项目所有开发人员,确保代码一致性、可维护性和安全性。 --- ### .Trae/Skills/Admin Element/References/Api Flow (.trae/skills/admin-element/references/api_flow.md) # Admin-Element 接口请求流程文档 ## 1 API 请求流程概述 Admin-Element 项目的 API 请求流程遵循以下步骤: 1. **接口定义**: 在 `src/api/` 目录下按模块定义 API 接口 2. **请求封装**: 使用 `axios` 封装网络请求,添加拦截器 3. **接口调用**: 在组件或业务逻辑中调用 API 接口 4. **响应处理**: 统一处理 API 响应,包括成功和失败情况 5. **错误处理**: 统一处理网络错误、业务错误等异常情况 6. **数据管理**: 将获取的数据存储到状态管理或组件中 ## 2 网络请求封装 ### 2.1 axios 实例创建 在 `src/utils/request.js` 中创建 axios 实例并配置: ```javascript import axios from 'axios' import { Message, Loading } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' // 创建 axios 实例 const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // API 基础路径 timeout: 10000, // 请求超时时间 headers: { 'Content-Type': 'application/json;charset=utf-8' } }) ``` ### 2.2 请求拦截器 ```javascript // 请求拦截器 service.interceptors.request.use( config => { // 显示加载动画 if (config.loading !== false) { store.dispatch('app/showLoading') } // 自动添加 token if (store.getters.token) { config.headers['Authorization'] = `Bearer ${getToken()}` } return config }, error => { // 隐藏加载动画 store.dispatch('app/hideLoading') console.error('请求错误:', error) return Promise.reject(error) } ) ``` ### 2.3 响应拦截器 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 3 API 接口定义 ### 3.1 接口文件组织 API 接口按模块组织,存放在 `src/api/` 目录下: ``` src/api/ ├── index.js # API 入口文件 ├── user.js # 用户相关接口 ├── goods.js # 商品相关接口 ├── order.js # 订单相关接口 └── ... # 其他模块接口 ``` ### 3.2 接口定义示例 在 `src/api/user.js` 中定义用户相关接口: ```javascript import request from '@/utils/request' export default { // 登录 login(data) { return request({ url: '/admin/login', method: 'post', data }) }, // 获取用户信息 getUserInfo() { return request({ url: '/admin/user/info', method: 'get' }) }, // 获取用户列表 getUserList(params) { return request({ url: '/admin/user/list', method: 'get', params }) }, // 修改用户信息 updateUser(data) { return request({ url: '/admin/user/update', method: 'put', data }) }, // 删除用户 deleteUser(id) { return request({ url: `/admin/user/delete/${id}`, method: 'delete' }) } } ``` ### 3.3 API 入口文件 在 `src/api/index.js` 中导出所有 API 模块: ```javascript import user from './user' import goods from './goods' import order from './order' // 导出 API 模块 export default { user, goods, order } ``` ## 4 请求和响应处理 ### 4.1 请求参数处理 #### 4.1.1 GET 请求 ```javascript // 带查询参数的 GET 请求 api.user.getUserList({ page: 1, limit: 10, keyword: 'test' }) ``` #### 4.1.2 POST 请求 ```javascript // 带请求体的 POST 请求 api.user.login({ username: 'admin', password: '123456' }) ``` #### 4.1.3 PUT 请求 ```javascript // 带请求体的 PUT 请求 api.user.updateUser({ id: 1, username: 'newadmin', nickname: '新管理员' }) ``` #### 4.1.4 DELETE 请求 ```javascript // 路径参数的 DELETE 请求 api.user.deleteUser(1) ``` ### 4.2 响应数据结构 后端 API 响应数据结构应遵循以下规范: ```javascript { "code": 200, // 状态码,200 表示成功 "message": "操作成功", // 响应消息 "data": { ... } // 响应数据 } ``` ### 4.3 响应处理示例 ```javascript // 在组件中调用 API import api from '@/api' export default { methods: { async fetchUserList() { try { const res = await api.user.getUserList({ page: this.page, limit: this.limit }) // 处理成功响应 this.userList = res.data.list this.total = res.data.total } catch (error) { // 错误已在拦截器中处理,这里可以做额外处理 console.error('获取用户列表失败:', error) } } } } ``` ## 5 错误处理机制 ### 5.1 网络错误 - 网络连接失败 - 请求超时 - 服务器无响应 ### 5.2 业务错误 - 参数错误 (400) - 未授权 (401) - 拒绝访问 (403) - 请求地址不存在 (404) - 服务器内部错误 (500) ### 5.3 业务逻辑错误 - 状态码非 200 的响应 - 业务规则验证失败 ### 5.4 错误处理最佳实践 1. **统一错误处理**: 在响应拦截器中统一处理错误 2. **友好的错误提示**: 向用户显示清晰的错误消息 3. **错误日志记录**: 记录错误信息,便于排查问题 4. **特殊错误处理**: 对 token 过期等特殊情况进行处理 5. **降级处理**: 网络错误时提供合理的降级方案 ## 6 接口调用最佳实践 ### 6.1 使用 async/await ```javascript async fetchData() { try { const res = await api.goods.getGoodsList(this.queryParams) this.goodsList = res.data.list this.total = res.data.total } catch (error) { // 错误处理 } } ``` ### 6.2 加载状态管理 ```javascript export default { data() { return { loading: false, goodsList: [] } }, methods: { async fetchData() { this.loading = true try { const res = await api.goods.getGoodsList(this.queryParams) this.goodsList = res.data.list } catch (error) { // 错误处理 } finally { this.loading = false } } } } ``` ### 6.3 防抖和节流 对于频繁触发的请求,使用防抖或节流优化: ```javascript import { debounce } from 'lodash' export default { methods: { // 使用防抖优化搜索请求 search: debounce(async function(query) { try { const res = await api.goods.searchGoods({ keyword: query }) this.searchResults = res.data } catch (error) { // 错误处理 } }, 300) } } ``` ### 6.4 请求取消 对于可能重复触发的请求,使用取消令牌避免重复请求: ```javascript import axios from 'axios' export default { data() { return { cancelToken: null } }, methods: { async fetchData() { // 取消之前的请求 if (this.cancelToken) { this.cancelToken.cancel('取消重复请求') } // 创建新的取消令牌 this.cancelToken = axios.CancelToken.source() try { const res = await api.goods.getGoodsList({ page: this.page, limit: this.limit }, { cancelToken: this.cancelToken.token }) this.goodsList = res.data.list } catch (error) { if (axios.isCancel(error)) { console.log('请求已取消:', error.message) } else { // 错误处理 } } } } } ``` ## 7 接口安全 ### 7.1 认证与授权 - 使用 JWT 令牌进行身份认证 - 请求头中携带 Authorization 字段 - 定期刷新令牌,避免过期 ### 7.2 数据加密 - 敏感数据传输加密 - 密码等敏感信息使用 HTTPS 传输 ### 7.3 防止 CSRF 攻击 - 使用 CSRF Token - 验证请求来源 ### 7.4 接口速率限制 - 后端实现接口速率限制 - 前端避免频繁请求 ## 8 性能优化 ### 8.1 请求合并 对于多个相同类型的请求,合并为一个请求: ```javascript // 批量获取数据 api.goods.batchGetGoodsInfo(ids) ``` ### 8.2 缓存策略 - 对不常变化的数据进行缓存 - 使用 localStorage 或 sessionStorage 缓存数据 ### 8.3 懒加载 - 按需加载数据 - 滚动到底部加载更多数据 ### 8.4 预加载 - 预加载可能需要的数据 - 提升用户体验 ## 9 调试技巧 ### 9.1 接口调试工具 - 使用 Chrome DevTools 的 Network 面板 - 使用 Postman 等 API 调试工具 ### 9.2 日志记录 - 在开发环境下打印详细的请求和响应信息 - 在生产环境下只记录错误信息 ### 9.3 模拟数据 - 使用 Mock 数据进行前端开发 - 减少对后端接口的依赖 ## 10 总结 Admin-Element 项目的 API 请求流程采用了统一的封装和处理机制,通过 axios 拦截器实现了请求和响应的统一处理,提高了代码的可维护性和可扩展性。开发者应遵循接口定义规范和最佳实践,确保 API 调用的安全性、可靠性和性能。 --- ### .Trae/Skills/Admin Element/References/Code Style (.trae/skills/admin-element/references/code_style.md) # 管理端前端代码规范文档 ## 1. 概述 本文档描述了 CRMEB 项目中管理端前端的代码规范,包括命名规范、代码风格、文件结构、组件开发等方面的规范,旨在统一代码风格,提高代码质量和可维护性。 ## 2. 命名规范 ### 2.1 目录命名 - **目录名**: 小写字母,单词之间用连字符分隔 - **示例**: `components/common/`、`pages/user-management/`、`utils/` - **规范**: 简洁明了,反映目录的功能 ### 2.2 文件命名 - **组件文件**: 大写字母开头的 PascalCase 命名风格 - **示例**: `Button.vue`、`UserList.vue`、`Navbar.vue` - **页面文件**: 小写字母,单词之间用连字符分隔 - **示例**: `login.vue`、`user-list.vue`、`dashboard.vue` - **JS 文件**: 小写字母,单词之间用连字符分隔 - **示例**: `api.js`、`request.js`、`util.js` - **CSS/SCSS 文件**: 小写字母,单词之间用连字符分隔 - **示例**: `common.scss`、`theme.scss`、`variables.scss` ### 2.3 变量命名 - **普通变量**: 驼峰命名法 - **示例**: `userInfo`、`goodsList`、`isLoading` - **常量**: 全大写,单词之间用下划线分隔 - **示例**: `BASE_URL`、`MAX_COUNT`、`DEFAULT_PAGE_SIZE` - **布尔变量**: 以 `is` 开头的驼峰命名法 - **示例**: `isShow`、`isLoading`、`isLogin` - **数组变量**: 以复数形式命名 - **示例**: `users`、`goods`、`orders` - **对象变量**: 以单数形式命名 - **示例**: `user`、`good`、`order` ### 2.4 函数命名 - **函数名**: 驼峰命名法,动词开头 - **示例**: `getUserInfo`、`submitForm`、`handleClick` - **方法名**: 驼峰命名法 - **示例**: `data`、`methods`、`computed`、`watch` - **生命周期函数**: 按照 Vue 规范命名 - **示例**: `created`、`mounted`、`beforeDestroy` - **事件处理函数**: 以 `handle` 开头 - **示例**: `handleSubmit`、`handleClick`、`handleChange` ### 2.5 组件命名 - **组件名**: PascalCase 命名风格 - **示例**: `Button`、`UserList`、`Navbar` - **组件标签**: 小写字母,单词之间用连字符分隔 - **示例**: ``、``、`` - **组件文件名**: 与组件名一致,PascalCase 命名 - **示例**: `Button.vue`、`UserList.vue`、`Navbar.vue` ### 2.6 其他命名 - **路由命名**: 小写字母,单词之间用连字符分隔 - **示例**: `/login`、`/user/list`、`/dashboard` - **CSS 类名**: 小写字母,单词之间用连字符分隔 - **示例**: `.user-info`、`.goods-list`、`.btn-primary` - **ID 命名**: 小写字母,单词之间用连字符分隔 - **示例**: `#app`、`#header`、`#footer` - **Vuex 模块命名**: 小写字母,单词之间用连字符分隔 - **示例**: `user`、`goods`、`orders` ## 3. 代码风格 ### 3.1 缩进 - **缩进方式**: 4 个空格 - **示例**: ```vue ``` ### 3.2 换行 - **标签换行**: 多个属性的标签应该换行 - **示例**: ```vue 提交 ``` - **代码块换行**: 逻辑代码块应该换行 - **示例**: ```javascript if (condition) { // 代码块 } else { // 代码块 } ``` ### 3.3 空格 - **运算符空格**: 运算符两侧应该有空格 - **示例**: `a + b`、`x = y`、`i < 10` - **逗号空格**: 逗号后面应该有空格 - **示例**: `[1, 2, 3]`、`{ name: '张三', age: 18 }` - **括号空格**: 括号内侧不应该有空格 - **示例**: `if (condition)`、`function (param)` - **冒号空格**: 对象字面量中冒号后面应该有空格 - **示例**: `{ name: '张三', age: 18 }` ### 3.4 注释 - **单行注释**: 使用 `//` 注释 - **示例**: `// 这是单行注释` - **多行注释**: 使用 `/* */` 注释 - **示例**: ```javascript /* * 这是多行注释 * 第二行 */ ``` - **文档注释**: 使用 JSDoc 风格的注释 - **示例**: ```javascript /** * 获取用户信息 * @param {number} id - 用户ID * @returns {Promise} 用户信息 */ async function getUserInfo(id) { // 代码 } ``` - **组件注释**: 组件使用文档注释 - **示例**: ```vue /** * 用户列表组件 * @props {Array} users - 用户列表数据 * @props {Boolean} loading - 是否加载中 * @events {Function} select - 选择用户时触发 */ ``` ### 3.5 引号 - **字符串**: 使用单引号 `''` - **示例**: `const name = '张三'`、`Hello` - **模板字符串**: 使用反引号 `` ` `` - **示例**: `` const url = `${baseUrl}/api/user` `` - **HTML 属性**: 使用双引号 `""` - **示例**: `
`、`` ### 3.6 分号 - **语句结束**: 每个语句结束都应该加分号 - **示例**: `const name = '张三';`、`function() {};` ### 3.7 空行 - **代码块之间**: 代码块之间应该有空行 - **示例**: ```javascript function first() { // 代码 } function second() { // 代码 } ``` - **逻辑块之间**: 逻辑块之间应该有空行 - **示例**: ```javascript if (condition) { // 代码 } while (loop) { // 代码 } ``` ## 4. 文件结构 ### 4.1 组件文件结构 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 4.2 页面文件结构 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 4.3 JS 文件结构 ```javascript // 导入依赖 import axios from 'axios'; import { Message } from 'element-ui'; // 常量定义 const BASE_URL = process.env.VUE_APP_API_BASE_URL; const TIMEOUT = 10000; // 创建 axios 实例 const service = axios.create({ baseURL: BASE_URL, timeout: TIMEOUT }); // 请求拦截器 service.interceptors.request.use( config => { // 添加 token const token = localStorage.getItem('token'); if (token) { config.headers['Authorization'] = `Bearer ${token}`; } return config; }, error => { console.error('请求错误:', error); return Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( response => { const { data } = response; if (data.code !== 200) { Message.error(data.message || '请求失败'); return Promise.reject(data); } return data; }, error => { console.error('响应错误:', error); Message.error('网络错误,请稍后重试'); return Promise.reject(error); } ); // 工具函数 function formatDate(date) { const d = new Date(date); return d.toLocaleString(); } function deepClone(obj) { return JSON.parse(JSON.stringify(obj)); } // 导出 export { service, formatDate, deepClone }; // 默认导出 export default service; ``` ## 5. 组件开发规范 ### 5.1 组件设计 - **单一职责**: 每个组件只负责一个功能 - **可复用性**: 设计通用的、可复用的组件 - **可配置性**: 通过 props 提供配置选项 - **事件通信**: 通过事件与父组件通信 - **插槽支持**: 提供插槽,增强组件灵活性 ### 5.2 组件使用 - **组件导入**: 使用 import 导入组件 - **示例**: `import Button from '@/components/Button.vue'` - **组件注册**: 在 components 中注册组件 - **示例**: ```javascript components: { Button } ``` - **组件使用**: 使用组件标签 - **示例**: `` - **组件传值**: 通过 props 传递数据 - **示例**: `` - **事件监听**: 监听组件事件 - **示例**: `` ### 5.3 组件通信 - **props 向下传递**: 父组件通过 props 向子组件传递数据 - **events 向上传递**: 子组件通过 events 向父组件传递事件 - **refs 引用**: 通过 refs 引用子组件实例 - **provide/inject**: 祖先组件向后代组件传递数据 - **Vuex 全局状态**: 使用 Vuex 管理全局状态 - **EventBus**: 组件间事件总线 ### 5.4 组件生命周期 - **created**: 初始化数据,发送请求 - **mounted**: 操作 DOM,初始化第三方库 - **beforeUpdate**: 更新前的准备工作 - **updated**: 数据更新后的操作 - **beforeDestroy**: 清理定时器,取消订阅 - **destroyed**: 组件销毁后的清理工作 ### 5.5 组件命名规范 - **组件名**: PascalCase 命名风格 - **组件文件名**: 与组件名一致 - **组件目录**: 按功能分类存放 - **组件前缀**: 通用组件使用统一前缀 ## 6. 页面开发规范 ### 6.1 页面结构 - **模板结构**: 清晰明了,层次分明 - **脚本结构**: 按照 Vue 规范组织代码 - **样式结构**: 模块化,可维护 - **布局规范**: 遵循统一的布局规范 ### 6.2 数据管理 - **本地数据**: 使用 data 管理组件内部数据 - **计算数据**: 使用 computed 计算衍生数据 - **监听数据**: 使用 watch 监听数据变化 - **全局数据**: 使用 Vuex 管理全局数据 ### 6.3 路由管理 - **路由配置**: 在 router 目录中配置路由 - **路由跳转**: 使用 router.push、router.replace 等方法 - **路由参数**: 通过 $route.params 获取路由参数 - **路由守卫**: 使用全局/局部路由守卫 ### 6.4 API 调用 - **API 封装**: 统一封装 API 调用 - **异步处理**: 使用 async/await 处理异步请求 - **错误处理**: 使用 try/catch 捕获错误 - **加载状态**: 显示加载状态,提升用户体验 ### 6.5 用户体验 - **响应式设计**: 适配不同屏幕尺寸 - **加载状态**: 显示加载中提示 - **错误提示**: 显示错误信息 - **成功提示**: 显示操作成功提示 - **表单验证**: 实时表单验证 - **防抖节流**: 优化频繁触发的事件 ## 7. 性能优化 ### 7.1 代码优化 - **减少冗余代码**: 避免重复的代码 - **使用计算属性**: 对于复杂的计算,使用 computed - **使用 v-if 和 v-show 合理**: 根据场景选择合适的指令 - **使用 key**: 在 v-for 中使用 key,提高渲染性能 - **避免频繁更新**: 使用防抖和节流 ### 7.2 网络优化 - **合理使用缓存**: 缓存不经常变化的数据 - **减少请求次数**: 合并请求,批量操作 - **使用 CDN**: 静态资源使用 CDN - **压缩传输**: 使用 gzip 压缩传输数据 ### 7.3 构建优化 - **Tree Shaking**: 移除未使用的代码 - **代码分割**: 按路由分割代码 - **懒加载**: 路由懒加载,组件懒加载 - **预加载**: 预加载关键资源 ### 7.4 其他优化 - **减少 DOM 节点**: 简化 DOM 结构 - **优化图片**: 使用合适的图片格式和大小 - **使用虚拟列表**: 对于长列表,使用虚拟列表 - **避免内存泄漏**: 及时清理定时器、事件监听器等 ## 8. 常见问题 ### 8.1 代码风格问题 - **问题**: 代码风格不一致 - **解决方案**: 使用 ESLint 和 Prettier 统一代码风格 ### 8.2 性能问题 - **问题**: 页面加载慢,卡顿 - **解决方案**: 优化代码,减少 DOM 操作,使用虚拟列表等 ### 8.3 兼容性问题 - **问题**: 在不同浏览器上表现不一致 - **解决方案**: 遵循 Web 标准,使用 polyfill ### 8.4 维护性问题 - **问题**: 代码难以维护 - **解决方案**: 模块化开发,添加注释,遵循代码规范 ### 8.5 命名冲突问题 - **问题**: 命名冲突 - **解决方案**: 使用命名空间,避免全局变量 ## 9. 参考资源 - [Vue 官方风格指南](https://v2.vuejs.org/v2/style-guide/) - [Element UI 官方文档](https://element.eleme.io/#/zh-CN) - [ESLint 官方文档](https://eslint.org/docs/user-guide/) - [Prettier 官方文档](https://prettier.io/docs/en/) - [JavaScript 代码规范](https://github.com/airbnb/javascript) - [CSS 代码规范](https://github.com/airbnb/css) ## 10. 总结 本文档描述了 CRMEB 项目中管理端前端的代码规范,包括命名规范、代码风格、文件结构、组件开发等方面的规范。遵循本文档的规范,可以提高代码的可读性、可维护性和可扩展性,确保项目的质量和稳定性。 代码规范是团队协作的基础,建议开发团队成员严格遵循本文档的规范,共同维护一个高质量的代码库。 --- ### .Trae/Skills/Admin Element/References/Deploy (.trae/skills/admin-element/references/deploy.md) # 管理端前端部署文档 ## 1. 概述 本文档描述了 CRMEB 项目中管理端前端的部署流程,包括构建、部署、配置等环节,旨在规范前端部署流程,确保部署过程的顺利进行和系统的稳定运行。 ## 2. 部署环境 ### 2.1 服务器要求 - **操作系统**: Linux (Ubuntu 18.04+、CentOS 7+) - **Web 服务器**: Nginx 1.14+ 或 Apache 2.4+ - **Node.js**: v12.0.0+ (仅构建时需要) - **npm/yarn**: v6.0.0+ (仅构建时需要) - **内存**: 至少 2GB RAM - **CPU**: 至少 2 核 CPU - **磁盘空间**: 至少 20GB 可用空间 ### 2.2 环境准备 - **Web 服务器配置**: 配置虚拟主机,指向前端构建产物目录 - **SSL 证书**: 配置 HTTPS,使用 SSL 证书 - **防火墙**: 开放 80/443 端口 - **域名**: 配置域名解析,指向服务器 IP ## 3. 构建流程 ### 3.1 开发环境构建 - **命令**: `npm run dev` - **用途**: 本地开发,启动开发服务器 - **访问地址**: `http://localhost:8080` ### 3.2 测试环境构建 - **命令**: `npm run build:test` - **用途**: 测试环境部署 - **构建产物**: `dist/` 目录 ### 3.3 生产环境构建 - **命令**: `npm run build:prod` - **用途**: 生产环境部署 - **构建产物**: `dist/` 目录 ### 3.4 构建优化 - **代码压缩**: 压缩 JS/CSS/HTML 文件 - **资源压缩**: 压缩图片等静态资源 - **Tree Shaking**: 移除未使用的代码 - **代码分割**: 按路由分割代码 - **预加载**: 预加载关键资源 ## 4. 部署方式 ### 4.1 静态部署 #### 4.1.1 Nginx 配置 ```nginx server { listen 80; server_name admin.example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name admin.example.com; # SSL 配置 ssl_certificate /path/to/ssl/cert.pem; ssl_certificate_key /path/to/ssl/key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers on; # 静态文件配置 root /path/to/admin/dist; index index.html; # 路由重写,解决单页应用刷新 404 问题 location / { try_files $uri $uri/ /index.html; } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 30d; add_header Cache-Control "public, max-age=2592000"; } # 日志配置 access_log /var/log/nginx/admin_access.log; error_log /var/log/nginx/admin_error.log; } ``` #### 4.1.2 Apache 配置 ```apache ServerName admin.example.com Redirect permanent / https://admin.example.com/ ServerName admin.example.com # SSL 配置 SSLEngine on SSLCertificateFile /path/to/ssl/cert.pem SSLCertificateKeyFile /path/to/ssl/key.pem # 静态文件配置 DocumentRoot /path/to/admin/dist AllowOverride All Require all granted # 路由重写,解决单页应用刷新 404 问题 RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] # 日志配置 ErrorLog ${APACHE_LOG_DIR}/admin_error.log CustomLog ${APACHE_LOG_DIR}/admin_access.log combined ``` ### 4.2 容器部署 #### 4.2.1 Dockerfile ```dockerfile # 基础镜像 FROM node:12-alpine as build # 设置工作目录 WORKDIR /app # 复制依赖文件 COPY package*.json ./ # 安装依赖 RUN npm install # 复制源代码 COPY . . # 构建生产版本 RUN npm run build:prod # 生产镜像 FROM nginx:1.19-alpine # 复制构建产物 COPY --from=build /app/dist /usr/share/nginx/html # 复制 Nginx 配置 COPY nginx.conf /etc/nginx/conf.d/default.conf # 暴露端口 EXPOSE 80 # 启动 Nginx CMD ["nginx", "-g", "daemon off;"] ``` #### 4.2.2 Docker Compose ```yaml version: '3' services: admin: build: . ports: - "80:80" restart: always volumes: - ./ssl:/etc/nginx/ssl environment: - TZ=Asia/Shanghai ``` #### 4.2.3 部署命令 ```bash # 构建镜像 docker build -t crmeb-admin . # 运行容器 docker run -d --name crmeb-admin -p 80:80 crmeb-admin # 使用 Docker Compose docker-compose up -d ``` ### 4.3 CDN 部署 #### 4.3.1 配置 CDN - **源站设置**: 指向静态文件服务器 - **缓存策略**: 配置静态资源缓存时间 - **HTTPS**: 开启 HTTPS - **HTTP/2**: 开启 HTTP/2 #### 4.3.2 部署流程 1. 构建前端项目 2. 上传构建产物到 CDN 3. 配置 CDN 缓存策略 4. 验证部署结果 ## 5. 配置管理 ### 5.1 环境变量配置 - **开发环境**: `.env.development` - **测试环境**: `.env.test` - **生产环境**: `.env.production` ### 5.2 配置示例 ```env # API 基础地址 VUE_APP_API_BASE_URL=https://api.example.com # 静态资源 CDN 地址 VUE_APP_CDN_BASE_URL=https://cdn.example.com # 应用名称 VUE_APP_TITLE=CRMEB 管理后台 # 构建环境 NODE_ENV=production # 构建版本 VUE_APP_VERSION=1.0.0 ``` ### 5.3 运行时配置 - **API 地址**: 可通过环境变量或配置文件修改 - **主题配置**: 可通过配置文件修改 - **权限配置**: 可通过后端 API 动态获取 ## 6. 部署流程 ### 6.1 手动部署 1. **拉取代码**: `git pull origin master` 2. **安装依赖**: `npm install` 3. **构建项目**: `npm run build:prod` 4. **部署文件**: 将 `dist/` 目录复制到服务器 5. **配置 Web 服务器**: 配置虚拟主机 6. **重启服务**: 重启 Web 服务器 7. **验证部署**: 访问管理端地址 ### 6.2 自动化部署 #### 6.2.1 CI/CD 配置 - **Jenkins**: 配置 Jenkins 任务,实现自动构建和部署 - **GitLab CI**: 配置 `.gitlab-ci.yml`,实现自动构建和部署 - **GitHub Actions**: 配置 `.github/workflows/deploy.yml`,实现自动构建和部署 #### 6.2.2 GitHub Actions 示例 ```yaml name: Deploy Admin Frontend on: push: branches: - master jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: '12' - name: Install dependencies run: npm install - name: Build project run: npm run build:prod - name: Deploy to server uses: easingthemes/ssh-deploy@v2.1.5 env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} ARGS: '-rltgoDzvO --delete' SOURCE: 'dist/' REMOTE_HOST: ${{ secrets.REMOTE_HOST }} REMOTE_USER: ${{ secrets.REMOTE_USER }} REMOTE_PORT: ${{ secrets.REMOTE_PORT }} TARGET: ${{ secrets.REMOTE_TARGET }} - name: Restart Nginx uses: appleboy/ssh-action@master with: host: ${{ secrets.REMOTE_HOST }} username: ${{ secrets.REMOTE_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: ${{ secrets.REMOTE_PORT }} script: sudo systemctl restart nginx ``` ## 7. 监控与维护 ### 7.1 监控 - **访问日志**: 分析 Web 服务器访问日志 - **错误日志**: 监控 Web 服务器错误日志 - **性能监控**: 监控页面加载速度、响应时间 - **可用性监控**: 监控服务可用性,设置告警 ### 7.2 维护 - **定期更新**: 定期更新前端代码,修复漏洞 - **缓存清理**: 定期清理 CDN 缓存 - **日志清理**: 定期清理日志文件 - **备份**: 定期备份构建产物和配置文件 ### 7.3 常见问题 #### 7.3.1 404 问题 - **问题**: 刷新页面出现 404 错误 - **解决方案**: 配置 Web 服务器,将所有请求重定向到 index.html #### 7.3.2 静态资源加载失败 - **问题**: 静态资源(JS/CSS/图片)加载失败 - **解决方案**: 检查静态资源路径,确保 CDN 配置正确 #### 7.3.3 API 调用失败 - **问题**: 前端无法调用后端 API - **解决方案**: 检查 API 地址配置,确保后端服务正常运行 #### 7.3.4 性能问题 - **问题**: 页面加载慢,卡顿 - **解决方案**: 优化前端代码,使用 CDN,启用 HTTP/2 ## 8. 回滚策略 ### 8.1 版本管理 - **版本号**: 遵循语义化版本规范 - **发布记录**: 记录每次发布的版本和变更内容 - **备份**: 备份每次发布的构建产物 ### 8.2 回滚流程 1. **停止服务**: 停止当前版本的服务 2. **恢复备份**: 恢复到上一个稳定版本 3. **重启服务**: 启动恢复后的服务 4. **验证回滚**: 验证服务是否正常运行 ### 8.3 回滚方案 - **手动回滚**: 手动复制备份文件到部署目录 - **自动化回滚**: 通过 CI/CD 工具实现自动回滚 - **容器回滚**: 通过 Docker 镜像版本回滚 ## 9. 安全部署 ### 9.1 HTTPS 配置 - **SSL 证书**: 使用正规 CA 签发的 SSL 证书 - **证书续期**: 定期续期 SSL 证书 - **HTTP 重定向**: 将 HTTP 请求重定向到 HTTPS ### 9.2 安全头部 - **Content-Security-Policy**: 配置内容安全策略 - **X-Content-Type-Options**: 防止 MIME 类型嗅探 - **X-Frame-Options**: 防止点击劫持 - **X-XSS-Protection**: 启用 XSS 过滤 ### 9.3 访问控制 - **IP 白名单**: 限制管理端访问 IP - **登录验证**: 强制登录验证 - **权限控制**: 基于角色的权限控制 - **会话管理**: 安全的会话管理 ### 9.4 漏洞防护 - **依赖扫描**: 定期扫描依赖包漏洞 - **代码审计**: 定期进行代码安全审计 - **渗透测试**: 定期进行渗透测试 ## 10. 最佳实践 ### 10.1 构建优化 - **使用缓存**: 缓存依赖包和构建产物 - **并行构建**: 使用多线程并行构建 - **增量构建**: 只构建变更的文件 - **构建日志**: 保存构建日志,便于排查问题 ### 10.2 部署优化 - **灰度发布**: 采用灰度发布策略 - **蓝绿部署**: 采用蓝绿部署策略 - **滚动部署**: 采用滚动部署策略 - **金丝雀发布**: 采用金丝雀发布策略 ### 10.3 监控优化 - **实时监控**: 实时监控系统运行状态 - **告警机制**: 设置合理的告警阈值 - **日志聚合**: 聚合多服务器日志 - **性能分析**: 定期分析系统性能 ### 10.4 安全优化 - **最小权限**: 遵循最小权限原则 - **定期更新**: 定期更新依赖和系统 - **安全扫描**: 定期进行安全扫描 - **应急响应**: 建立安全应急响应机制 ## 11. 总结 本文档描述了 CRMEB 项目中管理端前端的部署流程,包括构建、部署、配置等环节,以及相关的最佳实践和常见问题解决方案。 遵循本文档的部署流程和规范,可以确保前端部署的顺利进行和系统的稳定运行,同时提高部署效率和系统安全性。 随着项目的发展和技术的演进,部署流程也需要不断优化和调整,以适应新的业务需求和技术挑战。 --- ### .Trae/Skills/Admin Element/References/Development Flow (.trae/skills/admin-element/references/development_flow.md) # 管理端前端开发流程文档 ## 1. 概述 本文档描述了 CRMEB 项目中管理端前端的开发流程,包括需求分析、设计、编码、测试、部署等环节,旨在规范前端开发流程,提高开发效率和代码质量。 ## 2. 开发流程 ### 2.1 需求分析 #### 2.1.1 需求获取 - **需求来源**: 产品经理、业务方、后端开发、测试人员 - **需求形式**: PRD 文档、需求评审会议、邮件、即时通讯工具 - **需求内容**: 功能需求、非功能需求、UI/UX 需求 #### 2.1.2 需求评审 - **评审人员**: 前端开发、后端开发、产品经理、测试人员 - **评审内容**: 需求可行性、技术实现方案、时间评估、风险评估 - **评审输出**: 评审纪要、任务分解、时间计划 #### 2.1.3 需求确认 - **确认内容**: 需求细节、技术方案、交付标准 - **确认形式**: 需求确认邮件、需求确认会议 - **确认输出**: 需求确认文档 ### 2.2 设计阶段 #### 2.2.1 UI 设计 - **设计工具**: Figma、Sketch、Adobe XD - **设计内容**: 页面布局、组件样式、交互设计、色彩方案 - **设计输出**: UI 设计稿、设计规范文档 #### 2.2.2 技术设计 - **设计内容**: 技术选型、架构设计、目录结构、组件设计、API 设计 - **设计输出**: 技术设计文档、架构图、组件设计图 #### 2.2.3 原型设计 - **原型工具**: Axure、Figma、Sketch - **原型内容**: 页面原型、交互原型、流程原型 - **原型输出**: 交互式原型、流程图 ### 2.3 编码实现 #### 2.3.1 环境搭建 - **开发环境**: Node.js、npm/yarn、VS Code、Git - **依赖安装**: `npm install` 或 `yarn install` - **开发工具**: Vue DevTools、Chrome DevTools #### 2.3.2 代码开发 - **开发顺序**: 基础组件 → 页面组件 → 业务逻辑 → 测试 - **开发规范**: 遵循代码规范、命名规范、文档规范 - **代码质量**: 代码可读性、可维护性、可扩展性 #### 2.3.3 代码审查 - **审查人员**: 前端团队成员 - **审查内容**: 代码质量、功能实现、性能优化、安全防护 - **审查工具**: GitLab/GitHub Code Review、ESLint、Prettier ### 2.4 测试验证 #### 2.4.1 单元测试 - **测试工具**: Jest、Vue Test Utils - **测试内容**: 组件测试、工具函数测试、状态管理测试 - **测试覆盖率**: 关键功能测试覆盖率 ≥ 80% #### 2.4.2 功能测试 - **测试人员**: 前端开发、测试人员 - **测试内容**: 功能实现、交互体验、页面布局、响应式设计 - **测试工具**: 浏览器、测试管理工具 #### 2.4.3 性能测试 - **测试工具**: Chrome DevTools、Lighthouse、WebPageTest - **测试内容**: 首屏加载速度、页面渲染性能、内存使用、网络请求 - **测试指标**: FCP、LCP、TTI、CLS、FID #### 2.4.4 兼容性测试 - **测试浏览器**: Chrome、Firefox、Safari、Edge - **测试分辨率**: 1024x768、1366x768、1920x1080 - **测试内容**: 页面显示、功能实现、交互体验 ### 2.5 部署上线 #### 2.5.1 构建打包 - **构建命令**: `npm run build:prod` - **构建产物**: 静态资源文件 - **构建优化**: 代码压缩、资源压缩、Tree Shaking #### 2.5.2 部署配置 - **部署环境**: 测试环境、预发布环境、生产环境 - **部署工具**: Nginx、Apache、CDN - **配置内容**: 服务器配置、域名配置、HTTPS 配置 #### 2.5.3 上线发布 - **发布流程**: 测试环境 → 预发布环境 → 生产环境 - **发布时间**: 非业务高峰期 - **发布监控**: 实时监控系统运行状态 #### 2.5.4 上线后验证 - **验证内容**: 功能验证、性能验证、兼容性验证 - **验证人员**: 前端开发、测试人员、产品经理 - **验证输出**: 上线验证报告 ## 3. 开发规范 ### 3.1 代码规范 - **ESLint 规则**: 遵循 Vue 官方推荐的 ESLint 规则 - **Prettier 配置**: 统一代码格式化规则 - **代码缩进**: 4 空格缩进 - **命名规范**: 组件名 PascalCase,变量/方法名 camelCase,常量全大写 ### 3.2 提交规范 - **提交信息格式**: `[类型] 描述` - **类型**: feat(新功能)、fix(修复)、docs(文档)、style(样式)、refactor(重构)、test(测试)、chore(构建/依赖) - **提交频率**: 小步提交,每个功能或修复一个提交 - **提交内容**: 只提交相关代码,不提交无关文件 ### 3.3 分支规范 - **主分支**: master(生产环境)、develop(开发环境) - **功能分支**: feature/功能名称 - **修复分支**: fix/修复内容 - **发布分支**: release/版本号 - **分支管理**: 定期清理无用分支 ### 3.4 文档规范 - **README.md**: 项目说明、安装说明、开发说明 - **组件文档**: 组件使用说明、Props、Events、Slots - **API 文档**: API 接口说明、请求参数、响应格式 - **开发文档**: 开发流程、编码规范、部署流程 ## 4. 开发工具 ### 4.1 开发环境 - **Node.js**: v12.0.0+ - **npm**: v6.0.0+ 或 **yarn**: v1.22.0+ - **VS Code**: 最新版本 - **Git**: 最新版本 ### 4.2 编辑器插件 - **Vetur**: Vue 开发插件 - **ESLint**: 代码检查插件 - **Prettier**: 代码格式化插件 - **GitLens**: Git 增强插件 - **Debugger for Chrome**: 浏览器调试插件 - **Auto Close Tag**: 自动闭合标签 - **Auto Rename Tag**: 自动重命名标签 ### 4.3 开发工具 - **Vue DevTools**: Vue 开发调试工具 - **Chrome DevTools**: 浏览器调试工具 - **Postman**: API 测试工具 - **Charles**: 网络调试工具 - **Figma/Sketch**: UI 设计工具 - **Zeplin**: 设计协作工具 ### 4.4 构建工具 - **Webpack**: 模块打包工具 - **Babel**: JavaScript 编译器 - **Sass/Less**: CSS 预处理器 - **ESLint**: 代码检查工具 - **Prettier**: 代码格式化工具 ## 5. 常见问题及解决方案 ### 5.1 需求变更 - **问题**: 开发过程中需求发生变更 - **解决方案**: 1. 记录需求变更内容 2. 评估变更影响范围 3. 与产品经理确认变更可行性 4. 调整开发计划和时间评估 5. 通知相关团队成员 ### 5.2 技术难题 - **问题**: 遇到技术难题无法解决 - **解决方案**: 1. 查阅相关文档和资料 2. 寻求团队成员帮助 3. 咨询外部专家 4. 尝试替代方案 5. 记录解决方案,形成知识库 ### 5.3 时间紧张 - **问题**: 开发时间紧张,任务无法按时完成 - **解决方案**: 1. 评估任务优先级 2. 与产品经理沟通,调整需求优先级 3. 寻求团队成员协助 4. 优化开发流程,提高开发效率 5. 加班完成(作为最后手段) ### 5.4 代码冲突 - **问题**: Git 代码冲突 - **解决方案**: 1. 拉取最新代码 2. 手动解决冲突 3. 测试冲突解决后的代码 4. 提交解决冲突后的代码 5. 通知相关团队成员 ### 5.5 线上问题 - **问题**: 线上出现问题 - **解决方案**: 1. 快速定位问题原因 2. 制定解决方案 3. 紧急修复并部署 4. 验证修复效果 5. 分析问题原因,避免类似问题再次发生 ## 6. 最佳实践 ### 6.1 开发前准备 - **需求确认**: 确保需求理解正确 - **技术方案**: 制定详细的技术实现方案 - **环境搭建**: 确保开发环境配置正确 - **依赖安装**: 安装必要的依赖包 ### 6.2 编码实现 - **组件化开发**: 封装可复用组件 - **模块化开发**: 按功能模块组织代码 - **代码复用**: 提取公共逻辑,避免重复代码 - **性能优化**: 考虑代码性能,避免性能瓶颈 - **安全性**: 考虑代码安全性,避免安全漏洞 ### 6.3 测试验证 - **单元测试**: 编写关键功能的单元测试 - **功能测试**: 全面测试功能实现 - **性能测试**: 测试页面性能 - **兼容性测试**: 测试不同浏览器兼容性 - **用户体验测试**: 测试页面交互体验 ### 6.4 部署上线 - **构建优化**: 优化构建产物 - **部署策略**: 采用灰度发布策略 - **监控告警**: 配置系统监控和告警 - **回滚方案**: 准备系统回滚方案 - **上线验证**: 上线后及时验证系统状态 ### 6.5 维护迭代 - **问题跟踪**: 及时跟踪和解决线上问题 - **代码维护**: 定期维护和优化代码 - **文档更新**: 及时更新相关文档 - **技术债务**: 定期清理技术债务 - **知识共享**: 分享开发经验和解决方案 ## 7. 团队协作 ### 7.1 协作模式 - **敏捷开发**: 采用 Scrum 或 Kanban 敏捷开发模式 - **每日站会**: 每日 15 分钟站会,同步开发进度 - **迭代周期**: 2-4 周一个迭代周期 - **迭代回顾**: 迭代结束后进行回顾,总结经验教训 ### 7.2 沟通工具 - **即时通讯**: 企业微信、钉钉、Slack - **项目管理**: Jira、Trello、GitHub Issues - **代码托管**: GitLab、GitHub、Gitee - **文档协作**: 语雀、Confluence、Google Docs ### 7.3 知识共享 - **技术分享**: 定期组织技术分享会议 - **代码审查**: 相互代码审查,分享编码经验 - **问题讨论**: 定期组织问题讨论会议 - **知识库**: 建立团队知识库,积累技术经验 ## 8. 总结 本文档描述了 CRMEB 项目中管理端前端的开发流程,包括需求分析、设计、编码、测试、部署等环节,以及相关的开发规范和最佳实践。 遵循本文档的开发流程和规范,可以提高前端开发效率和代码质量,减少开发过程中的问题和风险,确保项目的顺利进行。 同时,开发流程也需要根据项目的实际情况进行调整和优化,以适应不同项目的需求和特点。 --- ### .Trae/Skills/Admin Element/References/Directory Structure (.trae/skills/admin-element/references/directory_structure.md) # Admin-Element 目录结构文档 ## 1 项目根目录结构 ``` template/ # 前端项目目录 ├── admin-element/ # 管理端前端项目 │ ├── public/ # 静态资源目录 │ │ ├── favicon.ico # 网站图标 │ │ ├── index.html # 入口HTML文件 │ │ └── static/ # 静态资源文件 │ ├── src/ # 源代码目录 │ │ ├── api/ # API接口定义 │ │ ├── assets/ # 静态资源 │ │ ├── components/ # 通用组件 │ │ ├── config/ # 配置文件 │ │ ├── directive/ # 自定义指令 │ │ ├── filters/ # 过滤器 │ │ ├── layout/ # 布局组件 │ │ ├── router/ # 路由配置 │ │ ├── store/ # 状态管理 │ │ ├── styles/ # 样式文件 │ │ ├── utils/ # 工具函数 │ │ ├── views/ # 页面组件 │ │ ├── App.vue # 根组件 │ │ └── main.js # 入口文件 │ ├── tests/ # 测试文件 │ ├── .env.* # 环境变量配置 │ ├── babel.config.js # Babel配置 │ ├── package.json # 项目依赖 │ ├── vue.config.js # Vue配置 │ └── README.md # 项目说明 ``` ## 2 主要目录说明 ### 2.1 public/ 目录 - **favicon.ico**: 网站图标文件 - **index.html**: 应用入口HTML文件,Vue应用将挂载到这个文件中 - **static/**: 静态资源目录,存放不需要经过webpack处理的静态文件 ### 2.2 src/ 目录 #### 2.2.1 api/ 目录 - 定义所有API接口请求 - 按模块组织API文件 - 包含接口调用方法和参数配置 #### 2.2.2 assets/ 目录 - **images/**: 图片资源 - **icons/**: 图标资源 - **styles/**: 全局样式文件 - 其他静态资源文件 #### 2.2.3 components/ 目录 - **base/**: 基础组件 - **business/**: 业务组件 - **common/**: 通用组件 - 可复用的Vue组件 #### 2.2.4 config/ 目录 - **index.js**: 主配置文件 - **router.config.js**: 路由配置 - **menu.config.js**: 菜单配置 - **theme.config.js**: 主题配置 - 其他系统配置文件 #### 2.2.5 directive/ 目录 - 自定义Vue指令 - 如权限控制、表单验证等指令 #### 2.2.6 filters/ 目录 - 自定义Vue过滤器 - 如日期格式化、数字格式化等 #### 2.2.7 layout/ 目录 - **components/**: 布局组件 - **index.vue**: 主布局文件 - **AppMain.vue**: 内容区域组件 - **Navbar.vue**: 导航栏组件 - **Sidebar.vue**: 侧边栏组件 #### 2.2.8 router/ 目录 - **index.js**: 路由配置主文件 - **modules/**: 按模块组织的路由配置 - 路由守卫配置 #### 2.2.9 store/ 目录 - **index.js**: 状态管理主文件 - **modules/**: 按模块组织的状态管理 - **getters.js**: 全局计算属性 #### 2.2.10 styles/ 目录 - **index.scss**: 全局样式入口 - **variables.scss**: 全局变量 - **mixins.scss**: 混合器 - **reset.scss**: 重置样式 #### 2.2.11 utils/ 目录 - **request.js**: 网络请求封装 - **auth.js**: 认证相关工具 - **tools.js**: 通用工具函数 - **storage.js**: 存储工具 #### 2.2.12 views/ 目录 - 按业务模块组织页面组件 - 每个模块一个目录 - 包含页面组件和相关子组件 #### 2.2.13 App.vue - 应用根组件 - 包含全局布局结构 #### 2.2.14 main.js - 应用入口文件 - 初始化Vue实例 - 加载插件和全局配置 ### 2.3 配置文件 #### 2.3.1 package.json - 项目依赖配置 - 脚本命令配置 - 项目信息配置 #### 2.3.2 vue.config.js - Vue CLI配置 - 构建配置 - 代理配置 #### 2.3.3 babel.config.js - Babel转译配置 #### 2.3.4 .env.* - 环境变量配置文件 - **.env.development**: 开发环境 - **.env.production**: 生产环境 - **.env.staging**: 测试环境 ## 3 目录规范 ### 3.1 命名规范 - 目录名使用小写字母,多单词用连字符(-)分隔 - 文件名使用小写字母,多单词用连字符(-)分隔 - 组件名使用 PascalCase 命名法 ### 3.2 目录组织原则 1. **按功能模块组织**: 相关功能的文件放在同一目录 2. **模块化**: 每个模块保持相对独立 3. **可扩展性**: 目录结构应易于扩展和维护 4. **一致性**: 保持目录结构的一致性 ### 3.3 特殊目录处理 - **components/**: 只存放可复用组件 - **views/**: 存放页面级组件 - **api/**: 按模块组织API接口 - **store/modules/**: 按模块组织状态管理 ## 4 最佳实践 ### 4.1 目录使用建议 - 新增业务模块时,在 views/ 下创建对应的目录 - 新增可复用组件时,放在 components/ 下的对应子目录 - 新增API接口时,在 api/ 下按模块组织 - 新增状态管理时,在 store/modules/ 下创建对应模块 ### 4.2 目录结构维护 - 定期清理无用文件和目录 - 保持目录结构的清晰和整洁 - 遵循统一的命名规范 - 文档及时更新,反映目录结构的变化 ## 5 常见问题 ### 5.1 目录权限问题 - 确保目录权限正确,避免构建时出现权限错误 ### 5.2 路径引用问题 - 使用相对路径或别名路径引用文件 - 避免使用绝对路径 ### 5.3 目录结构优化 - 随着项目规模增大,适时调整目录结构 - 保持目录层级合理,避免过深的嵌套 ## 6 总结 Admin-Element 项目采用标准的 Vue + ElementUI 项目结构,通过清晰的目录组织和命名规范,提高了代码的可维护性和可扩展性。开发者应遵循目录结构规范,合理组织代码,确保项目的长期可维护性。 --- ### .Trae/Skills/Dev Docs Generate/SKILL (.trae/skills/dev-docs-generate/SKILL.md) --- name: dev-docs-generate description: 开发文档生成规范,快速生成开发文档,自动放到docs目录下,方便技术快速了解项目,能快速入手开发 --- # CRMEB 项目文档写作规范 ## 0. 自动调用场景 ### 0.1 触发条件 - **目录浏览时**:当浏览文档相关目录时自动调用 - 打开 `dev-docs/` 目录时触发 - 打开 `dev-docs/phpapi/` 目录时触发 - 打开 `dev-docs/admin/` 目录时触发 - 打开 `dev-docs/uniapp/` 目录时触发 - 打开 `dev-docs/nuxt/` 目录时触发 - **文档创建时**:当创建新的 Markdown 文档文件时自动调用 - **文档编辑时**:当编辑现有文档文件时自动调用 - **关键词触发**:当文档内容包含以下关键词时自动调用 - `文档`、`说明`、`指南`、`手册`、`规范` - `API`、`接口`、`部署`、`开发`、`需求` ### 0.2 适用文件类型 - `.md` (Markdown 文件) - `.txt` (文本文件) - `.doc`/`.docx` (Word 文档) - `.pdf` (PDF 文档) ### 0.3 调用优先级 - 当多个技能同时触发时,文档规范技能优先级中等 - 仅在文档相关操作时被触发 - 不影响其他技能的正常使用 ## 1. 文档类型 ### 1.1 技术文档 - **API 文档**:接口设计、参数说明、返回格式 - **开发文档**:架构设计、模块说明、开发流程 - **部署文档**:环境要求、安装步骤、配置说明 - **接口文档**:接口列表、请求参数、返回示例 ### 1.2 业务文档 - **需求文档**:功能描述、业务流程、数据结构 - **测试文档**:测试用例、测试结果、缺陷报告 - **用户手册**:功能介绍、操作指南、常见问题 ## 2. 格式规范 ### 2.1 文件名规范 - 使用小写下划线分隔 - 清晰描述文档内容 - 示例:`api接口文档.md`、`部署指南.md` ### 2.2 标题层级 - 使用 `#` 表示标题层级 - 一级标题:文档主题 - 二级标题:主要章节 - 三级标题:细分内容 - 最多使用四级标题 ### 2.3 文本格式 - 正文使用宋体/无衬线字体,14px - 代码块使用 ``` 包裹,指定语言 - 列表使用 `-` 或 `1.` 表示 - 强调内容使用 `**加粗**` 或 `*斜体*` ### 2.4 代码规范 - 代码块必须指定语言 - 缩进一致,格式清晰 - 关键代码添加注释 - 示例: ```php // 获取用户信息 public function getUserInfo($id) { return $this->where('id', $id)->find(); } ``` ### 2.5 文档存放目录 - 文档保存到 `dev-docs` 目录中 - 后端接口文档存放 `dev-docs/phpapi` 目录中 - 后端前端 ElementUI(Admin)文档存放 `dev-docs/admin` 目录中 - 移动端前端 UniApp(移动端)文档存放 `dev-docs/uniapp` 目录中 - PC 端 Nuxt(PC)文档存放 `dev-docs/nuxt` 目录中 ## 3. 内容要求 ### 3.1 结构清晰 - 引言:文档目的、适用范围 - 主体:详细内容,逻辑连贯 - 结论:总结、后续计划 - 附录:参考资料、术语表 ### 3.2 语言要求 - 使用简洁、准确的语言 - 避免歧义,术语统一 - 中文文档使用规范汉字 - 英文文档语法正确 ### 3.3 内容完整性 - 包含必要的背景信息 - 步骤清晰,可操作 - 提供示例和截图 - 注明版本和更新日期 ### 3.4 可维护性 - 定期更新,保持时效性 - 使用版本控制管理文档 - 注明作者和联系方式 - 便于搜索和导航 ## 4. 文档工具 ### 4.1 编辑工具 - 推荐使用 Markdown 格式 - 支持工具:VS Code、Typora、语雀 - 图片存储:项目内部或图床 ### 4.2 版本管理 - 与代码一同纳入 Git 管理 - 提交信息清晰,说明文档变更 - 定期备份,防止丢失 ## 5. 审核与发布 ### 5.1 审核流程 1. 编写完成后进行自我检查 2. 提交给相关人员审核 3. 根据反馈修改完善 4. 最终确认发布 ### 5.2 发布规范 - 发布前检查格式和内容 - 明确文档版本号 - 通知相关人员文档更新 - 确保文档可访问 ## 6. Markdown 文档模板 ```markdown # 文档标题 ## 1. 引言 ### 1.1 文档目的 - 说明文档的编写目的 ### 1.2 适用范围 - 说明文档的适用范围 ### 1.3 术语定义 - 解释文档中使用的专业术语 ## 2. 主体内容 ### 2.1 功能描述 - 详细描述功能特性 ### 2.2 实现方案 - 说明技术实现方案 ### 2.3 代码示例 ```php // 代码示例 function example() { return true; } ``` ### 2.4 操作步骤 1. 第一步操作 2. 第二步操作 3. 第三步操作 ## 3. 结论 ### 3.1 总结 - 总结文档的主要内容 ### 3.2 后续计划 - 说明后续的工作计划 ## 4. 附录 ### 4.1 参考资料 - 列出参考的文档和资源 ### 4.2 联系方式 - 提供联系人信息 --- **版本**: 1.0 **作者**: 文档作者 **更新日期**: YYYY-MM-DD ``` ## 7. Markdown 语法指南 ### 7.1 标题 ```markdown # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ``` ### 7.2 列表 - 无序列表项 1 - 无序列表项 2 - 嵌套列表项 1. 有序列表项 1 2. 有序列表项 2 ### 7.3 链接和图片 - [链接文本](https://example.com) - ### 7.4 代码块 ```javascript // JavaScript 代码 console.log('Hello World'); ``` ### 7.5 表格 | 表头 1 | 表头 2 | | ------ | ------ | | 单元格 1 | 单元格 2 | | 单元格 3 | 单元格 4 | ### 7.6 引用 > 这是一段引用文本 ## 8. 注意事项 - 避免冗长,重点突出 - 保持格式统一 - 定期更新文档 - 确保内容准确无误 - 便于他人理解和使用 - 生成文档最后说明由AI生成 --- 以上规范适用于 CRMEB 项目所有文档写作,确保文档质量和一致性。 --- ### .Trae/Skills/Git Commit/SKILL (.trae/skills/git-commit/SKILL.md) --- name: Git提交规范 description: 规范git提交信息格式,确保不同目录下的文件提交时添加正确的前缀 --- # Git提交规范 ## 0. 自动触发说明 ### 0.1 触发条件 #### 0.1.1 操作触发 - **文件浏览时**: 当浏览以下目录时自动调用 - 打开 `crmeb/` 目录时触发 - 打开 `docker-compose/` 目录时触发 - 打开 `dev-docs/` 目录时触发 - 打开 `template/` 目录时触发 - **文件操作时**: 当对以下目录的文件进行操作时自动调用 - 修改 `crmeb/` 目录下文件时触发 - 修改 `docker-compose/` 目录下文件时触发 - 修改 `dev-docs/` 目录下文件时触发 - 修改 `template/` 目录下文件时触发 - **Git操作时**: 当执行以下Git命令时自动调用 - `git add` (添加文件到暂存区) - `git commit` (提交更改) - `git push` (推送更改) #### 0.1.2 内容触发 - **关键词触发**: 当文件内容包含以下关键词时自动调用 - Git关键词: `git`、`commit`、`push`、`pull`、`branch` - 提交关键词: `提交`、`更新`、`修复`、`添加`、`删除` - 目录关键词: `crmeb`、`docker-compose`、`docs`、`template` #### 0.1.3 命令触发 - **终端命令触发**: 当执行以下命令时自动调用 - `git` (Git相关命令) - `git commit` (提交命令) - `git add` (添加命令) ### 0.2 适用场景 #### 0.2.1 核心场景 - **代码提交**: 提交代码更改时 - **文件修改**: 修改项目文件时 - **目录操作**: 对项目目录进行操作时 #### 0.2.2 辅助场景 - **代码审查**: 审查代码提交时 - **版本管理**: 管理项目版本时 - **团队协作**: 团队成员协作开发时 ### 0.3 触发机制 #### 0.3.1 调用时机 - **实时触发**: Git命令执行时立即触发 - **延迟触发**: 文件操作后延迟1秒触发 - **批量触发**: 批量文件操作时合并触发 #### 0.3.2 调用频率 - 文件浏览: 最多每10秒触发一次 - 文件操作: 最多每5秒触发一次 - Git命令: 最多每3秒触发一次 #### 0.3.3 调用优先级 - **优先级等级**: 中等优先级 (3/5) - **竞争处理**: 当多个技能同时触发时 - 最高优先级: 系统核心技能 - 高优先级: 代码结构技能 - 中等优先级: Git提交技能、PHP后端技能、前端技能 - 低优先级: 辅助工具技能 ### 0.4 触发后行为 #### 0.4.1 自动分析 - **目录分析**: 分析当前操作的文件所在目录 - **提交信息分析**: 分析提交信息格式是否符合规范 - **前缀检查**: 检查提交信息是否包含正确的目录前缀 #### 0.4.2 自动展示 - **提交规范**: 展示Git提交规范 - **目录前缀**: 展示当前目录对应的提交前缀 - **示例格式**: 展示正确的提交信息格式示例 #### 0.4.3 自动建议 - **前缀建议**: 提供当前目录对应的提交前缀建议 - **格式建议**: 提供提交信息格式建议 - **最佳实践**: 提供Git提交最佳实践建议 ## 1. 提交信息格式规范 ### 1.1 基本格式 ``` [目录前缀] 提交描述 详细说明(可选) ``` ### 1.2 目录前缀规则 | 目录 | 前缀 | 示例 | |------|------|------| | crmeb/ | 【程序目录】 | 【程序目录】修复登录功能bug | | docker-compose/ | 【DOCKER】 | 【DOCKER】更新Docker配置文件 | | dev-docs/ | 【开发文档】 | 【开发文档】完善API接口文档 | | template/ | 【前端文件】 | 【前端文件】优化前端界面样式 | ### 1.3 提交描述规范 - **长度限制**: 不超过50个字符 - **内容要求**: 简洁明了,说明本次提交的主要内容 - **动词使用**: 使用现在时动词,如「添加」、「修复」、「更新」等 - **格式规范**: 首字母大写,结尾不加标点符号 ### 1.4 详细说明规范 - **长度限制**: 不超过200个字符 - **内容要求**: 详细说明本次提交的原因、解决的问题等 - **格式规范**: 每行不超过72个字符,使用空行分隔不同段落 ## 2. 提交信息示例 ### 2.1 crmeb目录示例 ``` 【程序目录】添加用户注册功能 - 实现用户注册接口 - 添加注册参数验证 - 集成短信验证码功能 ``` ### 2.2 docker-compose目录示例 ``` 【DOCKER】优化Docker镜像构建 - 减少镜像体积 - 提高构建速度 - 修复容器启动问题 ``` ### 2.3 docs目录示例 ``` 【开发文档】更新API接口文档 - 补充新接口说明 - 修正参数描述错误 - 添加响应示例 ``` ### 2.4 template目录示例 ``` 【前端文件】优化登录页面样式 - 调整表单布局 - 美化按钮样式 - 优化响应式设计 ``` ## 3. 最佳实践 ### 3.1 提交频率 - **合理拆分**: 每个提交只包含一个功能或修复 - **及时提交**: 完成一个功能或修复后及时提交 - **避免批量**: 避免一次提交大量不相关的更改 ### 3.2 提交信息质量 - **清晰明了**: 提交信息应清晰说明本次更改的内容 - **准确描述**: 提交信息应准确反映代码更改 - **格式规范**: 严格遵循提交信息格式规范 ### 3.3 分支管理 - **主分支**: 保持主分支稳定,只用于发布 - **开发分支**: 在开发分支上进行功能开发 - **特性分支**: 为大型功能创建专门的特性分支 - **修复分支**: 为紧急bug创建专门的修复分支 ### 3.4 代码审查 - **自我审查**: 提交前自我审查代码 - **团队审查**: 重要更改应进行团队代码审查 - **审查标准**: 审查代码质量、安全性、性能等 ## 4. 常见问题 ### 4.1 提交信息问题 - **缺少前缀**: 忘记添加目录前缀 - 解决方法: 参考目录前缀规则,添加正确的前缀 - **描述过长**: 提交描述超过50个字符 - 解决方法: 精简描述,突出重点 - **格式不规范**: 提交信息格式不符合规范 - 解决方法: 参考提交信息格式规范,修正格式 ### 4.2 分支管理问题 - **分支混乱**: 分支过多或命名不规范 - 解决方法: 定期清理无用分支,使用规范的分支命名 - **合并冲突**: 分支合并时产生冲突 - 解决方法: 及时同步主分支,减少冲突可能性 ### 4.3 提交频率问题 - **提交过频**: 过于频繁的提交 - 解决方法: 合理组织提交,避免琐碎提交 - **提交过少**: 长时间不提交 - 解决方法: 及时提交更改,避免代码丢失 ## 5. 常用Git命令 ### 5.1 基本命令 - **git status**: 查看当前状态 - **git add **: 添加文件到暂存区 - **git commit -m "[前缀] 描述"**: 提交更改 - **git push**: 推送更改到远程仓库 - **git pull**: 从远程仓库拉取更改 ### 5.2 分支命令 - **git branch**: 查看分支 - **git checkout **: 切换分支 - **git checkout -b **: 创建并切换分支 - **git merge **: 合并分支 ### 5.3 历史命令 - **git log**: 查看提交历史 - **git show **: 查看提交详情 - **git diff**: 查看更改内容 ## 6. 参考资源 ### 6.1 官方文档 - [Git官方文档](https://git-scm.com/doc) - [GitHub Git教程](https://guides.github.com/introduction/git-handbook/) ### 6.2 学习资源 - [Pro Git](https://git-scm.com/book/zh/v2) - [Git分支管理策略](https://nvie.com/posts/a-successful-git-branching-model/) - [提交信息规范](https://chris.beams.io/posts/git-commit/) ### 6.3 工具推荐 - **Git GUI**: GitHub Desktop、SourceTree - **Git客户端**: GitKraken、Tower - **代码托管**: GitHub、GitLab、Gitee ### 6.4 其他资源 - Git工作流最佳实践 - 团队Git使用规范 - 代码审查流程指南 --- ### .Trae/Skills/Php Api/References/Api Flow (.trae/skills/php-api/references/api_flow.md) # 接口请求文档 ## 1. 概述 本文档描述了 CRMEB 项目中 API 接口请求的流程、规范、参数设计和响应格式等,旨在统一 API 请求格式,提高 API 的一致性和可维护性。 ## 2. 接口请求流程 ### 2.1 基本流程 1. **客户端发起请求**: 客户端通过 HTTP/HTTPS 协议向服务器发送请求 2. **请求到达服务器**: 请求经过网络传输到达服务器 3. **请求解析**: 服务器解析请求,包括请求方法、路径、参数等 4. **认证授权**: 服务器对请求进行认证和授权 5. **业务处理**: 服务器执行相应的业务逻辑 6. **生成响应**: 服务器生成响应数据 7. **返回响应**: 服务器将响应返回给客户端 8. **客户端处理响应**: 客户端处理服务器返回的响应 ### 2.2 详细流程 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 客户端 │ │ 中间件 │ │ 控制器 │ │ 1. 发起请求 │────▶│ 2. 认证授权 │────▶│ 3. 业务处理 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ 服务层 │ │ 4. 执行逻辑 │ └─────────────────┘ │ ▼ ┌─────────────────┐ │ 数据层 │ │ 5. 数据操作 │ └─────────────────┘ │ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 客户端 │ │ 中间件 │ │ 控制器 │ │ 8. 处理响应 │◀────│ 7. 响应处理 │◀────│ 6. 生成响应 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ ``` ## 3. 请求方法 ### 3.1 HTTP 方法 | 方法 | 描述 | 幂等性 | 安全性 | |------|------|--------|--------| | GET | 获取资源 | 是 | 是 | | POST | 创建资源 | 否 | 否 | | PUT | 更新资源 | 是 | 否 | | DELETE | 删除资源 | 是 | 否 | | PATCH | 部分更新资源 | 否 | 否 | | OPTIONS | 获取资源的可用操作 | 是 | 是 | | HEAD | 获取资源的元数据 | 是 | 是 | ### 3.2 方法使用规范 - **GET**: 用于获取资源,不应修改资源状态 - **POST**: 用于创建新资源 - **PUT**: 用于更新整个资源,应包含资源的完整表示 - **DELETE**: 用于删除资源 - **PATCH**: 用于部分更新资源,只包含需要更新的字段 - **OPTIONS**: 用于获取资源支持的 HTTP 方法 - **HEAD**: 用于获取资源的元数据,如 Content-Length、Last-Modified 等 ## 4. 请求头 ### 4.1 通用请求头 | 请求头 | 描述 | 示例 | |-------|------|------| | Accept | 客户端可接受的响应内容类型 | application/json | | Accept-Encoding | 客户端可接受的编码方式 | gzip, deflate | | Content-Type | 请求体的内容类型 | application/json | | Authorization | 认证信息 | Bearer {token} | | User-Agent | 客户端标识 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 | | X-Requested-With | 请求类型 | XMLHttpRequest | | X-Token | 认证令牌(自定义) | your_token_here | ### 4.2 自定义请求头 自定义请求头应以 `X-` 为前缀,如 `X-Token`、`X-Request-ID` 等。 ## 5. 请求参数 ### 5.1 参数位置 | 位置 | 适用场景 | 示例 | |------|----------|------| | URL 路径 | 资源标识 | /api/v1/user/1 | | 查询字符串 | 过滤、排序、分页 | /api/v1/user?page=1&limit=10&sort=create_time&order=desc | | 请求体 | 复杂数据、创建/更新资源 | {"username": "test", "password": "123456"} | | 请求头 | 认证信息、元数据 | Authorization: Bearer {token} | | Cookie | 会话信息 | PHPSESSID=your_session_id | ### 5.2 参数命名规范 - **命名风格**: 使用 camelCase 命名风格,如 `userName` - **语义化**: 参数名应具有明确的语义,如 `page`、`limit`、`sort` - **简洁性**: 参数名应简洁明了,避免过长 - **一致性**: 相同类型的参数在不同接口中应保持一致 ### 5.3 常用参数 | 参数名 | 类型 | 描述 | 示例 | |-------|------|------|------| | page | int | 页码,默认 1 | page=1 | | limit | int | 每页数量,默认 10 | limit=20 | | sort | string | 排序字段 | sort=create_time | | order | string | 排序方式,asc 或 desc | order=desc | | keyword | string | 搜索关键词 | keyword=test | | status | int | 状态过滤 | status=1 | | start_time | string | 开始时间 | start_time=2024-01-01 | | end_time | string | 结束时间 | end_time=2024-01-31 | ## 6. 请求体 ### 6.1 内容类型 | 内容类型 | 描述 | 示例 | |---------|------|------| | application/json | JSON 格式,最常用 | {"username": "test", "password": "123456"} | | application/x-www-form-urlencoded | 表单格式 | username=test&password=123456 | | multipart/form-data | 文件上传 | 包含文件和表单字段 | | text/plain | 纯文本 | 简单的文本数据 | | application/xml | XML 格式 | test123456 | ### 6.2 JSON 请求体规范 - **使用 camelCase 命名**: 字段名使用 camelCase 命名风格 - **明确的数据类型**: 使用适当的数据类型,如字符串、数字、布尔值、数组、对象 - **避免 null 值**: 非必要字段不应包含 null 值 - **嵌套结构**: 合理使用嵌套结构,避免过深的嵌套 - **数组格式**: 数组元素类型应一致 示例: ```json { "username": "test", "password": "123456", "nickname": "测试用户", "age": 18, "gender": 1, "tags": ["tag1", "tag2"], "address": { "province": "北京", "city": "北京", "district": "朝阳区" } } ``` ## 7. 响应格式 ### 7.1 基本响应格式 所有 API 响应应使用统一的 JSON 格式,包含 `status`、`msg` 和可选的 `data` 字段。系统实际调用方式为 `app('json')->success()`。 #### 7.1.1 调用示例 ```php // 基本成功响应 return app('json')->success('操作成功', ['id' => 1, 'username' => 'test']); // 只返回数据,不指定消息 return app('json')->success(['id' => 1, 'username' => 'test']); // 使用系统内置成功码 return app('json')->success(100000); // 100000 是 "保存成功" 对应的系统内置成功码 ``` #### 7.1.2 响应格式 ```json { "status": 200, "msg": "操作成功", "data": { "id": 1, "username": "test", "nickname": "测试用户" } } ``` ### 7.2 分页响应格式 分页响应应包含 `total`、`page`、`limit` 和 `list` 字段,系统实际调用方式为 `app('json')->success()`。 #### 7.2.1 调用示例 ```php // 分页数据响应 $pageData = [ 'total' => 100, 'page' => 1, 'limit' => 10, 'list' => [ ['id' => 1, 'username' => 'test1', 'nickname' => '测试用户1'], ['id' => 2, 'username' => 'test2', 'nickname' => '测试用户2'] ] ]; return app('json')->success('获取列表成功', $pageData); ``` #### 7.2.2 响应格式 ```json { "status": 200, "msg": "获取列表成功", "data": { "total": 100, "page": 1, "limit": 10, "list": [ { "id": 1, "username": "test1", "nickname": "测试用户1" }, { "id": 2, "username": "test2", "nickname": "测试用户2" } ] } } ``` ### 7.3 错误响应格式 系统使用统一的错误响应格式,所有错误响应通过 `app('json')->fail()` 方法返回。`fail()` 方法支持两种参数类型: - **错误码**(推荐):系统内置的数字错误码,如 `410025` - **错误消息**:直接的字符串错误信息 #### 7.3.1 统一响应格式 无论使用哪种参数类型,系统都会返回统一的 JSON 格式,包含 `status`、`msg` 和可选的 `data` 字段。当使用错误码时,响应中还会包含 `code` 字段。 ```json { "status": 400, "msg": "账号或密码错误", "code": 410025, "data": null } ``` #### 7.3.2 调用示例 ```php // 推荐:使用系统内置错误码 return app('json')->fail(410025); // 不推荐:直接使用错误消息 return app('json')->fail('账号或密码错误'); // 使用错误码并传递额外数据 return app('json')->fail(410025, ['extra' => 'additional data']); // 使用错误码并传递替换参数 return app('json')->fail(410025, [], ['field' => 'username']); ``` #### 7.3.3 最佳实践 - **优先使用错误码**:系统内置错误码经过统一规划,便于维护和国际化 - **避免直接使用字符串**:直接使用字符串错误信息不利于国际化和统一管理 - **传递必要的额外数据**:对于复杂错误,可以在 `data` 字段中提供详细信息 - **使用替换参数**:对于动态错误信息,使用替换参数提高灵活性 ### 7.4 响应码规范 | 响应码范围 | 类型 | 描述 | 示例 | |-----------|------|------|------| | 200 | 成功 | 操作成功 | 200 | | 1000-1999 | 系统级错误 | 系统核心错误 | 1001(参数错误) | | 4000-4999 | 业务级错误 | 具体业务逻辑错误 | 410025(账号或密码错误) | | 400 | 客户端错误 | 请求参数错误 | 400 | | 401 | 认证错误 | 未认证或认证过期 | 401 | | 403 | 权限错误 | 无权限访问 | 403 | | 404 | 资源错误 | 资源不存在 | 404 | | 500 | 服务器错误 | 服务器内部错误 | 500 | ## 8. 错误处理 ### 8.1 错误响应设计 错误响应应遵循以下设计原则: 1. **统一格式**: 所有错误响应使用相同的 JSON 格式 2. **明确的错误码**: 使用唯一的错误码标识不同的错误类型 3. **清晰的错误信息**: 错误信息应简洁明了,便于理解 4. **可选的详细信息**: 对于复杂错误,可以在 `data` 字段中提供详细信息 5. **HTTP 状态码匹配**: 错误码应与 HTTP 状态码匹配 ### 8.2 AI 自动提示系统内置错误码 CRMEB 系统集成了 AI 自动提示功能,当开发者在编写代码时使用 `fail()` 方法返回错误信息时,AI 会自动: 1. **识别错误信息**: 自动识别开发者输入的错误信息字符串 2. **匹配内置错误码**: 在系统内置错误码库中查找匹配的错误码 3. **自动转换**: 在运行时将错误信息自动转换为对应的系统内置错误码 4. **提供建议**: 对于未匹配到的错误信息,提供相似的错误码建议 5. **实时提示**: 在 IDE 中实时显示错误码建议 6. **错误码文档**: 在错误码文档 error_code.md,找到对应的错误码说明 #### 8.2.1 功能示例 ```php // 开发者输入 return $this->fail('登录失败'); // AI 自动提示并替换为 return $this->fail(410019); // 410019 是 "登录失败" 对应的系统内置错误码 ``` #### 8.2.2 工作原理 1. **语言文件解析**: 系统在运行时解析语言文件,构建错误码到错误信息的映射表 2. **自动匹配**: 当调用 `fail()` 方法传入字符串错误信息时,系统自动在映射表中查找匹配的错误码 3. **运行时转换**: 如果找到匹配的错误码,系统会将错误信息替换为错误码,并在响应中包含 `code` 字段 4. **智能提示**: 在 IDE 中,AI 会实时提示开发者使用正确的系统内置错误码 #### 8.2.3 实际响应格式 当使用字符串错误信息时,系统会自动匹配并转换为错误码,最终响应格式为: ```json { "status": 400, "msg": "登录失败", "code": 410019 } ``` 当直接使用错误码时,响应格式为: ```json { "status": 400, "msg": "登录失败", "code": 410019 } ``` ### 8.3 错误处理最佳实践 1. **使用系统内置错误码**: 优先使用系统内置错误码,避免自定义错误信息 2. **错误信息本地化**: 使用 `getLang()` 函数获取本地化的错误信息 3. **详细的错误日志**: 记录详细的错误日志,包括错误码、错误信息、请求参数等 4. **友好的错误提示**: 对客户端返回友好的错误信息,避免暴露系统内部细节 5. **统一的错误处理**: 使用统一的错误处理中间件处理所有错误 6. **错误码文档化**: 定期更新错误码文档,确保与实际代码一致 ### 8.4 自定义错误码 对于系统内置错误码无法覆盖的业务场景,可以自定义错误码,但应遵循以下规范: 1. **错误码范围**: 使用系统未占用的错误码范围 2. **命名规范**: 错误码应具有明确的语义 3. **文档化**: 自定义错误码应在文档中明确说明 4. **本地化**: 自定义错误码应在语言文件中定义对应的错误信息 ## 9. 接口开发流程 ### 9.1 需求分析与设计 1. **需求理解**: 明确接口的业务需求和功能要求 2. **资源设计**: 确定接口涉及的资源和数据模型 3. **接口设计**: 设计接口的 URL、请求方法、参数和响应格式 4. **权限设计**: 确定接口的访问权限和认证方式 5. **错误设计**: 定义接口可能出现的错误情况和错误码 ### 9.2 开发实现 1. **创建路由**: 在路由文件中定义接口路由 2. **实现控制器**: 创建控制器并实现接口逻辑 3. **参数验证**: 使用验证器对请求参数进行验证 4. **业务逻辑**: 实现接口的业务逻辑 5. **错误处理**: 使用 `app('json')->fail()` 统一处理错误 6. **响应返回**: 使用 `app('json')->success()` 统一返回响应 ### 9.3 测试验证 1. **单元测试**: 编写单元测试验证接口功能 2. **集成测试**: 测试接口与其他模块的集成 3. **接口测试**: 使用 Postman 或其他工具测试接口 4. **性能测试**: 测试接口的性能和响应时间 5. **安全测试**: 测试接口的安全性 ### 9.4 文档编写 1. **接口文档**: 编写接口的详细文档 2. **错误码文档**: 在 `error_code.md` 中记录接口使用的错误码 3. **变更记录**: 记录接口的变更历史 ### 9.5 上线发布 1. **代码审查**: 进行代码审查,确保代码质量 2. **测试环境验证**: 在测试环境验证接口功能 3. **灰度发布**: 灰度发布接口,观察运行情况 4. **正式上线**: 正式上线接口 ### 9.6 监控维护 1. **监控**: 监控接口的运行状态和性能 2. **日志**: 记录接口的访问日志和错误日志 3. **优化**: 根据监控数据优化接口性能 4. **维护**: 定期维护和更新接口 ## 10. 最佳实践 ### 10.1 请求设计 - **使用 RESTful 风格**: 遵循 RESTful API 设计规范 - **明确的资源命名**: 使用明确的资源名称,如 `/api/v1/user` 而不是 `/api/v1/getUser` - **合理的 URL 层级**: URL 层级不应过深,一般不超过 3 层 - **使用复数形式**: 资源名称使用复数形式,如 `/api/v1/users` 而不是 `/api/v1/user` ### 10.2 参数设计 - **必填参数**: 明确标识必填参数 - **默认值**: 为可选参数提供合理的默认值 - **参数验证**: 对所有参数进行验证 - **参数类型**: 明确参数类型和格式 ### 10.3 响应设计 - **统一格式**: 使用统一的响应格式 - **明确的数据类型**: 响应数据类型应明确 - **避免冗余数据**: 只返回必要的数据 - **分页响应**: 列表接口应支持分页 - **错误信息**: 错误信息应清晰、准确 ### 10.4 安全设计 - **认证授权**: 使用 JWT 或 OAuth2 进行认证授权 - **HTTPS**: 使用 HTTPS 加密传输 - **参数验证**: 严格验证所有输入参数 - **输出编码**: 对输出数据进行编码,防止 XSS 攻击 - **SQL 注入防护**: 使用参数绑定,避免直接拼接 SQL - **CSRF 防护**: 实现 CSRF Token 验证 ## 11. 常见问题 ### 11.1 跨域问题 - **问题**: 浏览器同源策略导致跨域请求失败 - **解决方案**: 实现 CORS(跨域资源共享),设置适当的响应头 ### 10.2 认证失败 - **问题**: 请求未携带认证信息或认证信息无效 - **解决方案**: 检查请求头中的认证信息,确保令牌有效 ### 10.3 参数错误 - **问题**: 请求参数格式错误或缺少必填参数 - **解决方案**: 检查请求参数,确保格式正确且包含所有必填参数 ### 10.4 响应数据不符合预期 - **问题**: 响应数据格式或内容不符合预期 - **解决方案**: 检查 API 文档,确保请求格式正确,或联系 API 提供者 ### 10.5 性能问题 - **问题**: API 请求响应时间过长 - **解决方案**: 优化 API 实现,使用缓存,减少数据库查询次数 ## 12. 参考资源 - [RESTful API 设计指南](https://restfulapi.net/) - [HTTP 状态码](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status) - [API 设计最佳实践](https://cloud.google.com/apis/design) - [JSON API 规范](https://jsonapi.org/) - [OpenAPI 规范](https://swagger.io/specification/) - [API 安全性最佳实践](https://owasp.org/www-project-api-security/) --- ### .Trae/Skills/Php Api/References/Db Design (.trae/skills/php-api/references/db_design.md) # 数据库设计文档 ## 1. 概述 本文档描述了 CRMEB 项目的数据库设计,包括数据库架构、表结构、索引设计、关系设计等,旨在规范数据库设计,提高数据库性能和可维护性。 ## 2. 数据库架构 ### 2.1 整体架构 - **数据库系统**: MySQL 5.7~8.0 - **存储引擎**: InnoDB (默认) - **字符集**: utf8mb4 - **排序规则**: utf8mb4_general_ci - **连接池**: 建议使用 - **SQL文件位置**: `public/install/crmeb.sql` ### 2.2 技术栈 - **MySQL**: 5.7+ - **Redis**: 用于缓存 - **ThinkPHP ORM**: 用于模型操作 - **数据库迁移**: 用于版本控制 - **数据库备份**: 用于数据安全 ### 2.3 配置说明 #### 2.3.1 数据库配置 ```php // config/database.php return [ 'default' => env('database.driver', 'mysql'), 'connections' => [ 'mysql' => [ 'type' => 'mysql', 'hostname' => env('database.hostname', '127.0.0.1'), 'database' => env('database.database', ''), 'username' => env('database.username', ''), 'password' => env('database.password', ''), 'hostport' => env('database.hostport', '3306'), 'charset' => 'utf8mb4', 'prefix' => env('database.prefix', ''), 'debug' => env('app_debug', true), ], ], ]; ``` ## 3. 数据库设计规范 ### 3.1 命名规范 - **数据库名**: 小写字母,下划线分隔 - **表名**: 小写字母,下划线分隔,前缀统一 - **字段名**: 小写字母,下划线分隔 - **索引名**: 小写字母,下划线分隔,类型前缀 - 主键: `PRIMARY` - 唯一索引: `uk_字段名` - 普通索引: `idx_字段名` ### 3.2 表结构规范 - **主键**: 统一命名为 `id`,自增整数 - **外键**: 格式 `表名_id`,如 `user_id` - **时间字段**: `create_time`/`update_time` - **状态字段**: `status`,默认值 0 - **软删除字段**: `delete_time`,默认值 NULL ### 3.3 字段类型规范 - **整数类型**: 根据实际范围选择 - `TINYINT`: 1字节,范围 -128~127 - `SMALLINT`: 2字节,范围 -32768~32767 - `INT`: 4字节,范围 -2147483648~2147483647 - `BIGINT`: 8字节,范围更大 - **字符串类型**: - 固定长度: `CHAR` - 可变长度: `VARCHAR` - 长文本: `TEXT` - 大文本: `LONGTEXT` - **日期时间类型**: - 日期: `DATE` - 时间: `TIME` - 日期时间: `DATETIME` - 时间戳: `TIMESTAMP` - **数值类型**: - 小数: `DECIMAL` - 浮点数: `FLOAT`, `DOUBLE` - **布尔类型**: 使用 `TINYINT(1)`,0 表示 false,1 表示 true ### 3.4 索引规范 - **主键索引**: 每个表必须有主键 - **唯一索引**: 用于唯一标识的字段 - **普通索引**: 用于经常查询的字段 - **复合索引**: 用于多字段查询 - **外键索引**: 用于关联查询 - **索引数量**: 每个表索引数量不宜过多,一般不超过 5 个 ## 4. 核心表结构 ### 4.1 用户表 (`user`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 用户ID | | `username` | `VARCHAR` | 50 | `NOT NULL` | 用户名 | | `password` | `VARCHAR` | 255 | `NOT NULL` | 密码 | | `nickname` | `VARCHAR` | 50 | `NOT NULL` | 昵称 | | `avatar` | `VARCHAR` | 255 | | 头像 | | `mobile` | `VARCHAR` | 20 | | 手机号 | | `email` | `VARCHAR` | 100 | | 邮箱 | | `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ### 4.2 商品表 (`product`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 商品ID | | `name` | `VARCHAR` | 255 | `NOT NULL` | 商品名称 | | `category_id` | `INT` | 11 | `NOT NULL` | 分类ID | | `price` | `DECIMAL` | 10,2 | `NOT NULL` | 价格 | | `stock` | `INT` | 11 | `NOT NULL` | 库存 | | `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ### 4.3 订单表 (`order`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 订单ID | | `order_sn` | `VARCHAR` | 32 | `NOT NULL UNIQUE` | 订单号 | | `user_id` | `INT` | 11 | `NOT NULL` | 用户ID | | `total_price` | `DECIMAL` | 10,2 | `NOT NULL` | 总价 | | `status` | `TINYINT` | 1 | `DEFAULT 0` | 状态 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ### 4.4 分类表 (`category`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 分类ID | | `name` | `VARCHAR` | 50 | `NOT NULL` | 分类名称 | | `parent_id` | `INT` | 11 | `DEFAULT 0` | 父分类ID | | `sort` | `INT` | 11 | `DEFAULT 0` | 排序 | | `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ### 4.5 地址表 (`address`) | 字段名 | 数据类型 | 长度 | 约束 | 描述 | |-------|---------|------|------|------| | `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 地址ID | | `user_id` | `INT` | 11 | `NOT NULL` | 用户ID | | `name` | `VARCHAR` | 50 | `NOT NULL` | 收货人姓名 | | `mobile` | `VARCHAR` | 20 | `NOT NULL` | 手机号 | | `province` | `VARCHAR` | 50 | `NOT NULL` | 省份 | | `city` | `VARCHAR` | 50 | `NOT NULL` | 城市 | | `district` | `VARCHAR` | 50 | `NOT NULL` | 区县 | | `detail` | `VARCHAR` | 255 | `NOT NULL` | 详细地址 | | `is_default` | `TINYINT` | 1 | `DEFAULT 0` | 是否默认 | | `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 | | `delete_time` | `DATETIME` | | | 删除时间 | ## 5. 索引设计 ### 5.1 用户表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `uk_username` | 唯一 | `username` | 用户名唯一索引 | | `idx_mobile` | 普通 | `mobile` | 手机号索引 | | `idx_email` | 普通 | `email` | 邮箱索引 | | `idx_status` | 普通 | `status` | 状态索引 | ### 5.2 商品表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `idx_category_id` | 普通 | `category_id` | 分类ID索引 | | `idx_price` | 普通 | `price` | 价格索引 | | `idx_status` | 普通 | `status` | 状态索引 | ### 5.3 订单表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `uk_order_sn` | 唯一 | `order_sn` | 订单号唯一索引 | | `idx_user_id` | 普通 | `user_id` | 用户ID索引 | | `idx_status` | 普通 | `status` | 状态索引 | | `idx_create_time` | 普通 | `create_time` | 创建时间索引 | ### 5.4 分类表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `idx_parent_id` | 普通 | `parent_id` | 父分类ID索引 | | `idx_sort` | 普通 | `sort` | 排序索引 | | `idx_status` | 普通 | `status` | 状态索引 | ### 5.5 地址表索引 | 索引名 | 类型 | 字段 | 描述 | |-------|------|------|------| | `PRIMARY` | 主键 | `id` | 主键索引 | | `idx_user_id` | 普通 | `user_id` | 用户ID索引 | | `idx_is_default` | 普通 | `is_default` | 是否默认索引 | ## 6. 关系设计 ### 6.1 表关系图 ``` user ----------------- order | | | | | | address product | | | category ``` ### 6.2 关系说明 - **用户与订单**: 一对多关系,一个用户可以有多个订单 - **用户与地址**: 一对多关系,一个用户可以有多个地址 - **商品与分类**: 多对一关系,多个商品属于一个分类 - **订单与商品**: 多对多关系,一个订单可以包含多个商品,一个商品可以出现在多个订单中 ### 6.3 外键关系 | 主表 | 主键 | 从表 | 外键 | 描述 | |------|------|------|------|------| | `user` | `id` | `order` | `user_id` | 订单所属用户 | | `user` | `id` | `address` | `user_id` | 地址所属用户 | | `category` | `id` | `product` | `category_id` | 商品所属分类 | ## 7. 性能优化 ### 7.1 索引优化 - **选择合适的索引类型**: 根据查询场景选择合适的索引类型 - **避免过度索引**: 只在需要的字段上创建索引 - **使用复合索引**: 对于多字段查询,使用复合索引 - **定期维护索引**: 定期重建碎片化的索引 ### 7.2 查询优化 - **避免全表扫描**: 使用索引覆盖查询 - **减少查询字段**: 只查询需要的字段 - **使用连接查询**: 合理使用连接查询,避免子查询 - **限制查询结果**: 使用 LIMIT 限制查询结果数量 ### 7.3 存储优化 - **选择合适的字段类型**: 根据实际需求选择合适的字段类型 - **使用分区表**: 对于大表,使用分区表提高查询性能 - **定期清理数据**: 定期清理无用数据,减少表大小 - **使用缓存**: 对于频繁查询的数据,使用 Redis 缓存 ### 7.4 配置优化 - **调整 innodb_buffer_pool_size**: 根据服务器内存大小调整 - **调整 max_connections**: 根据并发量调整 - **启用查询缓存**: 对于读多写少的场景 - **优化日志配置**: 合理配置二进制日志和慢查询日志 ## 8. 安全设计 ### 8.1 数据安全 - **加密存储**: 敏感数据(如密码)加密存储 - **数据备份**: 定期备份数据库 - **数据恢复**: 建立数据恢复机制 - **访问控制**: 严格控制数据库访问权限 ### 8.2 SQL 注入防护 - **使用参数化查询**: 避免直接拼接 SQL - **使用 ORM**: 使用 ThinkPHP ORM 框架 - **输入验证**: 对用户输入进行验证 - **转义特殊字符**: 对特殊字符进行转义 ### 8.3 权限管理 - **最小权限原则**: 只授予必要的权限 - **角色分离**: 不同角色拥有不同权限 - **定期审计**: 定期审计数据库访问日志 ## 9. 备份与恢复 ### 9.1 备份策略 - **全量备份**: 定期进行全量备份 - **增量备份**: 每天进行增量备份 - **日志备份**: 备份二进制日志 ### 9.2 恢复策略 - **全量恢复**: 使用全量备份恢复 - **增量恢复**: 使用增量备份恢复 - **点恢复**: 使用二进制日志进行点恢复 ### 9.3 备份工具 - **mysqldump**: MySQL 自带备份工具 - **xtrabackup**: Percona 提供的备份工具 - **第三方工具**: 如 Navicat 等 ## 10. 版本控制 ### 10.1 数据库迁移 - **使用迁移工具**: 使用 ThinkPHP 数据库迁移工具 - **版本管理**: 对数据库结构变更进行版本管理 - **回滚机制**: 支持数据库结构回滚 ### 10.2 迁移文件命名规范 - **格式**: `YYYYMMDDHHMMSS_描述.php` - **示例**: `20230101000000_create_user_table.php` ### 10.3 迁移文件结构 ```php table('user'); $table->addColumn('username', 'string', ['limit' => 50, 'comment' => '用户名']) ->addColumn('password', 'string', ['limit' => 255, 'comment' => '密码']) ->addColumn('nickname', 'string', ['limit' => 50, 'comment' => '昵称']) ->addColumn('avatar', 'string', ['limit' => 255, 'comment' => '头像']) ->addColumn('mobile', 'string', ['limit' => 20, 'comment' => '手机号']) ->addColumn('email', 'string', ['limit' => 100, 'comment' => '邮箱']) ->addColumn('status', 'tinyint', ['default' => 1, 'comment' => '状态']) ->addColumn('create_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间']) ->addColumn('update_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'update' => 'CURRENT_TIMESTAMP', 'comment' => '更新时间']) ->addColumn('delete_time', 'datetime', ['comment' => '删除时间']) ->addIndex('username', ['unique' => true]) ->addIndex('mobile') ->addIndex('email') ->addIndex('status') ->create(); } } ``` ## 11. 维护与监控 ### 11.1 日常维护 - **定期优化表**: 定期执行 OPTIMIZE TABLE 命令 - **监控表大小**: 监控表大小变化 - **检查慢查询**: 定期分析慢查询日志 - **更新统计信息**: 定期更新表统计信息 ### 11.2 监控指标 - **查询性能**: 监控查询响应时间 - **连接数**: 监控数据库连接数 - **缓存命中率**: 监控缓存命中率 - **磁盘使用率**: 监控磁盘空间使用情况 - **CPU 使用率**: 监控数据库服务器 CPU 使用率 ### 11.3 监控工具 - **MySQL Enterprise Monitor**: MySQL 企业版监控工具 - **Percona Monitoring and Management**: 开源监控工具 - **Zabbix**: 通用监控工具 - **Prometheus + Grafana**: 现代化监控方案 ## 12. 总结 本文档描述了 CRMEB 项目的数据库设计规范和最佳实践,包括数据库架构、表结构、索引设计、关系设计、性能优化、安全设计、备份与恢复、版本控制、维护与监控等方面。 遵循本文档的设计规范,可以提高数据库性能和可维护性,确保系统的稳定运行。同时,定期对数据库进行维护和监控,可以及时发现和解决潜在问题,保障系统的安全性和可靠性。 随着业务的发展和系统的演进,数据库设计也需要不断优化和调整,以适应新的业务需求和技术挑战。 --- ### .Trae/Skills/Php Api/References/Directory Structure (.trae/skills/php-api/references/directory_structure.md) # 目录结构文档 ## 1. 概述 本文档描述了 CRMEB 项目的目录结构,包括各目录的功能、文件组织方式等,旨在帮助开发者理解项目结构,提高开发效率。 ## 2. 项目根目录结构 ``` CRMEB/ ├── app/ # 应用目录 ├── config/ # 配置目录 ├── crmeb/ # 核心库目录 ├── database/ # 数据库目录 ├── extend/ # 扩展目录 ├── public/ # 公共资源目录 ├── runtime/ # 运行时目录 ├── thinkphp/ # ThinkPHP 核心目录 ├── vendor/ # 第三方依赖目录 ├── .env # 环境变量文件 ├── .env.example # 环境变量示例文件 ├── composer.json # Composer 配置文件 ├── composer.lock # Composer 锁定文件 ├── LICENSE # 许可证文件 ├── README.md # 项目说明文档 ├── think # ThinkPHP 命令行工具 ``` ## 3. 应用目录结构 (app/) ``` app/ ├── api/ # API 接口层 │ ├── v1/ # API 版本 1 │ ├── v2/ # API 版本 2 │ └── BaseApi.php # API 基类 ├── controller/ # 控制器层 │ ├── admin/ # 管理端控制器 │ ├── api/ # API 控制器 │ └── BaseController.php # 控制器基类 ├── dao/ # 数据访问层 │ └── BaseDao.php # DAO 基类 ├── event/ # 事件层 ├── exception/ # 异常处理层 ├── middleware/ # 中间件层 ├── model/ # 模型层 │ └── BaseModel.php # 模型基类 ├── services/ # 业务逻辑层 │ └── BaseServices.php # 服务基类 ├── subscribe/ # 事件订阅层 ├── validate/ # 验证层 │ └── BaseValidate.php # 验证器基类 └── common.php # 公共函数文件 ``` ### 3.1 API 目录 (app/api/) - **功能**: 处理 API 接口请求 - **结构**: 按 API 版本划分目录 - **基类**: `BaseApi.php`,提供 API 基础功能 - **版本控制**: 通过目录结构实现 API 版本管理 ### 3.2 控制器目录 (app/controller/) - **功能**: 处理 HTTP 请求,路由分发 - **结构**: 按模块划分控制器 - **基类**: `BaseController.php`,提供控制器基础功能 - **类型**: 管理端控制器、API 控制器 ### 3.3 DAO 目录 (app/dao/) - **功能**: 数据访问对象,封装数据库操作 - **结构**: 按业务模块划分 DAO 类 - **基类**: `BaseDao.php`,提供 DAO 基础功能 - **职责**: 处理数据库查询、插入、更新、删除等操作 ### 3.4 模型目录 (app/model/) - **功能**: 数据模型,定义数据结构和关系 - **结构**: 按业务模块划分模型类 - **基类**: `BaseModel.php`,提供模型基础功能 - **特性**: 支持 ORM、关联查询、软删除等 ### 3.5 服务目录 (app/services/) - **功能**: 业务逻辑层,封装核心业务逻辑 - **结构**: 按业务模块划分服务类 - **基类**: `BaseServices.php`,提供服务基础功能 - **职责**: 实现业务规则,协调多个 DAO 和模型 ### 3.6 验证目录 (app/validate/) - **功能**: 数据验证,验证请求参数 - **结构**: 按业务模块划分验证器类 - **基类**: `BaseValidate.php`,提供验证器基础功能 - **特性**: 支持规则验证、场景验证等 ## 4. 配置目录结构 (config/) ``` config/ ├── app.php # 应用配置 ├── cache.php # 缓存配置 ├── captcha.php # 验证码配置 ├── console.php # 控制台配置 ├── cookie.php # Cookie 配置 ├── database.php # 数据库配置 ├── filesystem.php # 文件系统配置 ├── lang.php # 语言配置 ├── log.php # 日志配置 ├── queue.php # 队列配置 ├── route.php # 路由配置 ├── session.php # Session 配置 ├── template.php # 模板配置 └── trace.php # 调试配置 ``` - **功能**: 存储项目的所有配置文件 - **结构**: 按功能模块划分配置文件 - **特性**: 支持环境变量配置、配置缓存等 - **加载顺序**: 框架配置 → 应用配置 → 环境配置 ## 5. 核心库目录结构 (crmeb/) ``` crmeb/ ├── basic/ # 基础类库 ├── exception/ # 核心异常类 ├── services/ # 核心服务类 ├── utils/ # 工具类 └── version.php # 版本信息 ``` - **功能**: 存储 CRMEB 核心库代码 - **结构**: 按功能模块划分目录 - **特性**: 独立于应用代码,便于维护和升级 - **作用**: 提供核心功能和基础服务 ## 6. 数据库目录结构 (database/) ``` database/ ├── migrations/ # 数据库迁移文件 └── seeders/ # 数据库种子文件 ``` - **功能**: 存储数据库相关文件 - **迁移文件**: 用于版本控制数据库结构 - **种子文件**: 用于初始化数据库数据 - **工具**: 使用 ThinkPHP 迁移工具管理 ## 7. 公共资源目录结构 (public/) ``` public/ ├── admin/ # 管理端资源 ├── api/ # API 资源 ├── assets/ # 静态资源 │ ├── css/ # CSS 文件 │ ├── images/ # 图片文件 │ └── js/ # JavaScript 文件 ├── index.php # 应用入口文件 ├── robots.txt # 机器人协议文件 └── router.php # URL 重写文件 ``` - **功能**: 存储可直接访问的公共资源 - **结构**: 按功能模块划分目录 - **特性**: 可通过 URL 直接访问 - **安全**: 敏感文件不应放在此目录 ## 8. 运行时目录结构 (runtime/) ``` runtime/ ├── cache/ # 缓存目录 ├── log/ # 日志目录 │ └── app/ # 应用日志 ├── session/ # Session 目录 ├── temp/ # 临时文件目录 └── think/ # ThinkPHP 运行时目录 ``` - **功能**: 存储运行时生成的文件 - **结构**: 按功能模块划分目录 - **特性**: 自动生成,无需手动维护 - **权限**: 需要可写权限 ## 9. 核心目录结构 (thinkphp/) ``` thinkphp/ ├── lang/ # 语言包目录 ├── library/ # 核心类库目录 ├── tpl/ # 模板目录 ├── base.php # 基础定义文件 ├── composer.json # Composer 配置文件 └── helper.php # 助手函数文件 ``` - **功能**: 存储 ThinkPHP 框架核心代码 - **结构**: 框架默认结构 - **特性**: 独立于应用代码 - **升级**: 通过 Composer 升级 ## 10. 第三方依赖目录结构 (vendor/) ``` vendor/ ├── autoload.php # 自动加载文件 ├── composer/ # Composer 核心目录 ├── symfony/ # Symfony 组件 ├── topthink/ # ThinkPHP 组件 └── ... # 其他第三方依赖 ``` - **功能**: 存储第三方依赖库 - **管理**: 通过 Composer 管理 - **结构**: 按依赖包名称划分目录 - **自动加载**: 通过 `autoload.php` 自动加载 ## 11. 目录结构最佳实践 ### 11.1 命名规范 - **目录名**: 小写字母,单词之间用下划线分隔 - **文件名**: 与类名一致,使用 PascalCase 命名风格 - **类名**: 使用 PascalCase 命名风格 - **方法名**: 使用 camelCase 命名风格 - **变量名**: 使用 camelCase 命名风格 ### 11.2 组织原则 - **模块化**: 按功能模块组织目录结构 - **分层架构**: 遵循 MVC + Service + DAO 分层架构 - **单一职责**: 每个目录和文件只负责一个功能 - **可扩展性**: 便于添加新功能和模块 - **易维护性**: 便于理解和维护 ### 11.3 开发建议 - **遵循框架规范**: 遵循 ThinkPHP 框架目录结构规范 - **合理划分模块**: 根据业务功能合理划分模块 - **避免目录过深**: 目录层级不宜过深,一般不超过 4 层 - **保持目录整洁**: 及时清理无用文件和目录 - **文档化**: 为重要目录添加说明文档 ## 12. 常见问题 ### 12.1 目录权限问题 - **问题**: 运行时目录没有写权限 - **解决方案**: 执行 `chmod -R 777 runtime/` 赋予写权限 ### 12.2 自动加载问题 - **问题**: 新增类无法自动加载 - **解决方案**: 执行 `composer dump-autoload` 更新自动加载 ### 12.3 配置文件不生效 - **问题**: 修改配置文件后不生效 - **解决方案**: 清除配置缓存,执行 `php think clear` ### 12.4 目录结构混乱 - **问题**: 目录结构不清晰,难以维护 - **解决方案**: 重新组织目录结构,遵循模块化原则 ## 13. 参考资源 - [ThinkPHP 6 目录结构](https://www.kancloud.cn/manual/thinkphp6_0/1037487) - [MVC 架构设计](https://zh.wikipedia.org/wiki/MVC) - [分层架构设计](https://zh.wikipedia.org/wiki/分层架构) - [模块化设计](https://zh.wikipedia.org/wiki/模块化设计) --- ### .Trae/Skills/Php Api/References/Error Code (.trae/skills/php-api/references/error_code.md) # 错误码文档 ## 1. 概述 本文档描述了 CRMEB 项目的错误码规范,包括错误码的分类、定义、使用方法等,旨在统一错误码格式,提高错误处理的一致性和可维护性。 ## 2. 错误码分类 ### 2.1 HTTP 状态码 - **1xx**: 信息性状态码,表示请求已接收,继续处理 - **2xx**: 成功状态码,表示请求已成功处理 - **3xx**: 重定向状态码,表示需要进一步操作以完成请求 - **4xx**: 客户端错误状态码,表示请求包含语法错误或无法完成请求 - **5xx**: 服务器错误状态码,表示服务器在处理请求时发生错误 ### 2.2 业务错误码 业务错误码由 5 位数字组成,格式为 `XXXXX`,其中: - **第一位**: 错误类型标识 - `1`: 系统错误 - `2`: 业务错误 - `3`: 参数错误 - `4`: 权限错误 - `5`: 资源错误 - `6`: 数据库错误 - `7`: 第三方服务错误 - `8`: 其他错误 - **后四位**: 具体错误编码,从 0000 开始递增 ## 3. 系统错误码 ### 3.1 系统错误 (1xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 10001 | 系统内部错误 | 500 | | 10002 | 系统维护中 | 503 | | 10003 | 系统繁忙 | 503 | | 10004 | 服务不可用 | 503 | | 10005 | 网关错误 | 502 | ### 3.2 业务错误 (2xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 20001 | 操作失败 | 400 | | 20002 | 业务逻辑错误 | 400 | | 20003 | 数据已存在 | 400 | | 20004 | 数据不存在 | 404 | | 20005 | 操作不允许 | 403 | ### 3.3 参数错误 (3xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 30001 | 参数不能为空 | 400 | | 30002 | 参数格式错误 | 400 | | 30003 | 参数类型错误 | 400 | | 30004 | 参数超出范围 | 400 | | 30005 | 参数验证失败 | 422 | ### 3.4 权限错误 (4xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 40001 | 未登录 | 401 | | 40002 | 登录已过期 | 401 | | 40003 | 无权限访问 | 403 | | 40004 | 权限不足 | 403 | | 40005 | 令牌无效 | 401 | ### 3.5 资源错误 (5xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 50001 | 资源不存在 | 404 | | 50002 | 资源已删除 | 404 | | 50003 | 资源已锁定 | 400 | | 50004 | 资源不足 | 400 | | 50005 | 资源已过期 | 400 | ### 3.6 数据库错误 (6xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 60001 | 数据库连接失败 | 500 | | 60002 | 数据库查询失败 | 500 | | 60003 | 数据库更新失败 | 500 | | 60004 | 数据库插入失败 | 500 | | 60005 | 数据库删除失败 | 500 | | 60006 | 数据库事务失败 | 500 | ### 3.7 第三方服务错误 (7xxxxx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 70001 | 第三方服务连接失败 | 500 | | 70002 | 第三方服务超时 | 504 | | 70003 | 第三方服务返回错误 | 500 | | 70004 | 第三方服务认证失败 | 401 | | 70005 | 第三方服务限流 | 429 | ## 4. 模块错误码 ### 4.1 用户模块 (801xx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 80101 | 用户名或密码错误 | 401 | | 80102 | 用户不存在 | 404 | | 80103 | 用户已存在 | 400 | | 80104 | 用户状态异常 | 400 | | 80105 | 验证码错误 | 400 | | 80106 | 验证码已过期 | 400 | | 80107 | 手机号格式错误 | 400 | | 80108 | 邮箱格式错误 | 400 | ### 4.2 商品模块 (802xx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 80201 | 商品不存在 | 404 | | 80202 | 商品已下架 | 400 | | 80203 | 商品库存不足 | 400 | | 80204 | 商品价格异常 | 400 | | 80205 | 商品分类不存在 | 404 | ### 4.3 订单模块 (803xx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 80301 | 订单不存在 | 404 | | 80302 | 订单状态异常 | 400 | | 80303 | 订单已取消 | 400 | | 80304 | 订单已完成 | 400 | | 80305 | 订单支付失败 | 400 | | 80306 | 订单支付超时 | 400 | ### 4.4 支付模块 (804xx) | 错误码 | 描述 | HTTP 状态码 | |-------|------|-------------| | 80401 | 支付方式不支持 | 400 | | 80402 | 支付金额异常 | 400 | | 80403 | 支付参数错误 | 400 | | 80404 | 支付失败 | 400 | | 80405 | 支付超时 | 400 | | 80406 | 支付已完成 | 400 | ## 5. 错误码使用规范 ### 5.1 错误响应格式 ```json { "code": 20001, "msg": "操作失败", "data": [] } ``` ### 5.2 成功响应格式 ```json { "code": 200, "msg": "操作成功", "data": {...} } ``` ### 5.3 错误处理流程 1. **捕获异常**: 在控制器或中间件中捕获异常 2. **确定错误码**: 根据异常类型确定对应的错误码 3. **构建响应**: 按照统一格式构建错误响应 4. **返回响应**: 返回错误响应给客户端 ### 5.4 错误日志记录 - **记录内容**: 错误码、错误信息、请求参数、请求路径、用户信息、时间戳等 - **记录级别**: 根据错误严重程度选择合适的日志级别 - **记录位置**: 系统日志文件 - **监控告警**: 对于严重错误,触发告警机制 ## 6. 错误码管理 ### 6.1 错误码定义 错误码定义在配置文件中,便于统一管理和维护: ```php // config/error_code.php return [ // 系统错误 10001 => '系统内部错误', 10002 => '系统维护中', // 业务错误 20001 => '操作失败', 20002 => '业务逻辑错误', // 参数错误 30001 => '参数不能为空', 30002 => '参数格式错误', // ... ]; ``` ### 6.2 错误码使用 在代码中使用错误码时,应直接引用配置文件中的定义: ```php // 控制器中使用 return $this->fail(config('error_code.20001')); // 或直接使用错误码 return $this->fail('操作失败', [], 20001); ``` ### 6.3 错误码更新 当需要添加新的错误码时,应遵循以下流程: 1. **确定错误类型**: 根据错误性质确定错误类型 2. **分配错误码**: 从对应类型的错误码范围中分配一个未使用的错误码 3. **更新配置**: 在 `error_code.php` 配置文件中添加错误码定义 4. **更新文档**: 更新错误码文档 5. **通知团队**: 通知团队成员新添加的错误码 ## 7. 错误码最佳实践 ### 7.1 设计原则 - **唯一性**: 每个错误码唯一对应一种错误情况 - **可读性**: 错误码应易于理解和记忆 - **可扩展性**: 错误码应具有良好的扩展性,便于添加新的错误码 - **一致性**: 错误码格式和使用方法应保持一致 - **详细性**: 错误信息应清晰、准确,便于调试和定位问题 ### 7.2 使用建议 - **避免硬编码**: 错误码应定义在配置文件中,避免直接硬编码在代码中 - **统一处理**: 使用统一的错误处理中间件处理错误 - **详细日志**: 记录详细的错误日志,便于调试和分析 - **友好提示**: 向客户端返回友好的错误信息,避免暴露系统内部细节 - **定期清理**: 定期清理不再使用的错误码,保持错误码的简洁性 ### 7.3 常见问题 #### 7.3.1 错误码冲突 - **问题**: 不同模块使用了相同的错误码 - **解决方案**: 严格按照模块划分错误码范围,避免冲突 #### 7.3.2 错误信息不明确 - **问题**: 错误信息过于简洁,无法定位问题 - **解决方案**: 提供详细的错误信息,包含必要的上下文 #### 7.3.3 错误码未及时更新 - **问题**: 新增功能时未及时添加对应的错误码 - **解决方案**: 在开发新功能时,同步更新错误码定义和文档 ## 8. 参考资源 - [HTTP 状态码](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status) - [RESTful API 错误处理](https://restfulapi.net/http-status-codes/) - [错误码设计最佳实践](https://www.thoughtworks.com/insights/blog/error-handling-microservices) - [API 错误码规范](https://cloud.google.com/apis/design/errors) --- ### .Trae/Skills/Uniapp/References/Api Flow (.trae/skills/uniapp/references/api_flow.md) # UniApp API 开发流程文档 ## 1. 概述 本文档描述了 CRMEB 项目中 UniApp 移动端的 API 开发流程,包括 API 接口设计、请求流程、响应处理、错误处理等,旨在规范 API 开发,提高开发效率和代码质量。 ## 2. API 目录结构 ``` template/uni-app/api/ ├── activity.js # 活动相关接口 ├── admin.js # 管理相关接口 ├── api.js # 基础 API 配置 ├── kefu.js # 客服相关接口 ├── lottery.js # 抽奖相关接口 ├── order.js # 订单相关接口 ├── public.js # 公共接口 ├── store.js # 商城相关接口 └── user.js # 用户相关接口 ``` ## 3. 基础 API 配置 (api.js) ```javascript // 基础 API 配置 const baseURL = 'https://api.crmeb.net'; // 请求超时时间 const timeout = 10000; // 请求拦截器 const requestInterceptor = (config) => { // 添加 token const token = uni.getStorageSync('token'); if (token) { config.header['Authorization'] = `Bearer ${token}`; } // 添加设备信息 config.header['X-Device-Type'] = uni.getSystemInfoSync().platform; return config; }; // 响应拦截器 const responseInterceptor = (response) => { const { data } = response; // 统一处理错误 if (data.code !== 200) { uni.showToast({ title: data.message || '请求失败', icon: 'none' }); // 处理登录过期 if (data.code === 401) { uni.redirectTo({ url: '/pages/login/index' }); } return Promise.reject(data); } return data; }; // 错误处理 const errorHandler = (error) => { uni.showToast({ title: '网络错误,请稍后重试', icon: 'none' }); return Promise.reject(error); }; // 导出配置 export default { baseURL, timeout, requestInterceptor, responseInterceptor, errorHandler }; ``` ## 4. API 接口封装 ### 4.1 通用请求方法 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 4.2 业务接口封装 ```javascript // api/user.js import request from '../utils/request'; // 用户相关接口 export default { // 登录 login: (data) => request.post('/api/user/login', data), // 注册 register: (data) => request.post('/api/user/register', data), // 获取用户信息 getUserInfo: () => request.get('/api/user/info'), // 更新用户信息 updateUserInfo: (data) => request.put('/api/user/info', data), // 修改密码 changePassword: (data) => request.post('/api/user/password', data), // 获取地址列表 getAddressList: () => request.get('/api/user/address'), // 添加地址 addAddress: (data) => request.post('/api/user/address', data), // 更新地址 updateAddress: (id, data) => request.put(`/api/user/address/${id}`, data), // 删除地址 deleteAddress: (id) => request.delete(`/api/user/address/${id}`), // 设置默认地址 setDefaultAddress: (id) => request.put(`/api/user/address/${id}/default`) }; ``` ## 5. API 调用示例 ### 5.1 页面中调用 API ```vue ``` ### 5.2 组件中调用 API ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## 6. API 开发最佳实践 ### 6.1 命名规范 - **文件命名**: 小写字母,单词之间用下划线分隔,如 `user.js` - **方法命名**: 驼峰命名法,如 `getUserInfo` - **URL 命名**: 小写字母,单词之间用连字符分隔,如 `/api/user/info` - **参数命名**: 驼峰命名法,与后端保持一致 ### 6.2 接口设计规范 - **RESTful 风格**: 遵循 RESTful API 设计规范 - **版本控制**: 在 URL 中包含版本号,如 `/api/v1/user/info` - **统一响应格式**: 所有接口返回统一的响应格式 - **错误处理**: 统一的错误码和错误信息 ### 6.3 请求规范 - **请求方法**: 根据操作类型选择合适的 HTTP 方法 - GET: 获取资源 - POST: 创建资源 - PUT: 更新资源 - DELETE: 删除资源 - **请求头**: 统一添加必要的请求头,如 Authorization、Content-Type 等 - **参数传递**: 根据请求方法选择合适的参数传递方式 - GET: 查询参数 - POST/PUT: 请求体 - DELETE: 查询参数或路径参数 ### 6.4 响应规范 - **成功响应**: ```json { "code": 200, "message": "请求成功", "data": {} } ``` - **失败响应**: ```json { "code": 400, "message": "请求失败", "data": {} } ``` ### 6.5 错误处理规范 - **网络错误**: 统一处理网络错误,如超时、断网等 - **业务错误**: 根据错误码处理不同的业务错误 - **登录过期**: 统一处理登录过期,跳转到登录页面 - **错误提示**: 统一的错误提示方式,使用 uni.showToast ## 7. API 性能优化 ### 7.1 请求优化 - **合并请求**: 多个相关请求合并为一个 - **缓存策略**: 对不经常变化的数据使用缓存 - **请求防抖**: 避免频繁发送相同的请求 - **批量操作**: 支持批量操作,减少请求次数 ### 7.2 响应优化 - **数据结构优化**: 优化响应数据结构,减少数据传输量 - **分页处理**: 对列表数据使用分页 - **字段筛选**: 支持字段筛选,只返回需要的字段 - **压缩传输**: 使用 gzip 压缩传输数据 ### 7.3 代码优化 - **模块化**: 按业务模块划分 API 文件 - **复用代码**: 提取通用的请求逻辑 - **减少冗余**: 避免重复的 API 调用 - **代码可读性**: 保持代码清晰易读 ## 8. 常见问题 ### 8.1 跨域问题 - **问题**: 开发环境中遇到跨域问题 - **解决方案**: 在本地开发服务器中配置跨域代理 ### 8.2 Token 过期问题 - **问题**: Token 过期后请求失败 - **解决方案**: 在响应拦截器中处理 Token 过期,跳转到登录页面 ### 8.3 请求超时问题 - **问题**: 网络不稳定时请求超时 - **解决方案**: 设置合理的超时时间,添加网络状态检测 ### 8.4 重复请求问题 - **问题**: 快速点击按钮导致重复请求 - **解决方案**: 添加请求防抖或锁机制 ### 8.5 数据缓存问题 - **问题**: 缓存数据与服务器数据不一致 - **解决方案**: 合理设置缓存过期时间,提供手动刷新机制 ## 9. 参考资源 - [UniApp 网络请求文档](https://uniapp.dcloud.io/api/request/request) - [RESTful API 设计指南](https://restfulapi.cn/) - [Axios 文档](https://axios-http.com/zh/docs/intro) - [HTTP 方法](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods) ## 10. 总结 本文档描述了 CRMEB 项目中 UniApp 移动端的 API 开发流程,包括 API 接口设计、请求流程、响应处理、错误处理等。遵循本文档的开发规范,可以提高 API 开发的效率和质量,确保应用的稳定性和可靠性。 随着业务的发展和技术的演进,API 开发流程也需要不断优化和调整,以适应新的业务需求和技术挑战。 --- ### .Trae/Skills/Uniapp/References/Code Style (.trae/skills/uniapp/references/code_style.md) # UniApp 代码规范文档 ## 1. 概述 本文档描述了 CRMEB 项目中 UniApp 移动端的代码规范,包括命名规范、代码风格、文件结构、组件开发等,旨在统一代码风格,提高代码质量和可维护性。 ## 2. 命名规范 ### 2.1 目录命名 - **目录名**: 小写字母,单词之间用下划线分隔 - **示例**: `pages/index/`、`components/common/`、`utils/` - **规范**: 简洁明了,反映目录的功能 ### 2.2 文件命名 - **页面文件**: 小写字母,单词之间用下划线分隔 - **示例**: `index.vue`、`login.vue`、`user_info.vue` - **组件文件**: 大写字母开头的 PascalCase 命名风格 - **示例**: `Button.vue`、`NavBar.vue`、`GoodsList.vue` - **JS 文件**: 小写字母,单词之间用下划线分隔 - **示例**: `user.js`、`request.js`、`util.js` - **CSS/SCSS 文件**: 小写字母,单词之间用下划线分隔 - **示例**: `common.scss`、`theme.scss` ### 2.3 变量命名 - **普通变量**: 驼峰命名法 - **示例**: `userInfo`、`goodsList`、`isLoading` - **常量**: 全大写,单词之间用下划线分隔 - **示例**: `BASE_URL`、`MAX_COUNT`、`DEFAULT_PAGE_SIZE` - **布尔变量**: 以 `is` 开头的驼峰命名法 - **示例**: `isShow`、`isLoading`、`isLogin` ### 2.4 函数命名 - **函数名**: 驼峰命名法,动词开头 - **示例**: `getUserInfo`、`submitForm`、`handleClick` - **方法名**: 驼峰命名法 - **示例**: `data`、`methods`、`computed`、`watch` - **生命周期函数**: 按照 Vue 规范命名 - **示例**: `created`、`mounted`、`beforeDestroy` ### 2.5 组件命名 - **组件名**: PascalCase 命名风格 - **示例**: `Button`、`NavBar`、`GoodsList` - **组件标签**: 小写字母,单词之间用连字符分隔 - **示例**: ``、``、`` ### 2.6 其他命名 - **路由命名**: 小写字母,单词之间用连字符分隔 - **示例**: `/pages/index/index`、`/pages/user/login` - **CSS 类名**: 小写字母,单词之间用连字符分隔 - **示例**: `.user-info`、`.goods-list`、`.btn-primary` - **ID 命名**: 小写字母,单词之间用连字符分隔 - **示例**: `#app`、`#header`、`#footer` ## 3. 代码风格 ### 3.1 缩进 - **缩进方式**: 4 个空格 - **示例**: ```vue ``` ### 3.2 换行 - **标签换行**: 多个属性的标签应该换行 - **示例**: ```vue {{ message }} ``` - **代码块换行**: 逻辑代码块应该换行 - **示例**: ```javascript if (condition) { // 代码块 } else { // 代码块 } ``` ### 3.3 空格 - **运算符空格**: 运算符两侧应该有空格 - **示例**: `a + b`、`x = y`、`i < 10` - **逗号空格**: 逗号后面应该有空格 - **示例**: `[1, 2, 3]`、`{ name: '张三', age: 18 }` - **括号空格**: 括号内侧不应该有空格 - **示例**: `if (condition)`、`function (param)` ### 3.4 注释 - **单行注释**: 使用 `//` 注释 - **示例**: `// 这是单行注释` - **多行注释**: 使用 `/* */` 注释 - **示例**: ```javascript /* * 这是多行注释 * 第二行 */ ``` - **文档注释**: 使用 JSDoc 风格的注释 - **示例**: ```javascript /** * 获取用户信息 * @param {number} id - 用户ID * @returns {Promise} 用户信息 */ async function getUserInfo(id) { // 代码 } ``` ### 3.5 引号 - **字符串**: 使用单引号 `''` - **示例**: `const name = '张三'`、`Hello` - **模板字符串**: 使用反引号 `` ` `` - **示例**: `` const url = `${baseUrl}/api/user` `` - **HTML 属性**: 使用双引号 `""` - **示例**: ``、`` ## 4. 文件结构 ### 4.1 页面文件结构 ```vue ``` ### 4.2 组件文件结构 ```vue ``` ### 4.3 JS 文件结构 ```javascript // 导入依赖 import request from './request'; // 常量定义 const BASE_URL = 'https://api.crmeb.net'; const TIMEOUT = 10000; // 工具函数 function formatTime(time) { const date = new Date(time); return date.toLocaleString(); } function getRandomNum(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } // 导出 export { formatTime, getRandomNum }; // 默认导出 export default { BASE_URL, TIMEOUT }; ``` ## 5. 组件开发规范 ### 5.1 组件设计 - **单一职责**: 每个组件只负责一个功能 - **可复用性**: 设计通用的、可复用的组件 - **可配置性**: 通过 props 提供配置选项 - **事件通信**: 通过事件与父组件通信 ### 5.2 组件使用 - **组件导入**: 使用 import 导入组件 - **示例**: `import Button from '../../components/Button.vue'` - **组件注册**: 在 components 中注册组件 - **示例**: ```javascript components: { Button } ``` - **组件使用**: 使用组件标签 - **示例**: `` ### 5.3 组件通信 - **props 向下传递**: 父组件通过 props 向子组件传递数据 - **events 向上传递**: 子组件通过 events 向父组件传递事件 - **refs 引用**: 通过 refs 引用子组件实例 - **provide/inject**: 祖先组件向后代组件传递数据 ## 6. 页面开发规范 ### 6.1 页面结构 - **模板结构**: 清晰明了,层次分明 - **脚本结构**: 按照 Vue 规范组织代码 - **样式结构**: 模块化,可维护 ### 6.2 数据管理 - **本地数据**: 使用 data 管理组件内部数据 - **计算数据**: 使用 computed 计算衍生数据 - **监听数据**: 使用 watch 监听数据变化 - **全局数据**: 使用 Vuex 管理全局数据 ### 6.3 生命周期管理 - **created**: 初始化数据,发送请求 - **mounted**: 操作 DOM,初始化第三方库 - **beforeDestroy**: 清理定时器,取消订阅 ### 6.4 路由管理 - **路由配置**: 在 pages.json 中配置路由 - **路由跳转**: 使用 uni.navigateTo、uni.redirectTo 等方法 - **路由参数**: 通过 options 或 $route.params 获取路由参数 ## 7. API 调用规范 ### 7.1 API 封装 - **模块化**: 按业务模块封装 API - **统一处理**: 统一处理请求头、响应拦截、错误处理 - **Promise 化**: 使用 Promise 处理异步请求 ### 7.2 API 调用 - **异步处理**: 使用 async/await 处理异步请求 - **错误处理**: 使用 try/catch 捕获错误 - **加载状态**: 显示加载状态,提升用户体验 - **错误提示**: 统一处理错误提示 ### 7.3 示例代码 ```javascript async function getUserInfo() { try { this.loading = true; const res = await userApi.getUserInfo(); this.userInfo = res.data; } catch (error) { console.error('获取用户信息失败:', error); uni.showToast({ title: '获取用户信息失败', icon: 'none' }); } finally { this.loading = false; } } ``` ## 8. 性能优化 ### 8.1 代码优化 - **减少冗余代码**: 避免重复的代码 - **使用计算属性**: 对于复杂的计算,使用 computed - **使用 v-if 和 v-show 合理**: 根据场景选择合适的指令 - **使用 key**: 在 v-for 中使用 key,提高渲染性能 ### 8.2 网络优化 - **合理使用缓存**: 缓存不经常变化的数据 - **减少请求次数**: 合并请求,批量操作 - **使用防抖和节流**: 避免频繁的事件触发 - **延迟加载**: 对于非首屏内容,使用延迟加载 ### 8.3 其他优化 - **减少 DOM 节点**: 简化 DOM 结构 - **优化图片**: 使用合适的图片格式和大小 - **使用虚拟列表**: 对于长列表,使用虚拟列表 - **避免内存泄漏**: 及时清理定时器、事件监听器等 ## 9. 常见问题 ### 9.1 代码风格问题 - **问题**: 代码风格不一致 - **解决方案**: 使用 ESLint 等工具进行代码检查 ### 9.2 性能问题 - **问题**: 页面加载慢,卡顿 - **解决方案**: 优化代码,减少 DOM 操作,使用虚拟列表等 ### 9.3 兼容性问题 - **问题**: 在不同平台上表现不一致 - **解决方案**: 遵循 UniApp 规范,使用条件编译 ### 9.4 维护性问题 - **问题**: 代码难以维护 - **解决方案**: 模块化开发,添加注释,遵循代码规范 ## 10. 参考资源 - [Vue 官方文档](https://cn.vuejs.org/) - [UniApp 官方文档](https://uniapp.dcloud.io/) - [ESLint 官方文档](https://eslint.org/docs/user-guide/) - [Prettier 官方文档](https://prettier.io/docs/en/) - [前端代码规范指南](https://github.com/ecomfe/spec) ## 11. 总结 本文档描述了 CRMEB 项目中 UniApp 移动端的代码规范,包括命名规范、代码风格、文件结构、组件开发等。遵循本文档的规范,可以提高代码的可读性、可维护性和可扩展性,确保项目的质量和稳定性。 代码规范是团队协作的基础,建议开发团队成员严格遵循本文档的规范,共同维护一个高质量的代码库。 --- ### .Trae/Skills/Uniapp/References/Directory Structure (.trae/skills/uniapp/references/directory_structure.md) # UniApp 目录结构文档 ## 1. 概述 本文档描述了 CRMEB 项目中 UniApp 移动端的目录结构,包括各目录的功能、文件组织方式等,旨在帮助开发者理解项目结构,提高开发效率。 ## 2. 项目根目录结构 ``` template/uni-app/ ├── api/ # API 接口目录 ├── config/ # 配置目录 ├── libs/ # 库文件目录 ├── mixins/ # 混入目录 ├── store/ # 状态管理目录 ├── utils/ # 工具类目录 ├── App.vue # 应用入口组件 ├── main.js # 应用入口文件 ├── manifest.json # 应用配置文件 ├── package.json # 项目配置文件 ├── pages.json # 页面路由配置文件 ├── uni.scss # UniApp 全局样式文件 └── vue.config.js # Vue 配置文件 ``` ## 3. API 目录结构 (api/) ``` api/ ├── activity.js # 活动相关接口 ├── admin.js # 管理相关接口 ├── api.js # 基础 API 配置 ├── kefu.js # 客服相关接口 ├── lottery.js # 抽奖相关接口 ├── order.js # 订单相关接口 ├── public.js # 公共接口 ├── store.js # 商城相关接口 └── user.js # 用户相关接口 ``` - **功能**: 封装与后端交互的 API 接口 - **结构**: 按业务模块划分接口文件 - **特性**: 统一处理请求头、响应拦截、错误处理等 - **调用方式**: 通过 `import` 导入使用 ## 4. 配置目录结构 (config/) ``` config/ ├── app.js # 应用配置 ├── cache.js # 缓存配置 └── socket.js # WebSocket 配置 ``` - **功能**: 存储项目的所有配置文件 - **结构**: 按功能模块划分配置文件 - **特性**: 集中管理配置,便于维护和修改 - **加载顺序**: 应用启动时加载 ## 5. 库文件目录结构 (libs/) ``` libs/ ├── chat.js # 聊天相关功能 ├── login.js # 登录相关功能 ├── new_chat.js # 新聊天功能 ├── order.js # 订单相关功能 ├── routine.js # 小程序相关功能 ├── uniApi.js # UniApp API 封装 └── wechat.js # 微信相关功能 ``` - **功能**: 存储通用库文件和功能模块 - **结构**: 按功能划分库文件 - **特性**: 独立于页面代码,便于复用 - **作用**: 提供通用功能和服务 ## 6. 混入目录结构 (mixins/) ``` mixins/ └── color.js # 颜色相关混入 ``` - **功能**: 存储 Vue 混入对象 - **结构**: 按功能划分混入文件 - **特性**: 实现代码复用,避免重复逻辑 - **作用**: 为组件提供共享的方法和数据 ## 7. 状态管理目录结构 (store/) ``` store/ ├── getters.js # 状态获取器 └── index.js # 状态管理入口 ``` - **功能**: 存储 Vuex 状态管理相关文件 - **结构**: 按 Vuex 规范划分文件 - **特性**: 集中管理应用状态,实现组件间通信 - **作用**: 管理全局状态,如用户信息、购物车数据等 ## 8. 工具类目录结构 (utils/) ``` utils/ ├── cache.js # 缓存工具 ├── emoji.js # 表情工具 ├── index.js # 工具类入口 ├── lang.js # 语言工具 ├── request.js # 网络请求工具 ├── theme.js # 主题工具 ├── util.js # 通用工具 └── validate.js # 验证工具 ``` - **功能**: 存储通用工具类 - **结构**: 按功能划分工具文件 - **特性**: 提供通用功能,便于复用 - **作用**: 处理缓存、网络请求、验证等通用操作 ## 9. 页面目录结构 ### 9.1 页面配置 (pages.json) ```json { "pages": [ { "path": "pages/index/index", "style": { "navigationBarTitleText": "首页" } }, { "path": "pages/user/index", "style": { "navigationBarTitleText": "个人中心" } } ], "subPackages": [ { "root": "pages/order", "pages": [ { "path": "index", "style": { "navigationBarTitleText": "订单列表" } } ] } ] } ``` - **功能**: 配置页面路由、导航栏样式等 - **结构**: 按页面层级配置 - **特性**: 支持分包加载,优化应用体积 - **作用**: 定义应用的页面结构和导航样式 ## 10. 应用配置文件 ### 10.1 manifest.json ```json { "name": "CRMEB商城", "appid": "__UNI__APPID__", "description": "CRMEB商城移动端", "versionName": "1.0.0", "versionCode": "100", "transformPx": true, "uniStatistics": { "enable": true }, "app-plus": { "usingComponents": true, "nvueStyleCompiler": "uni-app" }, "mp-weixin": { "appid": "wx_appid", "setting": { "urlCheck": false }, "usingComponents": true } } ``` - **功能**: 配置应用的基本信息、平台配置等 - **结构**: 按平台划分配置 - **特性**: 支持多平台配置,如微信小程序、App 等 - **作用**: 定义应用的全局配置信息 ### 10.2 package.json ```json { "name": "crmeb-uni-app", "version": "1.0.0", "description": "CRMEB商城移动端", "main": "main.js", "scripts": { "dev": "npm run dev:mp-weixin", "dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch", "build": "npm run build:mp-weixin", "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build" }, "dependencies": { "vue": "^2.6.11", "vuex": "^3.4.0" } } ``` - **功能**: 配置项目的依赖、脚本等 - **结构**: 标准 npm 配置格式 - **特性**: 管理项目依赖,定义构建脚本 - **作用**: 管理项目的依赖和构建流程 ## 11. 目录结构最佳实践 ### 11.1 命名规范 - **目录名**: 小写字母,单词之间用下划线分隔 - **文件名**: 小写字母,单词之间用下划线分隔 - **组件名**: 使用 PascalCase 命名风格 - **方法名**: 使用 camelCase 命名风格 - **变量名**: 使用 camelCase 命名风格 ### 11.2 组织原则 - **模块化**: 按功能模块组织目录结构 - **分层架构**: 遵循 Vue 组件化开发架构 - **单一职责**: 每个目录和文件只负责一个功能 - **可扩展性**: 便于添加新功能和模块 - **易维护性**: 便于理解和维护 ### 11.3 开发建议 - **遵循 UniApp 规范**: 遵循 UniApp 官方目录结构规范 - **合理划分模块**: 根据业务功能合理划分模块 - **避免目录过深**: 目录层级不宜过深,一般不超过 4 层 - **保持目录整洁**: 及时清理无用文件和目录 - **文档化**: 为重要目录添加说明文档 ## 12. 常见问题 ### 12.1 目录权限问题 - **问题**: 某些目录没有读写权限 - **解决方案**: 确保项目目录有正确的读写权限 ### 12.2 页面路由配置问题 - **问题**: 新增页面后无法访问 - **解决方案**: 在 pages.json 中添加页面路由配置 ### 12.3 分包加载问题 - **问题**: 应用体积过大,无法上传到小程序平台 - **解决方案**: 使用分包加载,将页面划分到不同的分包中 ### 12.4 目录结构混乱 - **问题**: 目录结构不清晰,难以维护 - **解决方案**: 重新组织目录结构,遵循模块化原则 ## 13. 参考资源 - [UniApp 官方文档](https://uniapp.dcloud.io/) - [Vue 官方文档](https://cn.vuejs.org/) - [Vuex 官方文档](https://vuex.vuejs.org/zh/) - [微信小程序开发文档](https://developers.weixin.qq.com/miniprogram/dev/framework/) ## 14. 总结 本文档描述了 CRMEB 项目中 UniApp 移动端的目录结构,包括各目录的功能、文件组织方式等。遵循本文档的目录结构规范,可以提高项目的可维护性和可扩展性,便于团队协作开发。 随着业务的发展和技术的演进,目录结构也可能需要不断优化和调整,以适应新的业务需求和技术挑战。 ---