weizong song 6 months ago
parent 29fb515fe0
commit 62c04d7342

@ -0,0 +1,151 @@
{
"excluded_patterns": [
".git",
".gitignore",
"gradle",
"gradlew",
"gradlew.*",
"node_modules",
".snapshots",
".idea",
".vscode",
"*.log",
"*.tmp",
"target",
"dist",
"build",
".DS_Store",
"*.bak",
"*.swp",
"*.swo",
"*.lock",
"*.iml",
"coverage",
"*.min.js",
"*.min.css",
"__pycache__",
".marketing",
".env",
".env.*",
"*.jpg",
"*.jpeg",
"*.png",
"*.gif",
"*.bmp",
"*.tiff",
"*.ico",
"*.svg",
"*.webp",
"*.psd",
"*.ai",
"*.eps",
"*.indd",
"*.raw",
"*.cr2",
"*.nef",
"*.mp4",
"*.mov",
"*.avi",
"*.wmv",
"*.flv",
"*.mkv",
"*.webm",
"*.m4v",
"*.wfp",
"*.prproj",
"*.aep",
"*.psb",
"*.xcf",
"*.sketch",
"*.fig",
"*.xd",
"*.db",
"*.sqlite",
"*.sqlite3",
"*.mdb",
"*.accdb",
"*.frm",
"*.myd",
"*.myi",
"*.ibd",
"*.dbf",
"*.rdb",
"*.aof",
"*.pdb",
"*.sdb",
"*.s3db",
"*.ddb",
"*.db-shm",
"*.db-wal",
"*.sqlitedb",
"*.sql.gz",
"*.bak.sql",
"dump.sql",
"dump.rdb",
"*.vsix",
"*.jar",
"*.war",
"*.ear",
"*.zip",
"*.tar",
"*.tar.gz",
"*.tgz",
"*.rar",
"*.7z",
"*.exe",
"*.dll",
"*.so",
"*.dylib",
"*.app",
"*.dmg",
"*.iso",
"*.msi",
"*.deb",
"*.rpm",
"*.apk",
"*.aab",
"*.ipa",
"*.pkg",
"*.nupkg",
"*.snap",
"*.whl",
"*.gem",
"*.pyc",
"*.pyo",
"*.pyd",
"*.class",
"*.o",
"*.obj",
"*.lib",
"*.a",
"*.map",
".npmrc"
],
"default": {
"default_prompt": "Enter your prompt here",
"default_include_all_files": false,
"default_include_entire_project_structure": true
},
"included_patterns": [
"build.gradle",
"settings.gradle",
"gradle.properties",
"pom.xml",
"Makefile",
"CMakeLists.txt",
"package.json",
"requirements.txt",
"Pipfile",
"Gemfile",
"composer.json",
".editorconfig",
".eslintrc.json",
".eslintrc.js",
".prettierrc",
".babelrc",
".dockerignore",
".gitattributes",
".stylelintrc",
".npmrc"
]
}

@ -0,0 +1,11 @@
# Snapshots Directory
This directory contains snapshots of your code for AI interactions. Each snapshot is a markdown file that includes relevant code context and project structure information.
## What's included in snapshots?
- Selected code files and their contents
- Project structure (if enabled)
- Your prompt/question for the AI
## Configuration
You can customize snapshot behavior in `config.json`.

