# julyadmin
**Repository Path**: julystudio/julyadmin
## Basic Information
- **Project Name**: julyadmin
- **Description**: 快速后台开发工具
- **Primary Language**: PHP
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-02-04
- **Last Updated**: 2026-06-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# JulyAdmin
基于 **ThinkPHP 6.1 / 8.0** + **Layui** + **光年(Lyear)后台模板** 的快速后台开发扩展包。通过可视化配置、表单/表格构建器与代码生成,显著减少 CRUD、权限、上传等重复开发工作。
| | |
|---|---|
| **主页** | [https://julytian.top](https://julytian.top) |
| **作者** | July |
| **联系邮箱** | 1163433011@qq.com(使用疑问请通过邮箱联系) |
| **协议** | MIT(全文见仓库根目录 [LICENSE](LICENSE)) |
---
## 功能总览
| 模块 | 说明 |
|------|------|
| 后台框架 | 登录、验证码、多模板登录页、主框架、控制台、应用映射(如 `pro` → `admin`) |
| 权限体系 | 管理员、角色、菜单、按钮级权限、操作日志 |
| 平台配置 | 系统/UI/上传/地图等配置,数据库持久化 + 后台可视化编辑 |
| 文件中心 | 文件分类、上传记录、弹窗选文件、本地上传驱动(可扩展) |
| 数据库管理 | 同步表结构、字段/索引维护、清空数据、模型关联、生成 Model |
| UI 生成器 | 按数据表一键生成控制器、模型、列表/表单/搜索/工具栏代码 |
| 构建器 HasBuilder | 列表、增删改查、行内编辑、树表、导入导出、下拉分页等 |
| 前台标签库 | `{cms:db}`、`{cms:php}` 模板标签,便于前台取数 |
| 安装向导 | 复制静态资源、导入 SQL、初始化配置 |
---
## 一、后台基础
### 1.1 登录与首页
- **登录**:账号 + 密码 + 图形验证码;支持 3 套登录页模板(`admin_login_template`:1/2/3)
- **会话**:登录成功后写入 `session('admininfo')`(ThinkPHP 8 须存数组,见 [第八章](#八thinkphp-8x-兼容说明))
- **首页** `Index/index`:左侧/顶部菜单、iframe 多标签、用户信息展示
- **控制台** `Index/main`:PHP 版本、数据库版本、GD、上传限制、服务器信息等
- **退出** `Index/logOut`
### 1.2 路由与应用映射
- 包内控制器位于 `july\julyadmin\admin\controller`,由 `AppRun` 中间件在应用控制器不存在时自动接管
- 可在 `config/app.php` 配置 `app_map`,例如 `'pro' => 'admin'`,对外用 `/pro` 访问后台
- 项目可在 `app/admin/controller` 扩展业务控制器(如内容、项目分类等),与包控制器共存
### 1.3 认证与权限(`Auth`)
- **`$noNeedLogin`**:无需登录的方法(如 `login`、`code`)
- **`$noPermissionAuth`**:登录后无需校验菜单/按钮权限的方法
- **菜单权限**:按 `controller` + `action` 与角色菜单授权匹配
- **按钮权限**:`admin_role_list` 细粒度控制
- **超级管理员**:`roleid == 1` 跳过权限校验
- **操作日志**:按配置记录 POST/GET 等请求的 URL、参数、IP(可排除字段与方法)
---
## 二、系统管理(内置菜单)
### 2.1 平台配置 `Config`
- 管理 `config` 表中的配置项(键名、配置文件路径、JSON 内容)
- 内置配置模板(`src/webconfig/`):
- **System**:后台名称、Logo、登录页、日志策略、高德地图 Key
- **ImageUpload**:图片上传字段名、大小、后缀、路径规则、驱动
- **FileUpload**:附件上传规则、驱动
- 读取:`Config::config('System')` 或 `\july\julyadmin\common\model\Config::config('System')`
### 2.2 权限管理
| 控制器 | 功能 |
|--------|------|
| **Admin** | 管理员 CRUD、头像、角色绑定、修改密码、个人信息 |
| **AdminRole** | 角色 CRUD、菜单树授权、按钮权限勾选、权限缓存 |
| **Menu** | 无限级菜单、模块/控制器/方法、图标、排序、顶部左/右菜单标记 |
| **Operationlog** | 操作日志查询(只读列表) |
### 2.3 文件管理
| 控制器 | 功能 |
|--------|------|
| **FilesCategory** | 文件分类树 |
| **Files** | 已上传文件列表、筛选、**通用上传弹窗** `commonUploadForm`(供表单选图/选文件) |
| **Upload** | 上传接口(图片/附件,走配置驱动) |
| **Ueditor** | 百度 UEditor 对接 |
上传驱动目录:`src/uploaddrives/drives/`(默认 **本地上传** `FileUpload`),可在配置中选择。
### 2.4 数据库管理 `DatabaseManage`
- **同步数据表**:从 MySQL 读取表结构写入 `database_manage`
- **表维护**:字段增删改、类型、默认值、注释、表注释
- **索引管理** `tableIndex`:查看/维护表索引
- **清空数据** `clearData`:按表清空(需确认)
- **模型关联** `modelRelation`:配置 belongsTo / hasOne / hasMany 等,写入 `model_relation`
- **生成 Model** `createModel`:根据表结构生成 `app/common/model` 下模型代码(含关联方法)
### 2.5 UI 生成器 `UiCreate`
在后台选择已登记数据表,配置后一键生成:
- `app/admin/controller/{Table}.php`(继承 `Common` + `HasBuilder`)
- `app/common/model/{Table}.php`
- 列表页:搜索区、工具栏、列定义、行按钮
- 表单:字段组件类型、校验、布局(Tabs/Items)
- 支持树表、关联查询、行内编辑字段、导入导出等选项
适合新表快速落地标准后台 CRUD。
### 2.6 缓存 `Cache`
- 清除路由缓存、数据缓存、模板编译缓存(`runtime/temp`)
---
## 三、页面构建器(HasBuilder)详解
业务控制器 `use HasBuilder`,在 **`buildPage()`** 中组装列表页,在 **`buildForm()`** 中组装新增/编辑表单,在 **`filterWhere()`** 中处理搜索条件。
典型列表页自上而下结构(以「内容管理」为例):
```
┌─────────────────────────────────────────────────────────┐
│ 搜索区 Search(内容ID、标题、状态、时间范围…) [搜索][重置] │
├─────────────────────────────────────────────────────────┤
│ 工具栏 Toolbar(添加 | 开启/禁用 | 删除 | 刷新) │
├──────────┬──────────────────────────────────────────────┤
│ 左侧分类树 │ Layui 表格 DataTable(列 + 行内编辑 + 行按钮) │
│ JsTree │ 分页、多选、排序、导入/导出(可隐藏) │
└──────────┴──────────────────────────────────────────────┘
```
对应类:`Search.php` → `Toolbar.php` → `DataTable.php`(含左侧 `JsTree`)。
---
### 3.1 完整 Demo:内容列表(`app/admin/controller/Content.php`)
#### 控制器属性(构造函数)
```php
use HasBuilder;
public function __construct()
{
parent::initialize();
$this->dataModel = new ContentModel();
$this->relationWithJoins = ['category' => 'left']; // 列表 JOIN 分类
$this->pageTitle = '内容列表';
$this->disabledField = 'disabled';
$this->allowRowEditField = ['disabled', 'is_top', 'sort']; // 行内可改字段
$this->selectWhere = [['disabled', '=', 1]];
$this->selectSearch = 'id|name';
$this->selectTextField = '{id}#{name}';
$this->tableType = 'table';
}
```
#### buildPage:搜索 + 工具栏 + 左树 + 表格
```php
protected function buildPage(&$table = [])
{
// ① 搜索区
$table->getSearch()
->show('text', 'id', '内容ID')
->show('text', 'title', '内容标题')
->show('select', 'disabled', '禁用状态')
->options([1 => $this->switchBtnText[0], 0 => $this->switchBtnText[1]])
->show('select', 'is_top', '是否置顶')
->options([1 => $this->switchBtnText[0], 0 => $this->switchBtnText[1]])
->show('datetime-local', 'create_time_start', '创建时间开始')
->show('datetime-local', 'create_time_end', '创建时间结束')
->show('datetime-local', 'update_time_start', '更新时间开始')
->show('datetime-local', 'update_time_end', '更新时间结束');
// ② 表格上方工具栏(批量操作)
$table->getToolbar()
->addBtn()
->disabledBtn()
->deleteBtn()
->refreshBtn();
// ③ 左侧分类树,点击后按 category_id 筛选表格
$table->showLeftTree('category_id', '分类')
->dataUrl(url('ContentCategory/selectTree'));
$table->tableTitle('内容列表');
// ④ 表格列
$table->showCheckbox();
$table->show('id', '内容ID')->width('100')->sort(true);
$table->show('category_id', '分类')
->to('{category_id}#{category.name}')->width('200')->sort(true);
$table->show('title', '内容标题')->width('200')->sort(true);
$table->show('image', '封面', 'image')->width('200');
$table->show('disabled', '禁用状态', 'switchBtn')
->edit('switchBtn')->width('100')->sort(true);
$table->show('is_top', '是否置顶', 'switchBtn')
->edit('switchBtn')->width('100')->sort(true);
$table->show('sort', '排序')->edit('number')->width('100')->sort(true);
$table->show('create_time', '创建时间')->width('180')->sort(true);
$table->printShow(false);
$table->exportShow(false);
$table->importShow(false);
// ⑤ 行操作列
$table->showRowHandleMenus()->width(200);
$table->getTableRowBtns()
->editBtn()
->viewBtn()
->disabledBtn()
->deleteBtn();
}
```
#### filterWhere:把搜索参数转为查询条件
搜索表单提交字段为 `search[field]`,`filterWhere` 接收解析后的数组:
```php
protected function filterWhere($search = [])
{
$where = [];
foreach ($search as $k => $v) {
if ($v === '') continue;
switch ($k) {
case 'id':
$where[] = ['content.id', '=', $v];
break;
case 'category_id': // 左侧树选中时注入
$where[] = ['content.category_id', '=', $v];
break;
case 'title':
$where[] = ['content.title', 'LIKE', '%' . $v . '%'];
break;
// create_time_start / end 等同理
}
}
return $where;
}
```
#### buildForm:新增/编辑表单
```php
protected function buildForm(&$form, $isEdit, &$data = [])
{
$form->show('hidden', 'id', '内容ID');
$form->show('select', 'category_id', '分类')
->size(3, 3)->dataUrl(url('ContentCategory/selectPage'))->required();
$form->show('text', 'title', '内容标题')->required();
$form->show('image', 'image', '封面');
$form->show('switchBtn', 'disabled', '禁用状态')->default('1');
$form->show('editorMd', 'content', '文章内容')->height('800px')->required();
}
```
#### 可重写钩子一览
| 方法 | 作用 |
|------|------|
| `buildPage(&$table)` | 定义搜索、工具栏、表格列、左树 |
| `buildForm(&$form, $isEdit, &$data)` | 定义新增/编辑/详情表单 |
| `filterWhere($search)` | 列表搜索条件 |
| `filterSelectPageWhere($where)` | 下拉 `selectPage` 额外条件 |
| `handleData(&$data)` | 列表数据二次处理 |
| `filterTotalRow(...)` | 合计行自定义 |
| `save($isEdit)` | 提交保存与校验 |
---
### 3.2 HasBuilder Trait 与控制器属性
| Trait | 能力 |
|-------|------|
| **HasIndex** | 列表 `index`、分页、搜索、树表 |
| **HasAdd / HasEdit / HasView** | 弹窗表单增删改查 |
| **HasDelete / HasDisabled** | 批量/单行删除、启禁 |
| **HasAutopost** | 行内编辑提交到 `autopost` |
| **HasSelectPage** | 下拉分页 `selectPage`、树 `selectTree` |
| **HasExport / HasImport** | Excel 导入导出 |
| **HasBase** | `doSave`、`builder()`、按钮文案、主键 |
**常用 `$this` 属性:**
| 属性 | 说明 |
|------|------|
| `dataModel` | 当前业务模型 |
| `pageTitle` | 列表标题 |
| `relationWithJoins` | 列表 JOIN,如 `['category'=>'left']` |
| `relationWiths` | 列表 with 预加载 |
| `allowRowEditField` | 允许行内编辑的字段(须在 `edit()` 中声明) |
| `disabledField` | 启禁字段名,默认 `disabled` |
| `tableType` | `table` 或 `treeTable` |
| `noDeletePrimarykeys` / `noEditPrimarykeys` / `noDisabledPrimarykeys` | 保护指定主键 |
| `selectSearch` / `selectTextField` / `selectWhere` | 下拉 `selectPage` 配置 |
---
### 3.3 搜索区 `Search`(`$table->getSearch()`)
通过 `$table->getSearch()->show(类型, 字段, 标签)` 链式配置。提交后调用 `tableSearch()`,以 `search[字段名]` 传给后端 `index` 的 `$search` 参数。
**支持的搜索组件类型:** `text`、`date`、`datetime-local`、`month`、`time`、`week`、`select`
| 方法 | 说明 | 适用 |
|------|------|------|
| `show($type, $field, $label)` | 添加搜索项 | 全部 |
| `options($array)` | 静态下拉选项 | select |
| `dataUrl($url)` | 远程下拉(Select2 分页) | select |
| `setSelectPageTotal($n)` | 远程下拉每页条数 | select |
| `multiple($bool)` | 多选 | select |
| `default($value)` | 默认值 | 全部 |
| `placeholder($text)` | 占位符 | 全部 |
| `col($class)` | Bootstrap 栅格,如 `col-lg-3` | 整表搜索区 |
| `size($labelW, $inputW)` | label/input 栅格 1–12 | 整表搜索区 |
| `setStep($bool)` | 秒级精度 | datetime-local |
---
### 3.4 工具栏 `Toolbar`
**表格上方:** `$table->getToolbar()`
**行内操作:** `$table->getTableRowBtns()`
| 方法 | 说明 | 工具栏 | 行按钮 |
|------|------|:------:|:------:|
| `addBtn($show, $title, $w, $h, $parentOpen)` | 添加(弹窗) | ✓ | ✓ |
| `editBtn(...)` | 编辑 | ✓ | ✓ |
| `viewBtn(...)` | 详情只读 | ✓ | ✓ |
| `disabledBtn($show, $title)` | 批量/单行启禁 | ✓ | ✓ |
| `deleteBtn($show, $title)` | 删除 | ✓ | ✓ |
| `refreshBtn($show, $title)` | 刷新表格 | ✓ | — |
| `linkBtn($action, $title, $fn, $icon, $class)` | 自定义链接按钮 | ✓ | ✓ |
| `openWindowBtn($action, $title, $href, ...)` | 自定义弹窗 | ✓ | ✓ |
| `beforeHtml($html)` / `afterHtml($html)` | 插入 HTML | ✓ | ✓ |
| `br()` | 换行 | ✓ | ✓ |
行按钮可通过数据字段 `__edit_hidden__`、`__delete_hidden__` 等控制显示。权限与 `AdminRole` 按钮授权联动。
---
### 3.5 表格 `DataTable`(`buildPage` 中的 `$table`)
#### 表格级配置
| 方法 | 说明 |
|------|------|
| `tableTitle($title)` | 卡片标题 |
| `tableId($id)` | 表格 DOM id(一般自动生成) |
| `rows($n)` | 默认每页条数 |
| `limits([20,50,...])` | 分页可选条数 |
| `tableType('table'\|'treeTable')` | 普通表 / 树表 |
| `treeTableGroupField($field)` | 树表展开列 |
| `showCheckbox($bool)` | 显示多选列 |
| `showPage($bool)` | 是否分页 |
| `switchBtnText(['开启','关闭'])` | 开关列文案 |
| `printShow / exportShow / importShow` | 右上角打印/导出/导入 |
| `filterShow($bool)` | 列筛选按钮 |
| `tableHeight($h)` | 表格高度 |
| `showLeftTree($field, $title)` | 左侧分类树,返回 `JsTree` 可链式 `dataUrl()` |
#### 列定义:`$table->show($field, $title, $form_type)`
第三个参数 `$form_type` 为空则纯文本;可传 `image`、`switchBtn` 等。链式方法作用于**当前列**:
| 方法 | 说明 |
|------|------|
| `width($w)` / `minWidth($w)` | 列宽 |
| `sort($bool)` | 是否可排序 |
| `align('left'\|'center'\|'right')` | 对齐 |
| `fixed('left'\|'right')` | 固定列 |
| `hide($bool)` | 默认隐藏列 |
| `to('{id}#{name}')` | 显示模板,支持关联字段 `category.name` |
| `edit($type)` | 行内编辑:`text`、`number`、`switchBtn`、`image` 等 |
| `options($arr)` | 行内 `checkbox`/`radio` 选项 |
| `thumbSize($w, $h)` | 图片列缩略图尺寸 |
| `templet($js)` | laytpl 自定义单元格,`val` 当前值,`row` 当前行 |
| `totalRow($bool)` / `colTotalRow($bool)` | 合计行 |
| `showRowHandleMenus($title, $fixed)` | 右侧固定「操作」列 |
**行内编辑:** 字段须加入 `$this->allowRowEditField`,并调用 `->edit('switchBtn')` 等,保存走 `autopost` 接口。
---
### 3.6 表单组件 `forms`(`$form->show($type, $field, $label)`)
**统一调用:**
```php
$form->show(string $type, string $field, string $label = '');
```
- `$type`:组件类型(见下表)
- `$field`:表单项 `name` / 数据库字段名
- `$label`:左侧标签文字(第二个参数可留空,由语言包或业务自行处理时传 `''`)
链式配置在 `show()` 之后继续调用,返回当前组件实例(`$this`)。
---
#### 3.6.1 FormBase 公共方法(几乎所有组件均支持)
| 方法 | 参数类型 | 默认值 | 返回值 | 说明 |
|------|----------|--------|--------|------|
| `required(bool $required)` | `bool` | `true` | `$this` | 必填:标签红星 + HTML5 `required` |
| `default(mixed $value)` | `string\|int\|...` | `''` | `$this` | 新增时用默认值;编辑时仅当库中该字段为空才用 default |
| `placeholder(string $text)` | `string` | 构造时=label | `$this` | 输入框 placeholder |
| `help(string $help)` | `string` | `''` | `$this` | 控件下方说明(支持 HTML) |
| `tips(string $tips, int $direction, int $time, string $background)` | 见左 | `''`, `3`, `0`, `'#16b777'` | `$this` | 标签旁图标悬浮提示;`direction`:1上 2右 3下 4左;`time` 秒,0=不自动关 |
| `readonly(bool $readonly)` | `bool` | `true` | `$this` | 只读,不可编辑 |
| `isView(bool $isView)` | `bool` | `true` | `$this` | 详情页模式,多数组件改为纯文本展示 |
| `size(int $labelWidth, int $inputWidth)` | `int,int` | — | `$this` | Bootstrap 栅格 1–12;label 与 input 列宽 |
| `style(string $css)` | `string` | `''` | `$this` | 内联 CSS,写入控件或容器 |
**内部赋值(框架自动,一般不需手动调):**
| 方法 | 说明 |
|------|------|
| `setData(array $data)` | 编辑/详情时注入行数据 |
| `setIsEdit(int $isEdit)` | `0` 新增,`1` 编辑 |
| `setColWidth(int $colWidth)` | 整行占位 `col-md-*`,默认 `10` |
| `setItemsField(string $field)` | 在 `items` 子行内时由框架调用 |
| `itemsTitleStyle(string $style)` | `items` 表头单元格样式 |
---
#### 3.6.2 远程下拉 `selectPage` 约定(`select` / 搜索区 `select` 共用)
`dataUrl()` 指向控制器 `selectPage` 方法时,接口 JSON 格式:
```json
{
"data": [{"id": 1, "text": "显示文字"}, ...],
"total": 100
}
```
| 请求参数 | 类型 | 说明 |
|----------|------|------|
| `keyword` | `string` | 搜索关键字 |
| `page` | `int` | 页码 |
| `rows` | `int` | 每页条数(表单 `rows()` / 搜索 `setSelectPageTotal()`) |
| `parent_id` | `string` | 级联时父级 `select` 的值 |
| `default` | `string` | 回显已选 id,逗号分隔 |
静态 `options()` 支持两种数组:
- 一维:`[1 => '选项A', 2 => '选项B']`
- 二维:`[['id'=>1,'text'=>'A','disabled'=>false], ...]`
---
#### 3.6.3 各组件完整说明
---
##### `text` — `july\julyadmin\builder\forms\Text`
| 项 | 说明 |
|----|------|
| HTML | `` |
| 提交值 | `string` |
| 默认 placeholder | 等于 `$label` |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `maxlength(int $val)` | `$val` | `int` | `100` | `maxlength` 属性;传 `''` 可不限制 |
```php
$form->show('text', 'title', '标题')
->required()
->maxlength(200)
->placeholder('请输入标题');
```
---
##### `number` — `Number`
| 项 | 说明 |
|----|------|
| HTML | `` |
| 提交值 | `string`(数字字符) |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `min(mixed $val)` | 最小值 | `int\|float\|string` | `1` | `min` 属性 |
| `max(mixed $val)` | 最大值 | 同上 | `1` | `max` 属性 |
| `step(mixed $val)` | 步进 | 同上 | `1` | `step` 属性 |
| `maxlength(int $val)` | 最大位数 | `int` | `100` | 字符长度限制 |
```php
$form->show('number', 'sort', '排序')->min(0)->max(9999)->step(1)->default(0);
```
---
##### `textarea` — `Textarea`
| 提交值 | `string` |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `rows(int $val)` | 行数 | `int` | `3` | textarea 行数 |
| `setCols(int $val)` | 列数 | `int` | `20` | textarea 列数 |
| `maxlength(int $val)` | 最大长度 | `int` | `100` | 最大字符 |
---
##### `password` — `Password`
| 提交值 | `string` | 密码框,编辑时不自动填充 |
仅 FormBase 公共方法。
---
##### `email` — `Email`
| HTML | `` |
| 提交值 | `string` |
| 专有方法 | 参数 | 类型 | 默认 |
|----------|------|------|------|
| `maxlength(int $val)` | 最大长度 | `int` | `100` |
---
##### `hidden` — `Hidden`
| 提交值 | `string` | 无 label 行,仅 hidden input |
仅 FormBase 公共方法。常用于主键:`$form->show('hidden', 'id', 'ID');`
---
##### `html` — `Html`
| 说明 | 只读展示字段值,无输入框;`isView` 下显示「空」或实际值 |
| 提交值 | 一般不编辑(展示 `create_time` 等) |
仅 FormBase 公共方法。
---
##### `date` / `time` / `month` / `week` — `Date` `Time` `Month` `Week`
| HTML | 对应 HTML5 `type` |
| 提交值 | `string`,格式由浏览器决定,如 `2024-01-01` |
仅 FormBase + `style()`。
---
##### `datetime-local` — `DatetimeLocal`
| 提交值 | `string`,如 `2024-01-01T12:30` |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `setStep(int $val)` | 秒精度 | `int` | `1` | 设置 `step=1` 可选秒 |
---
##### `color` — `Color`
| HTML | `` |
| 提交值 | `#rrggbb` 字符串 |
仅 FormBase 公共方法。
---
##### `select` — `Select`(Select2)
| 提交值 | 单选:`string\|int` id;多选:逗号分隔 id 或数组(视表单序列化) |
| 依赖 | jQuery Select2 |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `options(array $options)` | 静态选项 | `array` | `[]` | 与 `dataUrl` 二选一 |
| `dataUrl(string $url)` | 远程地址 | `string` | `''` | 对接 `selectPage`;可 `(string)url(...)` |
| `rows(int $total)` | 每页条数 | `int` | `10` | AJAX 分页大小 |
| `multiple(bool $multiple)` | 多选 | `bool` | `false` | `true` 时 name 带 `[]` |
| `setParentId(string $parent_id)` | 父字段名 | `string` | `''` | 级联:请求会带 `parent_id`;`withNext` 子组件必填 |
| `setIsWith(bool $isWith)` | 是否被关联列 | `bool` | `false` | 框架内部用于 `withNext` 布局 |
| `showLabel(bool $show)` | 显示标签 | `bool` | `true` | `false` 时仅下拉,用于行内关联 |
| `withNext(Closure $formObject)` | 闭包 | `Closure` | — | 选中后右侧联动下一组件(需 `setParentId`) |
| `when(mixed $where, ...$forms)` | 条件+表单项 | 见下 | — | 值匹配时显示后续组件 |
**`when($where, ...$forms)` 参数:**
- `$where`:`string` \| `int` \| `float` \| 一维 `array`(当前值 in 数组,**区分类型**)
- `...$forms`:多个 `$form->show(...)` 返回的组件对象
```php
$form->show('select', 'type', '类型')
->options([1 => '站内', 2 => '站外'])
->when(2, $form->show('text', '外链', '外链地址'));
$form->show('select', 'category_id', '分类')
->dataUrl(url('ContentCategory/selectPage'))
->rows(20)
->required();
```
---
##### `radio` — `Radio`
| 提交值 | `string\|int`,单个 option 的 key |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `options(array $options)` | 选项 | `array` | `[]` | 键值对 `[value => '标签']` |
| `when(mixed $where, ...$forms)` | 同 select | — | — | 选中某值后显示其他表单项 |
---
##### `checkbox` — `Checkbox`
| 提交值 | `array` 或逗号分隔(多选 name 为 `field[]`) |
| 专有方法 | 参数 | 类型 | 默认 |
|----------|------|------|------|
| `options(array $options)` | 选项 | `array` | `[]` |
---
##### `switchBtn` — `SwitchBtn`
| 提交值 | 通常为 `1`(开)/ `0`(关),与数据库 `tinyint` 一致 |
| UI | Bootstrap 开关 |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `switchBtnText(array $val)` | 文案 | `array` | `['开启','关闭']` | 必须 2 个元素 |
| `setColor(string $color)` | 颜色名 | `string` | `'blue'` | `blue/indigo/purple/pink/red/orange/yellow/green/cyan/brown/gray/dark/teal` |
| `when(mixed $where, ...$forms)` | 条件显示 | 同 select | — | — |
```php
$form->show('switchBtn', 'disabled', '禁用状态')
->switchBtnText(['正常', '禁用'])
->setColor('green')
->default('1');
```
---
##### `image` — `Image`
| 提交值 | 单图:URL 字符串;多图:逗号分隔 URL |
| 上传 | WebUploader;配置读 `Config::config('ImageUpload')` |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `multiple(bool $multiple)` | 多图 | `bool` | `false` | |
| `setExt(string $ext)` | 允许后缀 | `string` | `''` | 如 `jpg,png`;空则用配置 |
| `thumbSize(int $width, int $height)` | 缩略图 | `int,int` | `165,110` | 列表预览尺寸,须 >0 |
| `showFileList(bool $show)` | 预览列表 | `bool` | `true` | |
| `isWriteData(bool $write)` | 写入 files 表 | `bool` | `true` | 上传接口 `isWriteData` 参数 |
| `setSelectServerFile(bool $show)` | 「选择」按钮 | `bool` | `true` | 从文件库选 |
| `setSelectLocationFile(bool $show)` | 「上传」按钮 | `bool` | `true` | 本地上传 |
```php
$form->show('image', 'image', '封面')
->multiple(false)
->setExt('jpg,png,jpeg')
->thumbSize(120, 120);
```
---
##### `file` — `File`
与 **image** 方法完全相同,区别:走 `FileUpload` 配置、支持更多后缀、上传接口为 `fileUpload`。
---
##### `tags` — `Tags`
| 提交值 | 逗号分隔标签字符串 |
| UI | Bootstrap Tags Input |
仅 FormBase + `style()`。
---
##### `iconPicker` — `IconPicker`
| 提交值 | MDI 图标 class 字符串,如 `mdi mdi-home` |
| 依赖 | fontIconPicker |
仅 FormBase 公共方法。
---
##### `jsTree` — `JsTree`
| 提交值 | 节点 id;多选时为逗号分隔 id |
| 数据 | 静态 `options` 为 jstree 节点数组,或 `dataUrl` 返回树 JSON |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `options(array $options)` | 树数据 | `array` | `[]` | 符合 jsTree 节点结构 |
| `dataUrl(string $url)` | 远程 | `string` | `''` | 如 `selectTree` |
| `setOpen(bool $is_open)` | 默认展开 | `bool` | `true` | |
| `showCheckbox(bool $show)` | 多选 | `bool` | `false` | 启用 checkbox 插件 |
---
##### `ueditor` — `Ueditor`
| 提交值 | HTML 字符串 |
| 依赖 | 百度 UEditor |
| 专有方法 | 参数 | 类型 | 默认 |
|----------|------|------|------|
| `width(string $width)` | 宽度 | `string` | `'100%'` |
| `height(string $height)` | 高度 | `string` | `'400px'` |
---
##### `editorMd` — `EditorMd`
| 提交值 | Markdown 源码 `string` |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `width(string $width)` | 编辑器宽 | `string` | `'100%'` | 支持 `%`、`px` |
| `height(string $height)` | 编辑器高 | `string` | `'400px'` | 支持 `auto` |
| `setExt(array $ext)` | 上传后缀 | `array` | `[]` | 必须一维数组 `['jpg','png']` |
| `showToolbar()` | 显示工具栏 | — | — | |
| `hideToolbar()` | 隐藏工具栏 | — | — | |
| `openPreview(bool $open)` | 实时预览 | `bool` | `true` | |
```php
$form->show('editorMd', 'content', '文章内容')
->height('800px')
->required();
```
---
##### `gaodeMap` — `GaodeMap`
| 提交值 | `string`,格式 `"经度,纬度"`,如 `"116.399193,39.905081"` |
| 配置 | `System.gaode_map_js`、`System.gaode_security_key` |
无专有链式方法,仅 FormBase。无坐标时默认天安门附近点位。
---
##### `items` — `Items`(动态多行)
| 提交值 | **二维数组** JSON/POST:`field` => `[ ['col1'=>'',...], ... ]` |
| 子字段 name | 带行前缀,如 `_skus_[0]name`(框架自动处理) |
| 专有方法 | 参数 | 类型 | 默认 | 说明 |
|----------|------|------|------|------|
| `with(Closure $formObject)` | 行内表单 | `Closure` | — | 参数为 `$form`,内层 `show()` 定义列 |
| `addBtn(bool $show)` | 添加行按钮 | `bool` | `true` | |
| `deleteBtn(bool $show)` | 删除行按钮 | `bool` | `true` | |
| `showRowHandleMenus(bool $show)` | 行操作区 | `bool` | `true` | |
**`items` 内允许的子组件 type:**
`text`, `number`, `color`, `date`, `datetime-local`, `email`, `month`, `password`, `textarea`, `time`, `week`, `checkbox`, `select`
```php
$form->show('items', 'skus', '规格')
->required()
->with(function ($row) {
$row->show('text', 'name', '名称')->required();
$row->show('number', 'price', '价格')->min(0)->step(0.01);
$row->show('select', 'unit', '单位')->options([1 => '件', 2 => '箱']);
});
```
---
##### `tabs` — `Tabs`(选项卡头)
**不通过 `show('tabs')` 使用**,而在 `Form` 上:
```php
$form->tabs('main')->addTab('基本信息', 'base', true)->addTab('扩展', 'ext', false);
$form->tabStart();
$form->tabItemStart('base');
// ... 表单项 ...
$form->tabItemEnd();
$form->tabItemStart('ext');
// ...
$form->tabItemEnd();
$form->tabEnd();
```
| 方法 | 参数 | 类型 | 默认 | 说明 |
|------|------|------|------|------|
| `addTab(string $label, string $tab_id, bool $active)` | 标签/ID/是否默认选中 | — | `$active=true` | `tab_id` 不可重复 |
---
#### 3.6.4 Form 容器布局方法(`Form.php`)
| 方法 | 参数 | 类型 | 说明 |
|------|------|------|------|
| `setColWidth(int $colWidth)` | 1–12 | `int` | 后续所有组件默认行宽 |
| `size(int $labelWidth, int $inputWidth)` | 1–12 | `int,int` | 全局 label/input 栅格 |
| `tabs(string $tab_id)` | 选项卡组 id | `string` | 返回 `Tabs` 对象 |
| `tabStart()` | — | — | 开始 tab 内容区 |
| `tabItemStart(string $tab_item_id)` | 对应 `addTab` 的 id | `string` | |
| `tabItemEnd()` | — | — | |
| `tabEnd()` | — | — | |
| `leftStart(int $width)` | 左栏栅格 | `int` | 默认 `6` |
| `leftEnd()` / `rightStart(int $width)` / `rightEnd()` | — | — | 左右分栏 |
| `script(string $script)` | 自定义 JS | `string` | 追加到表单页 |
| `style(string $style)` | 自定义 CSS | `string` | |
| `showFooterBtns(bool $show)` | 底部按钮 | `bool` | 默认 `true` |
---
#### 3.6.5 条件显示 `when()` 统一说明
适用于:**`select`、`radio`、`switchBtn`**
| `$where` 类型 | 匹配规则 |
|---------------|----------|
| `string` / `int` / `float` | 全等(多选时数组包含即显示) |
| 一维 `array` | 当前值 in 数组(注意 `1` 与 `'1'` 区分) |
后续参数为已通过 `$form->show()` 创建的配置对象,可传多个。
---
#### 3.6.6 组件类型速查表
| type | 类名 | 提交值类型 | 专有方法 |
|------|------|------------|----------|
| text | Text | string | maxlength |
| number | Number | string/number | min, max, step, maxlength |
| textarea | Textarea | string | rows, setCols, maxlength |
| password | Password | string | — |
| email | Email | string | maxlength |
| hidden | Hidden | string | — |
| html | Html | — | — |
| date/time/month/week | 同名 | string | datetime-local: setStep |
| color | Color | string | — |
| select | Select | string/array | options, dataUrl, rows, multiple, setParentId, showLabel, withNext, when |
| radio | Radio | string/int | options, when |
| checkbox | Checkbox | array | options |
| switchBtn | SwitchBtn | 0/1 | switchBtnText, setColor, when |
| image/file | Image/File | string | multiple, setExt, thumbSize, showFileList, isWriteData, setSelectServerFile, setSelectLocationFile |
| tags | Tags | string | — |
| iconPicker | IconPicker | string | — |
| jsTree | JsTree | string | options, dataUrl, setOpen, showCheckbox |
| ueditor | Ueditor | string(html) | width, height |
| editorMd | EditorMd | string(md) | width, height, setExt, showToolbar, hideToolbar, openPreview |
| gaodeMap | GaodeMap | string(lng,lat) | — |
| items | Items | array | with, addBtn, deleteBtn, showRowHandleMenus |
---
### 3.7 包自带后台控制器速查
| 控制器 | 功能 |
|--------|------|
| Index | 登录、首页、控制台、验证码 |
| Config | 平台配置项管理 |
| Admin / AdminRole / Menu | 管理员、角色权限、菜单 |
| Files / FilesCategory / Upload / Ueditor | 文件与上传 |
| DatabaseManage | 表结构、索引、模型、关联 |
| UiCreate | UI 代码生成 |
| Operationlog | 操作日志 |
| Cache | 清理缓存 |
---
## 四、前台 CMS 标签(`taglib/Cms`)
在 ThinkPHP 模板中(需通过 `AppRun` 注册标签库):
**数据库查询标签**
```html
{cms:db name="content" key="v" field="*" where="disabled=1" order="sort desc" limit="0,10"}
{$v.title}
{/cms:db}
```
| 属性 | 说明 |
|------|------|
| name | 表名(必填) |
| key | 循环变量名(必填) |
| field | 查询字段,默认 `*` |
| where | 条件 |
| order | 排序 |
| limit | `偏移,条数` |
| cache | 缓存键,秒数 |
| group | 分组 |
**PHP 代码块标签**
```html
{cms:php}
// 任意 PHP
{/cms:php}
```
包内还提供 `CmsPages`、`CmsPagesCategory` 模型,可供页面/栏目类业务扩展。
---
## 五、数据表说明(安装 SQL)
| 表名 | 用途 |
|------|------|
| admin | 管理员账户 |
| admin_role | 角色 |
| admin_role_list | 角色-菜单/按钮权限 |
| menu | 后台菜单 |
| config | 平台配置 |
| files / files_category | 文件与分类 |
| database_manage | 数据表元信息 |
| model_relation | 模型关联配置 |
| operation_log | 操作日志 |
安装后默认管理员:**admin / admin**(请及时修改密码)。
---
## 六、安装与使用
### 6.1 环境要求
- PHP >= 7.3(本包 `composer.json` 要求;ThinkPHP 6 项目常见为 `>=7.1`)
- MySQL 5.7+
- Composer
- 需安装 `topthink/think-multi-app`、`topthink/think-view`(版本见下方对应框架章节)
**ThinkPHP 6.x 宿主项目依赖参考(示例):**
```json
"php": ">=7.1.0",
"topthink/framework": "^6.0.15",
"topthink/think-orm": "^2.0",
"topthink/think-multi-app": "^1.0",
"topthink/think-view": "^1.0",
"topthink/think-captcha": "^3.0",
"liliuwei/thinkphp-jump": "^1.5"
```
详见 [第七章 ThinkPHP 6.x](#七thinkphp-6x-说明)。
**ThinkPHP 8.x 宿主项目依赖参考(示例):**
```json
"php": ">=8.0.0",
"topthink/framework": "^8.0",
"topthink/think-orm": "^3.0",
"topthink/think-multi-app": "^1.0",
"topthink/think-view": "^2.0",
"topthink/think-captcha": "^3.0",
"xvv/think-jump": "^1.0"
```
详见 [第八章 ThinkPHP 8.x](#八thinkphp-8x-兼容说明)。
### 6.2 Composer 安装
**从 Packagist 安装(包已发布后):**
```json
"july/julyadmin": "^1.0.1"
```
```bash
composer require july/julyadmin:^1.0.1
```
首次发布 Packagist 的步骤见仓库根目录 **[PACKAGIST.md](PACKAGIST.md)**。
在 ThinkPHP 项目的 `composer.json` 的 `require` 中加入:
```json
"july/julyadmin": "dev-master"
```
若包未发布到 Packagist,需自行在 `repositories` 中配置**你可访问的** Git 或 Composer 仓库地址,再执行:
```bash
composer require july/julyadmin:dev-master
```
**私有 Git 仓库安装(仅作者本地/内网测试示例,请勿当作公开安装源):**
以下为在**私有仓库**中验证安装时的写法,**必须将 `url` 换成你自己托管的仓库地址**;文档中**不提供**任何固定的公开 Git 地址,也不要把他人仓库地址写进生产项目。
```json
"repositories": [
{
"type": "git",
"url": "https://你的私有域名或内网地址/你的用户名/julyadmin.git"
}
],
"require": {
"july/julyadmin": "dev-master"
}
```
```bash
composer require july/julyadmin:dev-master
```
> 说明:能否 `composer install` 取决于你是否对该 `repositories.url` 拥有拉取权限;这与包功能无关,属于 Composer 源配置问题。
### 6.3 首次安装
1. 配置数据库连接 `config/database.php`
2. 浏览器访问:`http://你的域名/admin/install/index`(若配置了 `app_map`,使用映射名,如 `/pro/install/index`)
3. 安装程序将:
- 复制 `data/assets` → `public/static/assets`
- 复制 `webconfig` → 项目 `webconfig/`
- 执行 `sql/install.sql`
4. 安装锁:`public/static/assets/admin/install.lock`(删除后可重新安装)
### 6.4 扩展业务模块(推荐流程)
1. 在 MySQL 中创建业务表
2. 后台 **数据库管理** → 同步表 →(可选)配置关联 → 生成 Model
3. **UI 生成器** → 生成控制器与页面逻辑
4. **菜单管理** → 挂接菜单与权限
5. 按需重写 `buildForm`、`filterWhere` 等钩子
**手写控制器示例:**
```php
namespace app\admin\controller;
use app\common\model\Article as ArticleModel;
use july\julyadmin\admin\controller\Common;
use july\julyadmin\builder\traits\HasBuilder;
class Article extends Common
{
use HasBuilder;
protected $noNeedLogin = [];
protected $noPermissionAuth = [];
public function __construct()
{
parent::initialize();
$this->dataModel = new ArticleModel();
$this->pageTitle = '文章管理';
$this->allowRowEditField = ['sort', 'disabled'];
}
// 可选:重写 buildForm、buildPage 等
}
```
---
## 七、ThinkPHP 6.x 说明
适用于 **ThinkPHP 6.0 / 6.1** 宿主项目,与第八章(TP8)不要混用同一份依赖版本。
| 项目 | 说明 |
|------|------|
| 框架 | `topthink/framework` ^6.0(如 ^6.0.15) |
| ORM | `topthink/think-orm` ^2.0 |
| 视图 | `topthink/think-view` ^1.0 |
| 跳转页 | `liliuwei/thinkphp-jump` ^1.5,配置 `config/jump.php` 指向其 `dispatch_jump.tpl` |
| 多应用 | `topthink/think-multi-app` ^1.0 |
| 验证码 | `topthink/think-captcha` ^3.0 |
| Session | 历史上可直接 `session('admininfo', $model)`;仍建议改为数组,便于日后升级 TP8 |
| 请求方法 | 统一使用 `request()->isPost()` 等驼峰写法,勿写全小写 `ispost()`;详见 [第九章附录](#九附录助手函数与作废写法对照) |
可选:`topthink/think-worker` ^3.0(与业务是否使用 Workerman 有关,非本包硬性要求)。
---
## 八、ThinkPHP 8.x 兼容说明
**以下条目仅针对 ThinkPHP 8.x**,不要在 TP6 项目中按本章替换依赖。
| 项目 | 说明 |
|------|------|
| 框架 | `topthink/framework` ^8.0 |
| ORM | `topthink/think-orm` ^3.0 |
| 视图 | `topthink/think-view` ^2.0 |
| 跳转扩展 | 使用 `xvv/think-jump`,在 `config/jump.php` 配置 `dispatch_success_tpl` / `dispatch_error_tpl`(勿再用 `liliuwei/thinkphp-jump`) |
| Session | 登录必须使用 `$admininfo->toArray()` 写入 `session('admininfo')`,**禁止**直接存入 Model,否则易出现登录后立即掉线 |
| 请求方法 | 使用 `request()->isPost()` 等官方驼峰写法;全小写 `ispost()` 未列入手册且不利于静态分析,升级前请改掉,见 [第九章附录](#九附录助手函数与作废写法对照) |
安装后建议在项目根目录执行:
```bash
composer require topthink/think-view:^2.0
composer require xvv/think-jump:^1.0
```
---
## 九、附录:助手函数与作废写法对照
依据 ThinkPHP 官方手册整理(完整列表以官网为准):
- ThinkPHP 6.1:[助手函数](https://doc.thinkphp.cn/v6_1/zhushouhanshu.html)
- ThinkPHP 8.0:[助手函数](https://doc.thinkphp.cn/v8_0/helper.html)
> 说明:`framework/src/helper.php` 中注册的为**框架内置助手**;`topthink/think-helper` 另提供 `class_basename`、`collect`、`throw_if` 等,手册中常与框架助手一并列出,**并未作废**。
### 9.1 框架内置助手(TP6.1 / TP8 仍可用)
两版本 `helper.php` 中名称一致(TP8 另增 `rules()`,用于定义 `ValidateRuleSet`):
`abort`、`app`、`bind`、`cache`、`config`、`cookie`、`download`、`dump`、`env`、`event`、`halt`、`input`、`invoke`、`json`、`jsonp`、`lang`、`parse_name`、`redirect`、`request`、`response`、`session`、`token`、`token_field`、`token_meta`、`trace`、`url`、`validate`、`view`、`display`、`xml`、`app_path`、`base_path`、`config_path`、`public_path`、`runtime_path`、`root_path`(TP8 另有 `rules`)。
### 9.2 已从框架 `helper.php` 移除的助手(ThinkPHP 5.x → 6.0+)
以下在 **TP6 / TP8 中均不存在**,旧项目升级时若仍调用会报错,须改写:
| 作废助手 | 原用途(5.x) | 推荐替代 |
|----------|---------------|----------|
| `action()` | 调用模块/控制器/操作方法 | 路由指向控制器方法,或 `invoke()` / 直接实例化调用 |
| `behavior()` | 执行行为类 `run` | 中间件 `middleware`,或 `event()` 事件 |
| `call()` | 反射执行 callable | `invoke($callable, $args)` |
| `container()` | 获取容器实例 | `app()` 或 `think\Container::getInstance()` |
| `loader()` | 实例化 / 导入类(旧加载器) | Composer 自动加载 + `app()` / `invoke()` |
| `import()` | 导入命名空间类库 | Composer PSR-4 |
| `route()`(旧全局注册) | 5.x 式路由注册助手 | `Route` 门面 / `route/*.php` 路由定义文件 |
### 9.3 `request()` 请求类型判断(手册「请求类型」,非独立助手函数)
通过 `request()` 返回的 `think\Request` 实例判断 HTTP 方法,**官方仅记载驼峰方法名**:
| 类型 | 推荐(手册写法) |
|------|------------------|
| GET / POST / PUT / DELETE / PATCH / HEAD / OPTIONS | `isGet()`、`isPost()`、`isPut()`、`isDelete()`、`isPatch()`、`isHead()`、`isOptions()` |
| Ajax / Pjax / JSON / 手机 | `isAjax()`、`isPjax()`、`isJson()`、`isMobile()` |
| 运行环境 | `isCli()`、`isCgi()` |
**常见作废 / 不推荐写法:**
| 写法 | 状态 | 说明 |
|------|------|------|
| `IS_GET`、`IS_POST` 等常量 | **已作废**(TP5.0 起) | 改为 `request()->isGet()` 等 |
| `Request::instance()` | **已不推荐**(TP6+) | 使用 `request()` 助手或 `think\facade\Request` |
| `ispost()`、`isget()`、`isajax()` 全小写 | **非官方 API** | PHP 对**用户态**方法名大小写不敏感,可能仍能调到 `isPost()`,但 IDE/静态分析无法识别,代码评审与 TP8 升级均应按手册改为驼峰 |
| 3.x 字母助手 `I()`、`C()`、`D()`、`M()`、`A()`、`R()` 等 | **已作废**(TP5+) | 分别对应 `input()`、`config()`、`model()`、`Db`、`控制器调度`、`url()` 等,见 TP5 升级文档 |
### 9.4 其它与升级相关的作废 API(非 helper.php)
| 作废项 | 替代 / 说明 | 主要影响版本 |
|--------|-------------|--------------|
| `think\App::VERSION` 常量 | `version()` 方法 | TP8 标记 `@deprecated` |
| 继承 `think\Controller` 基类 | 普通类 + 路由 / 依赖注入 | TP6 升级指导 |
| 别名路由、控制器快捷路由、`_empty` 空操作 | 资源路由、`Route::miss`、`__call` | TP6 升级指导 |
| 配置 `url_param_type` | 统一「参数/值」路由传参 | TP6 |
| `think\cache\Driver::getReadTimes()` / `getWriteTimes()` | 避免依赖统计次数 | 源码 `@deprecated` |
| 扩展 `liliuwei/thinkphp-jump` | `xvv/think-jump` + `config/jump.php` | 宿主项目(见第七、八章) |
| `session('admininfo', Model)` | `session('admininfo', $model->toArray())` | TP8 序列化约束(见第八章) |
### 9.5 使用 julyadmin 时的建议
1. 业务与二次开发代码:**只使用第九章 9.1、9.3 中的现行写法**。
2. 从 TP5/旧 TP6 迁移:先用 9.2、9.4 表做全局搜索替换,再处理跳转扩展与 Session。
3. 本包内置代码中若仍出现 `ispost()`,与官方规范不一致,后续版本会逐步改为 `isPost()`。
---
## 十、目录结构
```
julyadmin/
├── data/assets/ # 后台静态资源(安装时复制到 public)
├── sql/install.sql # 安装脚本
├── src/
│ ├── admin/
│ │ ├── controller/ # 内置后台控制器
│ │ └── view/ # 后台视图(登录、首页、错误页)
│ ├── builder/ # 表单/表格构建器与 HasBuilder Traits
│ ├── common/ # 模型、逻辑类
│ ├── install/ # 安装控制器
│ ├── taglib/ # CMS 模板标签
│ ├── uploaddrives/ # 上传驱动
│ ├── webconfig/ # 配置模板
│ ├── AppRun.php # 多应用/包路由接管
│ └── Service.php # 服务注册
└── composer.json
```
---
## 十一、参与与致谢
### 作者与联系
| 项目 | 内容 |
|------|------|
| 主页 | [https://julytian.top](https://julytian.top) |
| 邮箱 | 1163433011@qq.com |
| 说明 | 安装、集成或使用中的疑问,请通过上述邮箱联系 |
### Composer 依赖(`composer.json`)
以下为 **本包声明** 的依赖版本约束(宿主 ThinkPHP 项目另需按第七、八章安装框架、ORM、视图、跳转扩展)。
**`require`(安装本包时由 Composer 一并解析):**
| 包名 | 版本约束 | 说明 |
|------|----------|------|
| `php` | `>=7.3` | 运行环境 |
| `topthink/think-multi-app` | `^1.0` | 多应用支持 |
| `topthink/think-captcha` | `^3.0` | 后台验证码 |
| `phpoffice/phpspreadsheet` | `^1.29` | Excel 导入导出 |
**`require-dev`(开发/联调本包源码时使用,宿主生产环境通常不安装):**
| 包名 | 版本约束 | 说明 |
|------|----------|------|
| `topthink/framework` | `^6.0\|^8.0` | ThinkPHP 框架(与宿主版本一致) |
**`suggest`(Composer 建议,宿主项目按 TP6/TP8 择一安装):**
| 包名 | 版本约束 | 说明 |
|------|----------|------|
| `topthink/think-view` | ThinkPHP 6:`^1.0`;ThinkPHP 8:`^2.0` | 视图渲染(后台页面必需) |
| `liliuwei/thinkphp-jump` | `^1.5` | 跳转提示页(仅 ThinkPHP 6 宿主) |
| `xvv/think-jump` | `^1.0` | 跳转提示页(仅 ThinkPHP 8 宿主) |
### 前端 JS 插件与商业授权
后台静态资源中的 JavaScript 插件位于 `data/assets/admin/js/`(安装后:`public/static/assets/admin/js/`)。
**官方明确表示商业使用需自行购买正版授权/商用许可的组件**(详见专文,勿使用「等」笼统带过):
| 组件 | 位置 | 说明 |
|------|------|------|
| **Highcharts** | `ueditor/third-party/highcharts/` | UEditor 图表功能依赖;商业/生产使用须向 [Highcharts](https://www.highcharts.com/license) 购买许可 |
| **高德地图 JS API** | `gaode-map/` + 配置项加载的 AMap SDK | 商业目的使用须向 [高德开放平台](https://lbs.amap.com/commercial) 取得技术服务许可 |
完整免责说明、其余开源插件清单与使用建议见:**[data/assets/admin/js/README.md](data/assets/admin/js/README.md)**。
> **免责:** 本包作者 July 仅对上述脚本进行收集与集成,**不出售、不代理** 任何第三方商业授权;商用请自行联系原厂商购买正版。
### UI 与静态资源致谢
- **光年(Lyear)** 后台模板
- **Layui** 前端组件库(开源 MIT,非收费的 LayuiAdmin 产品)