项目管理模块全量分析报告
项目管理模块全量分析报告
1. 分析范围与入口
- 主要入口页面:
themes/default/Distributors/project/create.html - 主控制器:
Banyan/Lib/Action/Distributors/ProjectAction.class.php - 关联控制器:
- Banyan/Lib/Action/Distributors/ProjectTenantAction.class.php
- Banyan/Lib/Action/Worker/ProjectAction.class.php
- Banyan/Lib/Action/Cron/TenantReminderAction.class.php
- 主要模型目录:
Banyan/Lib/Model/Project*.class.php
本报告围绕 distributors/project/create.html,覆盖项目管理在分销端、员工端、租户管理与定时提醒中的完整业务链路,并汇总可反推的数据表与字段。
2. 页面与业务定位
create.html 是“新增项目”页面,表单提交到 project/create,用于在 project 主表创建项目基础档案。
页面采集字段包括:
project_nameproject_type(property物业管理 /security法律管理)project_subtype(由前端联动)project_addresscontact_namecontact_mobilecontact_telstart_dateend_dateproject_desc
前端逻辑:
- 根据
project_type动态填充子类型选项; - 提交前做“项目类型必选”校验;
- 真实字段安全与必填以服务端校验为准。
3. 核心流程(Create 全链路)
3.1 请求与路由
- 页面表单:
POST U('project/create') - 进入:
Distributors/ProjectAction::create()
3.2 控制器处理
create() 的 POST 分支调用 createCheck():
checkFields(..., $this->create_fields)做白名单过滤;- 强制补充
shop_id = $this->shop_id(租户隔离关键字段); - 校验
project_name与project_type非空; - 写入
create_time = NOW_TIME; D('Project')->add($data)入库。
成功返回 byMsg('添加成功', U('project/index')),失败返回 byMsg('操作失败')。
3.3 后续业务流转
新增项目后,主要进入以下运营链路:
- 列表管理:
ProjectAction::index()(查询、筛选、分页、统计员工/租户数量) - 项目详情:
ProjectAction::detail()(统计门卫/车辆/巡岗等日志) - 项目设置:
ProjectAction::setting()(项目员工、租户、制度规则) - 租户管理:
ProjectTenantAction(合同、付租、水电、车辆、文档) - 员工端执行:
Worker/ProjectAction(门卫登记、巡岗、考勤、日志、图片等) - 定时提醒:
Cron/TenantReminderAction(房租到期、水电欠费提醒)
4. 权限与隔离机制
4.1 分销端(Distributors)
- 核心隔离字段:
shop_id - 典型校验模式:读取记录后检查
record.shop_id == $this->shop_id - 删除项目为软删:
closed = 1
4.2 员工端(Worker)
- 菜单能力受员工权限位控制:
is_project - 业务访问受项目关系控制:
project_worker(project_id, worker_id)关联校验
4.3 潜在权限风险点
- 若某接口仅按主键读取而未追加
shop_id/project_worker校验,可能产生越权风险; - 目前主要主链路已做校验,新增接口时应复用同一校验范式。
5. 数据表总览(Model 映射)
以下为代码中 Project*.Model 的主键与物理表映射:
| Model | pk | tableName |
|---|---|---|
ProjectModel | project_id | project |
ProjectworkerModel | id | project_worker |
ProjecttenantModel | tenant_id | project_tenant |
ProjecttenantcontractModel | contract_id | project_tenant_contract |
ProjecttenantpaymentModel | payment_id | project_tenant_payment |
ProjecttenantutilityModel | utility_id | project_tenant_utility |
ProjecttenantvehicleModel | vehicle_id | project_tenant_vehicle |
ProjecttenantdocumentModel | doc_id | project_tenant_document |
ProjectaccesslogModel | log_id | project_access_log |
ProjectvehiclelogModel | log_id | project_vehicle_log |
ProjectpatrollogModel | log_id | project_patrol_log |
ProjectattendanceModel | attendance_id | project_attendance |
ProjectworklogModel | log_id | project_work_log |
ProjectimageModel | image_id | project_image |
ProjectruleModel | rule_id | project_rule |
ProjectreportextraModel | id | project_report_extra |
ProjectdocumentModel | doc_id | project_document |
ProjectdailylogModel | log_id | project_daily_log |
ProjectsalaryModel | salary_id | project_salary |
ProjectsystemModel | system_id | project_system |
ProjectinspectionphotoModel | photo_id | project_inspection_photo |
ProjectworkerdocumentModel | doc_id | project_worker_document |
6. 核心表与字段(按代码读写反推)
说明:仓库未发现完整project*建表 SQL,以下字段来自 Action 的add/save/where与表单字段反推,已覆盖主要业务。
6.1 project(项目主表)
核心字段:
project_id(PK)shop_id(所属公司)project_nameproject_typeproject_subtypeproject_statusproject_addressproject_desccontact_namecontact_mobilecontact_telstart_dateend_dateclosedcreate_timeupdate_time
6.2 project_worker(项目员工关系)
核心字段:
id(PK)project_idworker_idrole(如普通/管理员)worker_nopositioncheck_in_timecheck_out_timestatusremarkcreate_time
6.3 project_tenant(租户主表)
核心字段:
tenant_id(PK)project_idtenant_nametenant_typeid_cardmobileteladdressrent_start_daterent_end_daterent_payment_typerent_paid_untilmonthly_rent(分)deposit(分)statusremarkcreate_timeupdate_time
6.4 租户扩展业务表
project_tenant_contract:合同编号/类型/期限/金额/附件/签字图/状态project_tenant_payment:付款月份/金额/日期/方式/凭证/状态project_tenant_utility:水电气等费用、月份、总额、缴费状态project_tenant_vehicle:车牌、车型、品牌、车位、状态project_tenant_document:证件类型、标题、文件、签字、有效期、状态
6.5 现场日志与报表相关
project_access_log:人员进出登记project_vehicle_log:车辆进出登记project_patrol_log:巡岗记录project_attendance:考勤记录project_work_log:工作日志project_image:项目图片归档(含image_category、related_id)project_rule:项目制度规则project_report_extra:报表补充信息
7. 关键业务逻辑说明
7.1 金额存储规范
租户相关金额字段在控制器中按“元转分”入库,例如:
monthly_rent = (int)($input * 100)deposit = (int)($input * 100)- 其他付款/费用字段同理
这说明数据库金额字段主要按“分”为整数存储,展示层再除以 100。
7.2 项目员工扩展字段兼容逻辑
addWorker 中存在“先带扩展字段写入,失败后移除扩展字段再写入”的降级逻辑,说明现网可能存在库结构不一致:
- 第一阶段写入:
worker_no/position/check_in_time/check_out_time/remark - 失败降级:仅保留核心字段
project_id/worker_id/role/create_time
这是兼容旧库的兜底策略,也提示了表结构治理需求。
7.3 图片存储策略
门卫/车辆登记提交时支持多图,先写日志表,再拆分写入 project_image:
image_category区分类别(如 access/vehicle)related_id回链原日志主键
8. 定时任务与消息联动
Cron/TenantReminderAction 每日执行:
- 房租到期提醒(按
rent_paid_until命中) - 水电费提醒(按
project_tenant_utility.payment_status=0与月份范围)
通知路径:
project_tenant/project_tenant_utility
-> project_worker(取项目员工)
-> shop_worker.user_id
-> message(站内消息)
同时做“当天去重”检查,避免重复推送。
9. 现状评估与问题清单
9.1 已具备
- 以
project为核心的模块化设计完整; - 分销端 + 员工端 + 租户子模块 + 定时提醒形成闭环;
- 多数关键接口具备归属校验(
shop_id或project_worker)。
9.2 主要问题
- 仓库内缺失
project*系列表结构 SQL,迁移与部署可追溯性不足; - 控制器直接承载较多业务逻辑,Service 层缺位;
- 局部存在“字段不存在则降级写入”的历史兼容分支,说明环境间 schema 不统一。
10. 建议(落地优先级)
P0(先做)
- 补齐并统一
project*建表/升级 SQL(含索引、默认值、注释); - 形成“版本化迁移脚本”,消除线上表结构漂移;
- 为关键权限接口补全自动化回归测试(越权、跨 shop、跨 project)。
P1
- 抽离
ProjectService/ProjectTenantService,沉淀校验与事务逻辑; - 统一金额处理与日期处理工具,减少控制器重复代码。
P2
- 建立模块数据字典(字段含义、枚举值、单位、索引说明);
- 对接审计日志(操作人、前后值、来源 IP)。
11. 结论
distributors/project/create.html 不是孤立页面,而是“项目主档创建入口”。其后连接了项目人员、租户经营、现场日志、员工执行与到期提醒等完整运营体系。当前最大的工程风险不在功能缺失,而在“数据库结构文档与迁移脚本缺失导致的环境一致性风险”。建议优先补齐 schema 资产,再推进服务层重构与测试加固。