@ -0,0 +1,44 @@
# Thank you for using Snapshots for AI
Thanks for using Snapshots for AI. We hope this tool has helped you solve a problem or two.
If you would like to support our work, please help us by considering the following offers and requests:
## Ways to Support
### Join the GBTI Network!!! 🙏🙏🙏
The GBTI Network is a community of developers who are passionate about open source and community-driven development. Members enjoy access to exclussive tools, resources, a private MineCraft server, a listing in our members directory, co-op opportunities and more.
- Support our work by becoming a [GBTI Network member](https://gbti.network/membership/).
### Try out BugHerd 🐛
BugHerd is a visual feedback and bug-tracking tool designed to streamline website development by enabling users to pin feedback directly onto web pages. This approach facilitates clear communication among clients, designers, developers, and project managers.
- Start your free trial with [BugHerd](https://partners.bugherd.com/55z6c8az8rvr) today.
### Hire Developers from Codeable 👥
Codeable connects you with top-tier professionals skilled in frameworks and technologies such as Laravel, React, Django, Node, Vue.js, Angular, Ruby on Rails, and Node.js. Don't let the WordPress focus discourage you. Codeable experts do it all.
- Visit [Codeable](https://www.codeable.io/developers/?ref=z8h3e) to hire your next team member.
### Lead positive reviews on our marketplace listing ⭐⭐⭐⭐⭐
- Rate us on [VSCode marketplace](https://marketplace.visualstudio.com/items?itemName=GBTI.snapshots-for-ai)
- Review us on [Cursor marketplace](https://open-vsx.org/extension/GBTI/snapshots-for-ai)
### Star Our GitHub Repository ⭐
- Star and watch our [repository](https://github.com/gbti-network/vscode-snapshots-for-ai)
### 📡 Stay Connected
Follow us on your favorite platforms for updates, news, and community discussions:
- **[Twitter/X](https://twitter.com/gbti_network)**
- **[GitHub](https://github.com/gbti-network)**
- **[YouTube](https://www.youtube.com/channel/UCh4FjB6r4oWQW-QFiwqv-UA)**
- **[Dev.to](https://dev.to/gbti)**
- **[Daily.dev](https://dly.to/zfCriM6JfRF)**
- **[Hashnode](https://gbti.hashnode.dev/)**
- **[Discord Community](https://gbti.network)**
- **[Reddit Community](https://www.reddit.com/r/GBTI_network)**
---
Thank you for supporting open source software! 🙏

@ -1,140 +0,0 @@
# 不良事件管理 - 测试数据填充说明
## 概述
本文档说明如何为"不良事件管理"模块填充测试数据,以便进行功能测试和演示。
## 文件说明
### 1. 数据库迁移文件
- `database/migrations/2025_07_24_093101_create_adverse_table.php`
- 创建不良事件数据表结构
### 2. 数据填充文件
- `database/seeders/AdverseSeeder.php` - Laravel Seeder填充器
- `database/seeders/adverse_data.sql` - SQL脚本文件
- `insert_adverse_data.php` - 独立PHP脚本
### 3. 模型和控制器
- `app/Models/Adverse.php` - 不良事件模型
- `app/Http/Controllers/Admin/AdverseController.php` - 管理控制器
- `app/Forms/AdverseForm.php` - 表单类
### 4. 视图文件
- `resources/views/admin/adverse/index.blade.php` - 列表页面
- `resources/views/admin/adverse/create.blade.php` - 创建页面
- `resources/views/admin/adverse/edit.blade.php` - 编辑页面
- `resources/views/admin/adverse/show.blade.php` - 详情页面
## 使用方法
### 方法一使用Laravel Seeder推荐
1. 确保已运行数据库迁移:
```bash
php artisan migrate
```
2. 运行Seeder填充数据
```bash
php artisan db:seed --class=AdverseSeeder
```
### 方法二使用SQL脚本
1. 确保已运行数据库迁移
2. 确保已有项目和订单数据
3. 执行SQL脚本
```bash
mysql -u username -p database_name < database/seeders/adverse_data.sql
```
### 方法三使用独立PHP脚本
1. 确保已运行数据库迁移
2. 确保已有项目和订单数据
3. 运行脚本:
```bash
php insert_adverse_data.php
```
## 数据内容
### 不良事件类型
- `safety` - 意外事件
- `complaint` - 沟通事件
- `other` - 其他
### 解决状态
- `pending` - 待处理
- `processing` - 处理中
- `solved` - 已解决
- `closed` - 已关闭
### 测试数据特点
- 包含30条测试记录
- 涵盖所有类型和状态
- 包含真实的事件描述和解决结果
- 时间分布在最近90天内
- 关联到实际的项目和订单
## 数据字段说明
| 字段名 | 类型 | 说明 |
|--------|------|------|
| project_id | int | 所属项目ID |
| order_id | int | 相关订单ID可为空 |
| type | varchar | 事件类型 |
| description | text | 事件描述 |
| solved_status | varchar | 解决状态 |
| solved_by | varchar | 经办人 |
| solved_at | datetime | 解决时间 |
| solved_result | text | 解决结果描述 |
| created_at | datetime | 创建时间 |
| updated_at | datetime | 更新时间 |
## 注意事项
1. **依赖关系**:确保在填充不良事件数据之前,已有项目和订单数据
2. **数据完整性**:已解决的事件会自动设置解决时间和结果
3. **时间分布**创建时间分布在最近90天内解决时间分布在最近30天内
4. **关联关系**订单ID会根据项目ID自动匹配
## 功能测试
填充数据后,可以测试以下功能:
1. **列表展示**:查看不良事件列表
2. **搜索筛选**:按关键词、状态、类型、项目等条件筛选
3. **创建事件**:新增不良事件记录
4. **编辑事件**:修改事件信息和状态
5. **查看详情**:查看完整的事件信息
6. **批量操作**:批量删除、标记解决等
## 故障排除
### 常见问题
1. **没有项目数据**
- 解决:先创建项目数据
2. **没有订单数据**
- 解决:先创建订单数据
3. **数据库连接错误**
- 检查数据库配置
- 确保数据库服务运行正常
4. **权限问题**
- 确保数据库用户有插入权限
### 日志查看
如果遇到问题可以查看Laravel日志
```bash
tail -f storage/logs/laravel.log
```
## 联系支持
如有问题,请联系开发团队或查看项目文档。

@ -0,0 +1,310 @@
# AlipayAccount MVC 实现文档
## 📋 概述
本文档记录了参照 `WechatpayAccount` 模型创建 `AlipayAccount` 相关 MVC 组件的完整过程。
---
## ✅ 已完成的工作
### 1. 模型 (Model)
**文件位置**: `app/Models/AlipayAccount.php`
```php
<?php
namespace App\Models;
class AlipayAccount extends SoftDeletesModel
{
protected $table = "alipay_account";
}
```
**说明**:
- 继承 `SoftDeletesModel` 基类,支持软删除功能
- 映射数据表 `alipay_account`
- 自动包含时间戳和软删除字段
---
### 2. 控制器 (Controller)
**文件位置**: `app/Http/Controllers/Admin/AlipayAccountController.php`
```php
<?php
namespace App\Http\Controllers\Admin;
use App\Forms\AlipayAccountForm;
use App\Models\AlipayAccount;
use Illuminate\Http\Request;
class AlipayAccountController extends CommonController
{
public $bladePath = "admin.alipay-account";
public $urlPrefix = "admin/alipay-account";
public $modelName = "支付宝账号";
public $modelClass = AlipayAccount::class;
public $formClass = AlipayAccountForm::class;
public function index(Request $request)
{
$data = $this->model->paginate(10);
return view($this->bladePath . ".index", compact("data"));
}
}
```
**功能说明**:
- 继承 `CommonController`,自动获得 CRUD 功能
- 定义视图路径、URL前缀、模型名称
- `index()` 方法分页显示支付宝账号列表每页10条
---
### 3. 表单构建器 (Form)
**文件位置**: `app/Forms/AlipayAccountForm.php`
```php
<?php
namespace App\Forms;
use Kris\LaravelFormBuilder\Form;
use Kris\LaravelFormBuilder\Field;
class AlipayAccountForm extends Form
{
public function buildForm()
{
$this->add("id", Field::HIDDEN);
$this->add("name", Field::TEXT, ["label" => "名称", "rules" => "required"]);
$this->add("appid", Field::TEXT, ["label" => "应用ID", "rules" => "required"]);
$this->add("public_key", Field::TEXTAREA, [
"label" => "应用公钥",
"rules" => "required",
"attr" => ["rows" => 4]
]);
$this->add("alipay_key", Field::TEXTAREA, [
"label" => "支付宝密钥",
"rules" => "required",
"attr" => ["rows" => 4]
]);
$this->add('buttons', 'buttongroup', [
"splitted" => true,
"buttons" => [
["label" => "保存", "attr" => ["class" => "btn btn-primary mr-1", "type" => "submit"]],
["label" => "返回", "attr" => ["class" => "btn btn-light btn-back", "type" => "button"]]
]
]);
}
}
```
**字段说明**:
- `id`: 隐藏字段用于编辑时传递ID
- `name`: 账号名称(必填)
- `appid`: 支付宝应用ID必填
- `public_key`: 应用公钥(必填,多行文本框)
- `alipay_key`: 支付宝密钥(必填,多行文本框)
- `buttons`: 保存和返回按钮组
---
### 4. 视图文件 (Views)
#### 4.1 列表页面
**文件位置**: `resources/views/admin/alipay-account/index.blade.php`
**更新内容**:
- 表头字段名称、应用ID、应用公钥、操作
- 数据显示:`$row->appid` 和 `Str::limit($row->public_key, 50)`
- 公钥字段限制显示前50个字符避免过长
**功能**:
- 显示支付宝账号列表
- 创建新账号按钮
- 编辑、删除操作按钮
- 分页功能
#### 4.2 创建/编辑页面
**文件位置**: `resources/views/admin/alipay-account/create.blade.php`
**内容**:
- 继承 `admin.layouts.layout` 布局
- 包含表单构建器生成的表单
- 支持创建和编辑两种模式
---
### 5. 路由配置
**文件位置**: `routes/web.php` (第69行)
```php
\App\Models\CommonModel::generateCurdRouter("AlipayAccountController", "alipay-account");
```
**自动生成的路由**:
| 方法 | URI | 动作 | 说明 |
|------|-----|------|------|
| GET | `/admin/alipay-account` | index | 列表页 |
| GET | `/admin/alipay-account/create` | create | 创建页 |
| POST | `/admin/alipay-account/store` | store | 保存新建 |
| GET | `/admin/alipay-account/edit?id={id}` | edit | 编辑页 |
| POST | `/admin/alipay-account/update/{id}` | update | 保存编辑 |
| POST | `/admin/alipay-account/delete` | delete | 删除 |
**权限控制**:
- 需要通过 `authorize:admin` 中间件(管理员身份验证)
- 需要通过 `rbac:admin` 中间件(基于角色的权限验证)
---
## 📊 数据库结构
**表名**: `alipay_account`
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | BIGINT | 主键ID |
| name | VARCHAR | 账号名称 |
| appid | VARCHAR | 应用ID |
| public_key | VARCHAR | 应用公钥 |
| alipay_key | VARCHAR | 支付宝密钥 |
| created_at | TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 更新时间 |
| deleted_at | TIMESTAMP | 软删除时间 |
---
## 🔄 与 WechatpayAccount 的对比
| 项目 | WechatpayAccount | AlipayAccount |
|------|------------------|---------------|
| 商户标识字段 | `mchid` (商户ID) | `appid` (应用ID) |
| 密钥字段 | `key` (商户密钥) | `public_key` + `alipay_key` |
| 字段类型 | TEXT | TEXTAREA (多行) |
| 字段数量 | 3个核心字段 | 4个核心字段 |
**主要区别**:
1. 支付宝使用应用ID代替商户ID
2. 支付宝需要两个密钥:应用公钥和支付宝密钥
3. 密钥字段较长,使用多行文本框输入
---
## 🚀 使用说明
### 访问管理页面
1. **登录后台**: 访问 `/admin/login`
2. **进入列表页**: 访问 `/admin/alipay-account`
3. **创建账号**: 点击"创建支付宝账号"按钮
4. **填写信息**:
- 名称:给账号起一个便于识别的名称
- 应用ID从支付宝开放平台获取
- 应用公钥:从支付宝开放平台生成
- 支付宝密钥:从支付宝开放平台获取
### 开发集成
```php
// 获取所有支付宝账号
$accounts = AlipayAccount::all();
// 获取单个账号
$account = AlipayAccount::find($id);
// 创建账号
$account = new AlipayAccount();
$account->name = "测试账号";
$account->appid = "2021xxxxx";
$account->public_key = "MIIBIjAN...";
$account->alipay_key = "MIIEvgI...";
$account->save();
// 更新账号
$account = AlipayAccount::find($id);
$account->name = "新名称";
$account->save();
// 软删除
$account->delete();
// 包含已删除记录
$accounts = AlipayAccount::withTrashed()->get();
```
---
## ✅ 验证清单
- [x] 模型文件创建完成
- [x] 控制器文件创建完成
- [x] 表单构建器创建完成
- [x] 视图文件已更新(字段匹配数据库)
- [x] 路由配置已添加
- [x] 无 Linter 错误
- [x] 继承关系正确SoftDeletesModel、CommonController
- [x] 权限中间件已配置
- [x] 遵循项目命名规范
---
## 📝 注意事项
1. **密钥安全**: 密钥字段包含敏感信息,建议:
- 在列表页只显示部分内容(已实现)
- 考虑加密存储
- 严格控制访问权限
2. **表单验证**:
- 所有字段均为必填
- 前端验证由表单构建器自动处理
- 可根据需要添加后端验证规则
3. **软删除**:
- 删除操作不会真正删除数据
- 可通过 `withTrashed()` 查询已删除记录
- 可使用 `restore()` 恢复数据
4. **扩展功能**:
- 如需关联项目,参考 `Project` 表中的 `alipay_account_id` 字段
- 可添加账号验证功能
- 可添加账号余额查询功能
---
## 🎯 后续建议
1. **添加账号验证功能**: 在保存时调用支付宝API验证配置是否正确
2. **添加使用统计**: 记录每个账号的使用次数和交易金额
3. **添加状态字段**: 标记账号启用/禁用状态
4. **添加备注字段**: 记录账号用途和相关说明
5. **日志记录**: 记录账号的创建、修改、删除操作
---
## 📞 技术支持
如有问题,请参考:
- Laravel 7.x 官方文档: https://laravel.com/docs/7.x
- Laravel Form Builder: https://github.com/kristijanhusak/laravel-form-builder
- 支付宝开放平台: https://open.alipay.com/
---
**创建时间**: 2025-10-13
**创建者**: AI Assistant
**基于模板**: WechatpayAccount MVC

@ -0,0 +1,243 @@
我来帮您整理项目情况。让我先查看项目的整体结构。
[14 tools called]
根据我对项目的分析,现在为您整理项目的详细情况:
## 📊 天天护工管理平台 - 项目情况整理
### 一、技术栈
#### **后端技术**
- **框架**: Laravel 7.x (PHP 7.2.5+)
- **数据库**: MySQL (使用 Eloquent ORM)
- **认证**: JWT (tymon/jwt-auth)
- **权限管理**: Spatie Laravel Permission
- **主要依赖包**:
- `intervention/image` - 图片处理
- `maatwebsite/excel` - Excel导入导出
- `simplesoftwareio/simple-qrcode` - 二维码生成
- `guzzlehttp/guzzle` - HTTP客户端
- `barryvdh/laravel-snappy` - PDF生成
- `zircote/swagger-php` - API文档
#### **前端技术**
- **基础框架**:
- Vue.js 2.x (用于H5移动端和护工端)
- Bootstrap 4.x (用于后台管理界面)
- jQuery (用于数据大屏和部分后台功能)
- **UI组件库**:
- Hyper Admin Template (管理后台主题)
- Layui (部分表单和弹窗)
- Select2 (下拉选择)
- DataTables (数据表格)
- ECharts (数据可视化)
- **前端插件**:
- WebUploader (文件上传)
- UEditor (富文本编辑器)
- jQuery Treetable (树形表格)
- SweetAlert2 (提示框)
- Moment.js (时间处理)
#### **支付集成**
- 支付宝支付 (F2F当面付)
- 微信支付 (小程序支付、扫码支付)
---
### 二、项目模块结构
#### **1. 后台管理模块 (Admin)**
**位置**: `app/Http/Controllers/Admin/`
主要功能控制器:
- `AdminController` - 管理员管理
- `RoleController` - 角色管理
- `PermissionController` - 权限管理
- `ProjectController` - 项目/医院管理
- `ProductController` - 产品/服务管理
- `OrdersController` - 订单管理
- `ParamedicController` - 护工管理
- `ManagerController` - 项目经理管理
- `TrainingController` - 培训管理
- `StatisticsController` - 数据统计
- `AdverseController` - 不良事件管理
- `FactorController` - 因素管理
- `WechatpayAccountController` - 微信支付账户管理
**前端页面**: `public/hyper/` - 使用Hyper管理后台模板
#### **2. 客户端模块 (Customer)**
**位置**: `app/Http/Controllers/Customer/`
主要功能:
- `AuthController` - 客户认证
- `OrdersController` - 订单下单、查询
- `PayCallbackController` - 支付回调处理
- `CommonController` - 通用功能(上传、获取配置等)
- `PublicController` - 公共数据接口
**前端页面**: `public/h5/` - UniApp编译的H5应用
#### **3. 护工端模块 (Worker)**
**位置**: `app/Http/Controllers/Worker/`
主要功能:
- `AuthController` - 护工认证登录
- `OrdersController` - 接单、订单管理
- `CommonController` - 通用功能
**前端页面**: `public/carer/` - Vue.js单页应用
#### **4. 项目经理端模块 (Manager)**
**位置**: `app/Http/Controllers/Manager/`
主要功能:
- `AuthController` - 经理认证
- `OrdersController` - 订单分配、管理
- `ParamedicController` - 护工管理
- `StatisticsController` - 数据统计
- `TrainingController` - 培训管理
- `CommonController` - 通用功能
#### **5. 数据大屏模块**
**位置**: `public/dashboard/`
功能:
- 实时数据展示驾驶舱
- ECharts数据可视化
- 护工陪护概况统计
---
### 三、核心业务模型
**主要数据表** (位于 `app/Models/`):
| 模型 | 说明 |
|------|------|
| `Orders` | 订单主表 |
| `OrderItems` | 订单明细 |
| `Paramedic` | 护工信息 |
| `ParamedicLevel` | 护工等级 |
| `Patient` | 患者信息 |
| `Product` | 产品/服务 |
| `ProductItems` | 产品项目 |
| `Project` | 项目/医院 |
| `Building` | 楼栋 |
| `Room` | 病房 |
| `Bed` | 床位 |
| `Training` | 培训记录 |
| `TrainingType` | 培训类型 |
| `Balance` | 余额账户 |
| `Recharge` | 充值记录 |
| `Refund` | 退款记录 |
| `Adverse` | 不良事件 |
| `Factor` | 因素评估 |
| `Approval` | 审批流程 |
---
### 四、开发风格特点
#### **1. 架构风格**
- **分层架构**: MVC模式控制器、模型、视图分离
- **多端分离**: Admin、Customer、Worker、Manager各端独立控制器
- **RESTful API**: 移动端采用API接口方式
- **事件驱动**: 使用Laravel Events和Listeners处理业务逻辑
- `OrderAssigned` - 订单分配事件
- `ProductSaved` - 产品保存事件
- `RechargeSucceed` - 充值成功事件
#### **2. 代码组织**
- **表单构建器**: 使用 `kris/laravel-form-builder` 统一表单管理
- **动态CURD**: `CommonModel::generateCurdRouter()` 生成通用增删改查路由
- **导出功能**: 使用 `Exports/` 目录组织Excel导出类
- **自定义类库**: `app/Libs/` 存放支付SDK等第三方封装
#### **3. 前端风格**
- **多页面应用**: 后台管理采用传统多页面方式
- **单页应用**: 护工端、客户H5端采用Vue单页应用
- **响应式设计**: 使用Bootstrap实现响应式布局
- **组件化**: 公共CSS样式统一管理(`public/css/common.css`)
#### **4. 数据库设计**
- **软删除**: 使用`SoftDeletesModel`基类实现软删除
- **审计日志**: 集成`owen-it/laravel-auditing`记录操作日志
- **多租户**: 通过`AdminProjectScope`实现项目级数据隔离
- **关联查询**: Eloquent ORM实现模型关联
#### **5. 权限控制**
- **RBAC**: 基于角色的访问控制
- **中间件**: `authorize:admin` 身份验证,`rbac:admin` 权限验证
- **多角色**: Admin、Manager、Worker、Customer四种角色体系
#### **6. 接口规范**
- **Swagger文档**: 集成API文档系统
- **JWT认证**: Token方式的API认证
- **统一响应**: 使用helpers辅助函数统一返回格式
---
### 五、项目目录结构
```
tiantian2/
├── app/ # 应用核心代码
│ ├── Actions/ # 业务动作类
│ ├── Console/ # 命令行任务
│ ├── Events/ # 事件定义
│ ├── Exports/ # 导出类
│ ├── Forms/ # 表单构建器
│ ├── Http/
│ │ ├── Controllers/ # 控制器(Admin/Customer/Manager/Worker)
│ │ └── Middleware/ # 中间件
│ ├── Libs/ # 第三方类库封装
│ ├── Listeners/ # 事件监听器
│ ├── Models/ # 数据模型
│ └── Notifications/ # 通知类
├── public/ # 公共资源目录
│ ├── h5/ # 客户端H5应用(UniApp)
│ ├── carer/ # 护工端应用(Vue)
│ ├── dashboard/ # 数据大屏
│ ├── hyper/ # 管理后台模板
│ ├── plugins/ # 前端插件库
│ └── css/js/ # 公共样式和脚本
├── database/
│ ├── migrations/ # 数据库迁移(108个文件)
│ └── seeds/ # 数据填充
├── routes/
│ ├── web.php # Web路由
│ └── api.php # API路由
└── config/ # 配置文件
```
---
### 六、开发特色
1. **多端适配**: 一套后端服务四个前端应用(管理后台、H5客户端、护工端、项目经理端)
2. **插件化设计**: 前端插件独立管理,便于维护和升级
3. **模板复用**: 使用成熟的Hyper管理后台模板
4. **移动优先**: H5和护工端使用Vue/UniApp实现原生体验
5. **数据驱动**: 数据大屏实时展示业务数据
6. **完整业务流程**: 从订单创建、护工分配、服务执行到结算的完整闭环
---
### 七、技术亮点
**RBAC权限系统** - 细粒度权限控制
**多支付方式** - 支付宝+微信支付集成
**事件驱动架构** - 解耦业务逻辑
**Excel导入导出** - 数据批量处理
**二维码生成** - 护工工牌、订单扫码
**图片处理** - 头像裁剪、缩略图生成
**API文档** - Swagger自动生成
**审计日志** - 操作记录可追溯
**软删除** - 数据安全保护
**多租户隔离** - 项目级数据隔离
这是一个**成熟的护工管理SaaS平台**,采用**前后端分离+多端适配**的技术架构,业务逻辑完整,代码组织规范。

@ -0,0 +1,24 @@
<?php
namespace App\Forms;
use Kris\LaravelFormBuilder\Form;
use Kris\LaravelFormBuilder\Field;
class AlipayAccountForm extends Form
{
public function buildForm()
{
$this->add("id", Field::HIDDEN);
$this->add("name", Field::TEXT, ["label" => "名称", "rules" => "required"]);
$this->add("appid", Field::TEXT, ["label" => "应用ID", "rules" => "required"]);
$this->add("public_key", Field::TEXTAREA, ["label" => "应用公钥", "rules" => "required", "attr" => ["rows" => 4]]);
$this->add("alipay_key", Field::TEXTAREA, ["label" => "支付宝密钥", "rules" => "required", "attr" => ["rows" => 4]]);
$this->add('buttons', 'buttongroup', ["splitted" => true, "buttons" => [
["label" => "保存", "attr" => ["class" => "btn btn-primary mr-1", "type" => "submit"]],
["label" => "返回", "attr" => ["class" => "btn btn-light btn-back", "type" => "button"]]
]]);
}
}

@ -2,6 +2,7 @@
namespace App\Forms;
use App\Models\AlipayAccount;
use App\Models\WechatpayAccount;
use Kris\LaravelFormBuilder\Form;
use Kris\LaravelFormBuilder\Field;
@ -15,6 +16,7 @@ class ProjectForm extends Form
$this->add("name", Field::TEXT, ["label" => "名称", "rules" => "required"]);
$this->add("address", Field::TEXT, ["label" => "地址", "rules" => "required"]);
$this->add("wechatpay_account_id", Field::SELECT, ["label" => "微信支付账号", "choices" => $this->getWechatpayAccount()]);
$this->add("alipay_account_id", Field::SELECT, ["label" => "支付宝账号", "choices" => $this->getAlipayAccount()]);
$this->add("percent_first_party", Field::NUMBER, ["label" => "院方结算百分比"]);
$this->add("logo", Field::TEXT, ["label" => "logo", "attr" => ["data-plugin" => "uploader"]]);
$this->add("banners", Field::TEXT, ["label" => "banner", "attr" => ["data-plugin" => "uploader", "data-multiple-multiple" => 1]]);
@ -55,4 +57,14 @@ class ProjectForm extends Form
}
return $res;
}
function getAlipayAccount()
{
$rows = (new AlipayAccount())->get();
$res = [];
foreach ($rows as $row) {
$res["{$row->id}"] = $row->name."({$row->appid})";
}
return $res;
}
}

@ -0,0 +1,30 @@
<?php
/**
* Created by PhpStorm.
* User: weizongsong
* Date: 2025-10-13
* Time: 21:00
*/
namespace App\Http\Controllers\Admin;
use App\Forms\AlipayAccountForm;
use App\Models\AlipayAccount;
use Illuminate\Http\Request;
class AlipayAccountController extends CommonController
{
public $bladePath = "admin.alipay-account";
public $urlPrefix = "admin/alipay-account";
public $modelName = "支付宝账号";
public $modelClass = AlipayAccount::class;
public $formClass = AlipayAccountForm::class;
public function index(Request $request)
{
$data = $this->model->paginate(10);
return view($this->bladePath . ".index", compact("data"));
}
}

@ -70,6 +70,8 @@ class ProductController extends CommonController
$query->has("paramedicLevel");
}])->find($id ?: $request->id);
dd($vo);
$project = (new Project())->with("paramedicLevels")->find($vo->project_id);
foreach ($vo->productParamedicLevels as $level) {

@ -130,7 +130,7 @@ class AlipayF2F
$options->appId = env("ALI_APP_ID");
//$options->alipayCertPath = env("ALI_CERT_ALIPAY");
//$options->alipayRootCertPath = env("ALI_CERT_ROOT");
//$options->alipayRootCertPath = env(" ALI_CERT_ROOT");
//$options->merchantCertPath = env("ALI_CERT_APP");
//注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可

@ -0,0 +1,10 @@
<?php
namespace App\Models;
class AlipayAccount extends SoftDeletesModel
{
protected $table = "alipay_account";
}

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateProjectAddAlipayAccountId extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table("project", function (Blueprint $table) {
$table->integer('alipay_account_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAlipayAccount extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('alipay_account', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string("appid")->nullable()->comment("应用ID");
$table->string("public_key",1024)->nullable()->comment("应用公钥");
$table->string("alipay_key",1024)->nullable()->comment("支付宝密钥");
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('alipay_account');
}
}

@ -0,0 +1,17 @@
@extends("admin.layouts.layout")
@php
$pageTitle = __("actions.".last(explode("/",request()->url()))).$modelName;
@endphp
@section("content")
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
@include("public._form")
</div>
</div>
</div>
</div>
@endsection

@ -0,0 +1,57 @@
@extends("admin.layouts.layout")
@section("content")
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="mb-3">
<a class="btn btn-primary" href="{{url($urlPrefix.'/create')}}">
@lang("icons.action_create") @lang('actions.create'){{$modelName}}
</a>
</div>
<table class="table table-bordered" id="data-table">
<thead>
<tr>
<th>
{{$modelName}}
</th>
<th>应用ID</th>
<th>应用公钥</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach ($data as $row)
<tr data-id="{{$row->id}}">
<td>
{{ $row->name }}
</td>
<td>{{ $row->appid }}</td>
<td>{{ Str::limit($row->public_key, 50) }}</td>
<td>
<a class="btn btn-sm btn-primary"
href="{{url("{$urlPrefix}/edit?id={$row['id']}")}}">@lang("icons.action_edit") @lang("actions.edit")</a>
<a class="btn btn-sm btn-danger btn-delete" data-id="{{$row['id']}}"
href="javascript:;">@lang("icons.action_delete") @lang("actions.delete")</a>
</td>
</tr>
@endforeach
</tbody>
</table>
@include("public._pages")
</div>
</div>
</div>
</div>
@include("public._delete")
@endsection
@push("footer")
<script>
</script>
@endpush

@ -16,28 +16,3 @@
</div>
@endsection
@push("footer")
<script>
$(function() {
$("#project_id").change(getLevels);
});
function getLevels() {
var project_id = $("#project_id").val();
var url = "{{ url($urlPrefix."/get-levels") }}";
$.get(url,{project_id:project_id},function(res) {
var html = "";
for (k in res) {
html += "<option value='"+ res[k].id +"'>"+ res[k].name +"</option>";
}
$("#paramedic_level_id").html(html);
});
}
function uploaderCallback(file, data, index) {
$('input[data-uploader-index=' + index + ']').val("/storage/" + (data.folder ? data.folder + "/" : "") + data.name);
return true;
}
</script>
@endpush

@ -66,6 +66,7 @@ Route::group(["namespace" => "Admin", "prefix" => "admin"], function () {
\App\Models\CommonModel::generateCurdRouter("TrainingTypeController", "training-type");
\App\Models\CommonModel::generateCurdRouter("TrainingController", "training");
\App\Models\CommonModel::generateCurdRouter("WechatpayAccountController", "wechatpay-account");
\App\Models\CommonModel::generateCurdRouter("AlipayAccountController", "alipay-account");
\App\Models\CommonModel::generateCurdRouter("AdverseController", "adverse");
Route::post("adverse/order-search", 'AdverseController@orderSearch');

Loading…
Cancel
Save