140 lines
5.2 KiB
Markdown
140 lines
5.2 KiB
Markdown
# 6.9 行政区划管理
|
||
|
||
:::tip 概述
|
||
行政区划管理维护全国省市区街道四级数据,支持按父编码级联查询。`CityService` 继承 `BaseService`(系统共享,不隔离),是导入导出中城市字段正反转换的支撑模块。
|
||
:::
|
||
|
||
## 模块特点
|
||
|
||
| 特性 | 说明 |
|
||
|------|------|
|
||
| 基类 | `BaseService`(系统共享,不隔离) |
|
||
| Trait 组合 | `HasCrudOperations, HasQueryScopes` |
|
||
| 层级结构 | `id/pid`(数字层级)+ `parent_code/area_code`(行政编码层级)双重标识 |
|
||
| 特殊接口 | `getByParentCode` 按父编码查询、`getProvinces` 省份列表、`getParent` 父级信息 |
|
||
| 详情/删除钩子 | `afterDetail` 补全父级名称;`beforeDelete` 业务校验 |
|
||
|
||
## 数据库表结构
|
||
|
||
```sql
|
||
CREATE TABLE `laravel_city` (
|
||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||
`city_code` varchar(6) NOT NULL COMMENT '城市区号',
|
||
`area_code` varchar(20) NOT NULL COMMENT '行政编码',
|
||
`parent_code` varchar(20) DEFAULT NULL COMMENT '上级行政编码',
|
||
`zip_code` varchar(6) NOT NULL COMMENT '邮政编码',
|
||
`level` int DEFAULT 0 COMMENT '城市级别:0-省份 1-城市 2-县区 3-街道',
|
||
`pid` int DEFAULT 0 COMMENT '上级城市ID',
|
||
`name` varchar(150) NOT NULL COMMENT '城市名称',
|
||
`short_name` varchar(150) NOT NULL COMMENT '城市简称',
|
||
`full_name` varchar(150) DEFAULT NULL COMMENT '城市全称',
|
||
`pinyin` varchar(150) DEFAULT NULL COMMENT '城市拼音',
|
||
`lng` varchar(150) DEFAULT NULL COMMENT '城市经度',
|
||
`lat` varchar(150) DEFAULT NULL COMMENT '城市纬度',
|
||
`create_user` varchar(50) DEFAULT NULL COMMENT '创建人',
|
||
`create_time` datetime DEFAULT (now()) COMMENT '创建时间',
|
||
`update_user` varchar(50) DEFAULT NULL COMMENT '更新人',
|
||
`update_time` datetime DEFAULT (now()) COMMENT '更新时间',
|
||
`is_delete` int DEFAULT 0 COMMENT '删除标识:0-正常 1-已删除',
|
||
PRIMARY KEY (`id`)
|
||
) COMMENT = '城市行政区划表';
|
||
```
|
||
|
||
## API 接口
|
||
|
||
| 方法 | 路径 | 权限码 | 说明 |
|
||
|------|------|--------|------|
|
||
| GET | `/api/city/list` | sys:city:list | 城市列表 |
|
||
| GET | `/api/city/detail/{id}` | sys:city:detail | 详情 |
|
||
| POST | `/api/city/add` | sys:city:add | 新增 |
|
||
| PUT | `/api/city/update` | sys:city:update | 修改 |
|
||
| DELETE | `/api/city/delete/{id}` | sys:city:delete | 删除 |
|
||
| DELETE | `/api/city/batchDelete` | sys:city:batchDelete | 批量删除 |
|
||
| GET | `/api/city/getCityList/{code}` | — | 按父编码获取子级城市(级联) |
|
||
| GET | `/api/city/getParent/{id}` | — | 获取父级信息 |
|
||
| GET | `/api/city/findByParentCode` | — | 按父编码查询子级 |
|
||
|
||
## Service 配置(来自项目实际代码)
|
||
|
||
```php
|
||
class CityService extends BaseService
|
||
{
|
||
use HasCrudOperations, HasQueryScopes;
|
||
|
||
protected string $modelClass = City::class;
|
||
|
||
// 模糊搜索支持名称、全称、拼音
|
||
protected array $pageLikeFields = ['name', 'full_name', 'pinyin'];
|
||
|
||
// 精确匹配级别与上级
|
||
protected array $pageEqFields = ['level', 'pid'];
|
||
|
||
protected array $pageOrderBy = ['field' => 'id', 'type' => 'asc'];
|
||
|
||
// 树形结构(pid 层级)
|
||
protected string $treeParentField = 'pid';
|
||
protected string $treeLikeField = 'name';
|
||
|
||
/**
|
||
* 详情查询后处理:补全父级名称
|
||
*/
|
||
protected function afterDetail(int $id, array &$data): void
|
||
{
|
||
$pid = $data['pid'] ?? 0;
|
||
if ($pid > 0) {
|
||
$parent = City::find($pid);
|
||
$data['parentName'] = $parent?->name ?? '';
|
||
} else {
|
||
$data['parentName'] = '';
|
||
}
|
||
}
|
||
|
||
// 按父级行政编码获取子级城市(级联选择数据源)
|
||
public function getByParentCode(string $parentCode): array { /* ... */ }
|
||
|
||
// 获取省份列表(level=0)
|
||
public function getProvinces(): array { /* ... */ }
|
||
|
||
// 获取某城市的父级信息
|
||
public function getParent(int $id): ?array { /* ... */ }
|
||
}
|
||
```
|
||
|
||
## 前端级联选择
|
||
|
||
```typescript
|
||
// ui/src/api/data/city.ts
|
||
export function getCityList(parentCode: string) {
|
||
return http.request({
|
||
url: '/city/getCityList/' + parentCode,
|
||
method: 'GET',
|
||
});
|
||
}
|
||
|
||
// 省 → 市 → 区 → 街道 级联加载
|
||
// 选择省份后加载城市,选择城市后加载区县...
|
||
```
|
||
|
||
## 模型辅助方法
|
||
|
||
City 模型提供两个静态方法,供导入导出使用:
|
||
|
||
| 方法 | 用途 | 示例 |
|
||
|------|------|------|
|
||
| `resolveCityNames(codes)` | 编码→名称 | `['320000000000','320100000000']` → `'江苏省,南京市'` |
|
||
| `resolveCityCodes(info)` | 名称→编码 | `'江苏省,南京市,建邺区'` → `['320000000000','320100000000','320105000000','']` |
|
||
|
||
```php
|
||
// 导出时:城市编码拼为名称字符串
|
||
$cityInfo = City::resolveCityNames(['320000000000', '320100000000', '320105000000']);
|
||
// 结果: "江苏省,南京市,建邺区"
|
||
|
||
// 导入时:城市名称反查为编码数组(逐级匹配,避免同名歧义)
|
||
$codes = City::resolveCityCodes('江苏省,南京市,建邺区');
|
||
// 结果: ['320000000000', '320100000000', '320105000000', '']
|
||
```
|
||
|
||
:::tip 数据来源
|
||
全国行政区划数据已包含在数据库初始化脚本中(`document/mysql/` 导入即有),无需手动录入。见 [2.5 数据库初始化](/zh/quickstart/database-init.html)。
|
||
:::
|