@cfygaoyang
2018-07-09T03:47:00.000000Z
字数 12883
阅读 733
APP
所有api接口请求,http header 定义 content-type: application/json;
上传文件请求方式为 form-data
服务器ip/host参考接口附件
POST /api/access_token
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
area | 字符串 | 可选 | 国际区号:默认中国 |
account | 字符串 | 是 | 手机号/邮箱 |
password | 字符串 | 是 | 密码 |
appid | 字符串 | 是 | 厂商标识 |
{
"code": 0,
"status": "success",
"message": {
"access_token": "884ffcc9d7af0b9a9abb2d1696a4a9db0a80b2bba2dc79fa4b05d10ebdd9",
"expires_in": 604800,
"expires_at": "2018-02-05 15:14:23",
"refresh_token": "f28f213ca3e202c4feca66b1eec863c68adf7aa570e4a6cf4d270382bf95"
}
}
参数 | 类型 | 说明 |
---|---|---|
access_token | 字符串 | 用于接口authorization中的token |
expires_in | 整型 | access_token有效期;单位:秒 |
expires_at | 字符串 | access_token有效期时间截止 |
refresh_token | 字符串 | 用于刷新token |
POST /api/access_token
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
area | 字符串 | 可选 | 国际区号:默认中国 |
account | 字符串 | 是 | 手机号/邮箱 |
code | 字符串 | 是 | 验证码 |
appid | 字符串 | 是 | 厂商标识 |
{
"code": 0,
"status": "success",
"message": {
"access_token": "884ffcc9d7af0b9a9abb2d1696a4a9db0a80b2bba2dc79fa4b05d10ebdd9",
"expires_in": 604800,
"expires_at": "2018-02-05 15:14:23",
"refresh_token": "f28f213ca3e202c4feca66b1eec863c68adf7aa570e4a6cf4d270382bf95"
}
}
参数 | 类型 | 说明 |
---|---|---|
access_token | 字符串 | 用于接口authorization中的token |
expires_in | 整型 | access_token有效期;单位:秒 |
expires_at | 字符串 | access_token有效期时间截止 |
refresh_token | 字符串 | 用于刷新token |
POST /api/refresh_token
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
refresh_token | 字符串 | 是 | 刷新Token |
{
"code":0,
"status":"success",
"message":{
"access_token":"aa660df56d9bef4e4136af4ecfd9c71476dc804471fe73531ca73e3a67c2",
"expires_in":604800,
"expires_at":"2018-06-27 14:16:53",
"refresh_token":"6acbb2361c99a7363cb91e86a73496d07dcb0910038b1f96b60af707b0fa"
}
}
参数 | 类型 | 说明 |
---|---|---|
access_token | 字符串 | 用于接口authorization中的token |
expires_in | 整型 | access_token有效期;单位:秒 |
expires_at | 字符串 | access_token有效期时间截止 |
refresh_token | 字符串 | 用于刷新token |
POST /api/destroy_token
{
"Authorization": " Token c8b1243cc508efc1e0d07e7a4091cee566d9976320edab08ea86886eeb27"
}
{
"code": 0,
"status": "success",
"message": ""
}
POST /api/send_code
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
area | 字符串 | 可选 | 国际区号:默认中国 |
account | 字符串 | 是 | 手机/邮箱 |
flag | 整型 | 可选 | 标签:1注册2修改密码 |
appid | 字符串 | 是 | 厂商标识 |
{
"code": 0,
"status": "success",
"message": ""
}
POST /api/reset_password
{
"Authorization": " Token c8b1243cc508efc1e0d07e7a4091cee566d9976320edab08ea86886eeb27"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
old_password | 字符串 | 可选 | 旧密码 |
password | 字符串 | 是 | 密码 |
{
"code": 0,
"status": "success",
"message": ""
}
GET /api/user/info
{
"Authorization": " Token c8b1243cc508efc1e0d07e7a4091cee566d9976320edab08ea86886eeb27"
}
{
"code": 0,
"status": "success",
"message": {
"id": 1,
"created_at": "2018-01-08 15:55:03",
"updated_at": "2018-01-08 15:55:03",
"avatar": "",
"birthday": "",
"sex": 2,
"city": "",
"address": "",
"user": 1,
"username": "18888888889",
"phone": "18888888889",
"email": "",
"company": "上海庆科",
"job": "Python",
"name": "张三"
}
}
参数 | 类型 | 说明 |
---|---|---|
avatar | 字符串 | 头像 |
birthday | 字符串 | 生日 |
sex | 整型 | 性别 (2:女 1:男 0:未知) |
city | 字符串 | 城市 |
address | 字符串 | 住址 |
username | 字符串 | 昵称 |
phone | 字符串 | 手机 |
字符串 | 邮箱 | |
name | 字符串 | 姓名 |
company | 字符串 | 公司 |
job | 字符串 | 职位 |
PUT /api/user/info
{
"Authorization": " Token c8b1243cc508efc1e0d07e7a4091cee566d9976320edab08ea86886eeb27"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
avatar | 字符串 | 可选 | 头像 |
birthday | 字符串 | 可选 | 生日 |
sex | 整型 | 可选 | 性别 (2:女 1:男 0:未知) |
city | 字符串 | 可选 | 城市 |
address | 字符串 | 可选 | 住址 |
username | 字符串 | 可选 | 昵称 |
phone | 字符串 | 可选 | 手机 |
字符串 | 可选 | 邮箱 | |
name | 字符串 | 可选 | 姓名 |
company | 字符串 | 可选 | 公司 |
job | 字符串 | 可选 | 职位 |
{
"code": 0,
"status": "success",
"message": {
"id": 1,
"created_at": "2018-01-08 15:55:03",
"updated_at": "2018-01-08 15:55:03",
"avatar": "",
"birthday": "",
"sex": 2,
"city": "",
"address": "",
"user": 1,
"username": "18888888889",
"phone": "18888888889",
"email": ""
}
}
参数 | 类型 | 说明 |
---|---|---|
avatar | 字符串 | 头像 |
birthday | 字符串 | 生日 |
sex | 整型 | 性别 (2:女 1:男 0:未知) |
city | 字符串 | 城市 |
address | 字符串 | 住址 |
username | 字符串 | 昵称 |
phone | 字符串 | 手机 |
字符串 | 邮箱 | |
name | 字符串 | 姓名 |
company | 字符串 | 公司 |
job | 字符串 | 职位 |
POST /api/account_check
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
area | 字符串 | 可选 | 国际区号:默认中国 |
account | 字符串 | 是 | 手机 /邮箱 |
appid | 字符串 | 是 | 厂商标识 |
{
"code": 0,
"status": "success",
"message": {
"flag": true
}
}
参数 | 类型 | 说明 |
---|---|---|
flag | boolean | 是否已注册 |
POST /api/device/bind
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
is_admin | 整型 | 可选 | 用户角色:1 管理员 0 分享用户 ;默认为0 |
device_name | 字符串 | 可选 | 设备名称:默认:紫光智能锁 |
{
"code": 0,
"status": "success",
"message": {
"is_admin": 1,
"device": "xxxxxx",
"user_id": 1,
"device_name": "紫光智能锁"
}
}
参数 | 类型 | 说明 |
---|---|---|
device | 字符串 | 设备uuid |
is_admin | 整型 | 用户角色:1 管理员 0 分享用户 |
user_id | 整型 | 用户id |
device_name | 字符串 | 设备设备昵称 |
DELETE /api/device/bind/{uuid}
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | url参数;设备uuid |
is_admin | 整型 | 可选 | url参数;用户角色:1 管理员 0 分享用户 ;默认为0 |
{
"code": 0,
"status": "success",
"message": ""
}
POST /api/client/bind
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
client_id | 字符串 | 是 | 推送唯一标识符 |
{
"code": 0,
"status": "success",
"message": ""
}
POST /api/push/switch
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
switch | 整型 | 是 | 开关状态;0关闭1开启 |
{
"code": 0,
"status": "success",
"message": {
"switch": 1,
"user_id": 1,
"appid": "xxxxxxx"
}
}
GET /api/push/switch
{
"Authorization": "Token 123456"
}
{
"code": 0,
"status": "success",
"message": {
"switch": 1,
"user_id": 1,
"appid": "xxxxxxx"
}
}
GET /api/lock/user
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
user_tyoe | 整型 | 可选 | 用户类型 |
* 请求回调
{
"code": 0,
"status": "success",
"message": [
{
"user_name": "小明",
"user_avatar": "http://xxx.com/xxx.jpg",
"user_role": 2,
"user_id": 1,
"user_type": 1,
"timestamp": "15200000000",
"created_at": 15200000000
}
]
}
参数 | 类型 | 说明 |
---|---|---|
user_name | 字符串 | 锁用户昵称 |
user_avatar | 字符串 | 头像地址 |
timestamp | 字符串 | 创建时间戳(单位:秒) |
user_role | 整型 | 用户角色 |
user_type | 整型 | 用户类型;0:APP用户1:密码2:指纹3:感应卡 |
user_id | 整型 | 锁用户id |
created_at | 整型 | 唯一标识(微秒时间戳) |
PUT /api/lock/user/{created_at}
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
created_at | 整型 | 是 | url参数;唯一标识(微秒时间戳) |
user_name | 字符串 | 可选 | 锁用户昵称 |
user_avatar | 字符串 | 可选 | 头像地址 |
* 请求回调
{
"code": 0,
"status": "success",
"message":
{
"id": "xxxxxx",
"user_name": "小明",
"user_avatar": "http://xxx.com/xxx.jpg",
"user_role": 2,
"user_id": 1,
"timestamp": "15200000000",
"created_at": 15200000000
}
}
GET /api/device/get/{deivce}
{
"Authorization": "Token 123456"
}
{
"code": 0,
"status": "success",
"message": {
"device": "xxxxxx",
"device_name": "智能锁"
}
}
参数 | 类型 | 说明 |
---|---|---|
device | 字符串 | url参数;设备uuid |
device_name | 字符串 | 设备名称 |
PUT /api/device/set/{deivce}
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | url参数;设备uuid |
device_name | 字符串 | 是 | 设备名称 |
* 请求回调
{
"code": 0,
"status": "success",
"message": ""
}
只有管理员有权限设置
GET /api/feedback/category
{
"Authorization: Token 1234567890"
}
{
"code": 0,
"status": "success",
"message": {
"total": 5,
"pages": 1,
"current_page": 1,
"page_size": 20,
"data": [
{
"id": 1,
"appid": "",
"created_at": "2018-03-26 09:52:39",
"updated_at": "2018-03-26 09:52:39",
"category_name": "设备使用问题"
},
{
"id": 2,
"appid": "",
"created_at": "2018-03-26 09:53:41",
"updated_at": "2018-03-26 09:53:41",
"category_name": "APP使用出错"
},
{
"id": 3,
"appid": "",
"created_at": "2018-03-26 09:53:56",
"updated_at": "2018-03-26 09:53:56",
"category_name": "设备配网问题"
},
{
"id": 4,
"appid": "",
"created_at": "2018-03-26 09:54:07",
"updated_at": "2018-03-26 09:54:07",
"category_name": "功能与设计建议"
},
{
"id": 5,
"appid": "",
"created_at": "2018-03-26 09:54:15",
"updated_at": "2018-03-26 09:54:15",
"category_name": "其他"
}
]
}
}
GET /api/feedback
{
"Authorization: Token 1234567890"
}
{
"code": 0,
"status": "success",
"message": {
"total": 1,
"pages": 1,
"current_page": 1,
"page_size": 20,
"data": [
{
"id": 1,
"appid": "",
"created_at": "2018-03-26 10:21:20",
"updated_at": "2018-03-26 10:21:20",
"feedback_content": "配网不成功",
"device": "xxx-xxx-xxx-xxx",
"category": 2,
"user": 2
}
]
}
}
POST /api/feedback
{
"Authorization: Token 1234567890"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
feedback_content | 字符串 | 是 | 反馈内容 |
category | 整型 | 可选 | 反馈类型 |
device | 字符串 | 可选 | 设备uuid |
* 请求回调
{
"code": 0,
"status": "success",
"message": {
"id": 1,
"appid": "",
"created_at": "2018-03-26 10:21:20",
"updated_at": "2018-03-26 10:21:20",
"feedback_content": "配网不成功",
"device": "xxx-xxx-xxx-xxx",
"category": 2,
"user": 2
}
}
GET /api/feedback/{pk}
{
"Authorization: Token 1234567890"
}
{
"code": 0,
"status": "success",
"message": {
"id": 1,
"appid": "",
"created_at": "2018-03-26 10:21:20",
"updated_at": "2018-03-26 10:21:20",
"feedback_content": "配网不成功",
"device": "xxx-xxx-xxx-xxx",
"category": 2,
"user": 2
}
}
PUT /api/feedback/{pk}
{
"Authorization: Token 1234567890"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
feedback_content | 字符串 | 是 | 反馈内容 |
category | 整型 | 是 | 反馈类型 |
device | 字符串 | 可选 | 设备uuid |
* 请求回调
{
"code": 0,
"status": "success",
"message": {
"id": 1,
"appid": "",
"created_at": "2018-03-26 10:21:20",
"updated_at": "2018-03-26 10:24:49",
"feedback_content": "配网不成功",
"device": "xxx-xxx-xxx-xxx",
"category": 2,
"user": 2
}
}
DELETE /api/feedback/{pk}
{
"Authorization: Token 1234567890"
}
{
"code": 0,
"status": "success",
"message": ""
}
POST /api/upload/img
form-data 请求方式; 对应的 key 为 img
与其他api接口有区别
{
"Authorization": "Token 123456"
}
{
"code": 0,
"status": "success",
"message": {
"img_path": "/storage/uploads/img/20180614153221.jpg"
}
}
img_path 为图片 path 路径;完整路径为 host + path
GET /api/lock/state
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
{
"code": 0,
"status": "success",
"message": {
"remote": {
"state": 0,
"timer": 0,
"remote_id": 1
},
"battery_percentage": 100,
"main_lock_state": true,
"back_lock_state": true,
"child_lock_state": true,
"remote_id": 20
}
}
参数 | 类型 | 说明 |
---|---|---|
status | 整型 | 0:开门失败;1:开门成功;2:等待开门;3:其他 |
timer | 整型 | 等待开门的倒计时时间段;单位(秒) |
main_lock_state | bool | 主锁状态 |
back_lock_state | bool | 反锁状态 |
child_lock_state | bool | 童锁状态 |
应用场景:
当 status=2
剩余有效时间 timer
当 status=0 或 1
远程开门结果;timer无效
当 status=3
其他
GET /api/lock/alarm
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
start_time | 整型 | 可选 | 起始时间戳;单位(微秒) |
end_time | 整型 | 可选 | 结束时间戳单位(微秒):默认为0,表示当前 |
{
"code": 0,
"status": "success",
"message": [
{
"alarm_type": 1,
"timestamp": "15200000000",
"user_type": 1,
"user_id": 1,
"created_at": 15200000000
}
]
}
参数 | 类型 | 说明 |
---|---|---|
timestamp | 字符串 | 设备时间戳;单位(秒) |
created_at | 整型 | 唯一标识(微秒时间戳) |
user_type | 整型 | 用户类型 |
GET /api/lock/open
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
user_type | 整型 | 可选 | 用户类型 |
start_time | 整型 | 可选 | 起始时间戳 |
end_time | 整型 | 可选 | 结束时间戳:默认为0,表示当前 |
{
"code": 0,
"status": "success",
"message": [
{
"user_type": 1,
"user_avatar": "",
"user_name": "用户1",
"timestamp": "15200000000",
"created_at": 15200000000
}
]
}
参数 | 类型 | 说明 |
---|---|---|
timestamp | 字符串 | 时间戳;单位(秒) |
created_at | 整型 | 唯一标识(微秒时间戳) |
user_type | 整型 | 用户类型 |
user_name | 字符串 | 锁用户名 |
user_avatar | 字符串 | 锁用户头像 |
GET /api/app/config
{
"code": 0,
"status": "success",
"message": {
"id": 1,
"appid": "XypDWhPWT2c0k5reNcuCgzHbi7BydFJkB8bnr4YV",
"created_at": "2018-06-15 00:00:00",
"updated_at": "2018-06-15 00:00:00",
"app_version": "V1.0.0",
"user_protocol": "http://www.baidu.com/"
}
}
参数 | 类型 | 说明 |
---|---|---|
app_version | 字符串 | app版本号 |
user_protocol | 字符串 | 用户协议地址 url |
GET /api/carousel
{
"code":0,
"status":"success",
"message":[
{
"id": 1,
"picture_url": "http://xxx.xx/xxx.jpg",
"picture_index": 1,
"out_url": "http://xxx.xx/xxx"
}
]
参数 | 类型 | 说明 |
---|---|---|
picture_url | 字符串 | 图片地址 |
picture_index | 整型 | 图片索引 |
out_url | 字符串 | 跳转地址 |
GET /api/alarm/phone
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
* 请求回调
{
"code":0,
"status":"success",
"message":[
{
"created_at": 100000000000000,
"device": "xxxxxxxx",
"user_id": 1,
"phone": "18656666666"
}
]
}
参数 | 类型 | 说明 |
---|---|---|
created_at | 整型 | 唯一标识(微秒时间戳) |
device | 字符串 | 设备uuid |
user_id | 整型 | 用户user_id |
phone | 字符串 | 报警电话 |
POST /api/alarm/phone
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
phone | 字符串 | 是 | 报警电话 |
* 请求回调
{
"code":0,
"status":"success",
"message":{
"device": "xxxxxx",
"phone": "18856666666",
"user_id": 1,
"created_at": 15555555555555
}
}
参数 | 类型 | 说明 |
---|---|---|
device | 字符串 | 设备uuid |
phone | 字符串 | 报警电话 |
user_id | 整型 | 用户id |
created_at | 整型 | 唯一标识(微秒时间戳) |
PUT /api/alarm/phone/{created_at}
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
created_at | 整型 | url参数;唯一标识(微秒时间戳) | |
device | 字符串 | 是 | 设备uuid |
phone | 字符串 | 是 | 报警电话 |
* 请求回调
{
"code":0,
"status":"success",
"message": {
"device": "xxxxxx",
"phone": "18856666666",
"user_id": 1,
"created_at": 15555555555555
}
}
参数 | 类型 | 说明 |
---|---|---|
device | 字符串 | 设备uuid |
phone | 字符串 | 报警电话 |
user_id | 整型 | 用户id |
created_at | 整型 | 唯一标识(微秒时间戳) |
DELETE /api/alarm/phone/{created_at}
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
created_at | 整型 | url参数;唯一标识(微秒时间戳) | |
device | 字符串 | 是 | url参数;设备uuid |
* 请求回调
{
"code":0,
"status":"success",
"message":""
}
GET /api/hijack/alarm/phone
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
user_created_at | 整型 | 是 | 锁用户唯一标识 |
* 请求回调
{
"code":0,
"status":"success",
"message":[
{
"created_at": 100000000000000,
"user_created_at": 100000000000000,
"device": "xxxxxxxx",
"user_id": 1,
"phone": "18656666666"
}
]
}
参数 | 类型 | 说明 |
---|---|---|
user_created_at | 整型 | 锁用户唯一标识(微秒时间戳) |
created_at | 整型 | 唯一标识(微秒时间戳) |
device | 字符串 | 设备uuid |
user_id | 整型 | 用户user_id |
phone | 字符串 | 报警电话 |
POST /api/hijack/alarm/phone
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
device | 字符串 | 是 | 设备uuid |
phone | 字符串 | 是 | 报警电话 |
user_created_at | 整型 | 是 | 所用户唯一标识(微秒时间戳) |
* 请求回调
{
"code":0,
"status":"success",
"message": {
"created_at": 100000000000000,
"user_created_at": 100000000000000,
"device": "xxxxxxxx",
"user_id": 1,
"phone": "18656666666"
}
}
参数 | 类型 | 说明 |
---|---|---|
user_created_at | 整型 | 所用户唯一标识(微秒时间戳) |
created_at | 整型 | 唯一标识(微秒时间戳) |
device | 字符串 | 设备uuid |
user_id | 整型 | 用户user_id |
phone | 字符串 | 报警电话 |
PUT /api/hijack/alarm/phone/{created_at}
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
created_at | 整型 | url参数;唯一标识(微秒时间戳) | |
device | 字符串 | 是 | 设备uuid |
phone | 字符串 | 是 | 报警电话 |
* 请求回调
{
"code":0,
"status":"success",
"message": {
"created_at": 100000000000000,
"user_created_at": 100000000000000,
"device": "xxxxxxxx",
"user_id": 1,
"phone": "18656666666"
}
}
参数 | 类型 | 说明 |
---|---|---|
user_created_at | 整型 | 所用户唯一标识(微秒时间戳) |
created_at | 整型 | 唯一标识(微秒时间戳) |
device | 字符串 | 设备uuid |
user_id | 整型 | 用户user_id |
phone | 字符串 | 报警电话 |
DELETE /api/hijack/alarm/phone/{created_at}
{
"Authorization": "Token 123456"
}
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
created_at | 整型 | url参数;唯一标识(微秒时间戳) | |
device | 字符串 | 是 | url参数;设备uuid |
* 请求回调
{
"code":0,
"status":"success",
"message":""
}
POST /api/device/restore
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
sn | 字符串 | 是 | 设备sn号 |
signature | 字符串 | 是 | 签名 |
* 请求回调
{
"code":0,
"status":"success",
"message": ""
}
错误码 | 错误信息 | 描述 |
---|---|---|
10000 | ... | 通用错误码 |
10001 | the phone is registered | 手机号已注册 |
10002 | the phone is not registered | 手机号未注册 |
10003 | 触发分钟级流控Permits:1 | 获取验证码太频繁 |
10004 | invalid token | token无效 |
10005 | The code is invalid | 验证码无效 |
10006 | The password is invalid | 密码错误 |
10007 | invalid phone | 手机不合法 |