产线软件 API 对接文档
所有接口地址:https://sf6.xahrf.cn/api.php
登录、刷新接口无需 Access Token,其他业务接口使用 Authorization: Bearer <access_token>
Access Token:有效期 2 小时(expires_in: 7200);Refresh Token:有效期 90 天,每次刷新都会轮换,旧值立即失效。
1. 员工账号密码登录

POST https://sf6.xahrf.cn/api.php?action=employee_login

参数说明
username员工账号
password员工密码
device_id必填。Qt 首次启动生成 UUID,并通过 QSettings 长期保存

返回字段说明:

字段类型说明
access_tokenstring业务接口认证令牌
refresh_tokenstring仅用于刷新令牌,必须安全保存
expires_inintAccess Token 有效秒数,固定 7200
refresh_expires_inintRefresh Token 有效秒数,固定 7776000(90 天)
userobject当前员工信息
{
  "success": true,
  "message": "登录成功",
  "data": {
    "access_token": "短期令牌",
    "refresh_token": "长期刷新令牌",
    "expires_in": 7200,
    "refresh_expires_in": 7776000,
    "user": {
      "id": 2,
      "username": "zhangsan",
      "real_name": "张三",
      "role": "employee",
      "group_name": "生产一部"
    }
  }
}
2. SSO / 钉钉扫码登录后换取 OSS 令牌

POST https://sf6.xahrf.cn/api.php?action=employee_sso_login

提交 SSO 扫码流程获得的 access_token 和本机 device_id。成功响应与员工账号密码登录一致。

{
  "access_token": "SSO 返回的令牌",
  "device_id": "550e8400-e29b-41d4-a716-446655440000"
}
3. 刷新 Access Token

POST https://sf6.xahrf.cn/api.php?action=refresh_token,请求类型 application/json

{
  "refresh_token": "当前保存的刷新令牌",
  "device_id": "550e8400-e29b-41d4-a716-446655440000"
}

刷新成功会同时返回新的 access_tokenrefresh_token。客户端必须原子替换两个值,旧 Refresh Token 立即失效。

4. 注销当前设备

POST https://sf6.xahrf.cn/api.php?action=logout,JSON 参数为 refresh_token 与同一 device_id。只注销当前设备,不影响同一账号的其他电脑。

Qt 刷新策略:在 Access Token 过期前 5 分钟刷新;同一时刻只允许一个刷新请求。业务接口返回 access_token_expiredaccess_token_invalid 时,刷新一次并将原请求重试一次。Refresh Token 过期、被注销、设备不匹配或账号禁用时,清除令牌并返回钉钉扫码页面。
5. 获取生产任务

GET https://sf6.xahrf.cn/api.php?action=tasks,请求头:Authorization: Bearer <access_token>

返回当前登录员工的待生产/生产中任务,无需传递 user_id。根据分配模式返回不同的统计字段。

返回字段说明:

字段类型说明
idint任务ID
task_namestring任务名称
planned_quantityint计划数量
meter_rangestring表计量程
accuracy_levelstring精度等级
distribution_modestring分配模式(average=平均分配,grab=抢单模式)
statusstring任务状态(pending=待生产,running=生产中)
completed_countint平均分配模式:已完成数量
my_assigned_countint平均分配模式:当前用户被分配的数量
pending_countint抢单模式:剩余可抢数量
my_locked_countint抢单模式:当前员工已锁定数量
specification_infoobject规格参数对象
specification_info.rated_valuestring额定值
specification_info.alarm1_valuestring报警1值
specification_info.lock1_valuestring锁定1值
specification_info.lock2_valuestring锁定2值
specification_info.overpressure_valuestring超压值
{
  "success": true,
  "has_task": true,
  "data": [{
    "id": 1,
    "task_name": "压力表任务A",
    "planned_quantity": 100,
    "meter_range": "0-2.5MPa",
    "accuracy_level": "1.6",
    "distribution_mode": "average",
    "status": "pending",
    "completed_count": 25,
    "my_assigned_count": 50,
    "specification_info": {
      "rated_value": "1.600",
      "alarm1_value": "1.800",
      "lock1_value": "2.000",
      "lock2_value": "2.200",
      "overpressure_value": "2.500"
    }
  }]
}
6. 获取可抢单的任务列表(抢单模式)

GET https://sf6.xahrf.cn/api.php?action=grab_tasks,请求头:Authorization: Bearer <access_token>

返回抢单模式下可抢的任务列表,包含每个任务的剩余可抢数量和当前员工已锁定数量,无需传递 user_id。

返回字段说明:

字段类型说明
task_idint任务ID
task_namestring任务名称
rated_valuestring额定值
alarm1_valuestring报警1值
lock1_valuestring锁定1值
lock2_valuestring锁定2值
overpressure_valuestring超压值
meter_rangestring表计量程
accuracy_levelstring精度等级
planned_quantityint计划总数
distribution_modestring分配模式(grab=抢单模式)
pending_countint剩余可抢数量
my_locked_countint当前员工已锁定数量
{
  "success": true,
  "data": [{
    "task_id": 1,
    "task_name": "压力表任务A",
    "rated_value": "1.600",
    "alarm1_value": "1.800",
    "lock1_value": "2.000",
    "lock2_value": "2.200",
    "overpressure_value": "2.500",
    "meter_range": "0-2.5MPa",
    "accuracy_level": "1.6",
    "planned_quantity": 100,
    "distribution_mode": "grab",
    "pending_count": 50,
    "my_locked_count": 2
  }]
}
7. 抢单(锁定计划数)

POST https://sf6.xahrf.cn/api.php?action=grab_task_item

员工抢单时调用,系统锁定一个计划数并返回计划数编号。锁定后其他员工无法抢该计划数。

参数必填说明
task_id任务ID
curl -X POST "https://sf6.xahrf.cn/api.php?action=grab_task_item" \
  -H "Authorization: Bearer <access_token>" \
  -d "task_id=1"

返回字段说明:

字段类型说明
item_idint计划数ID(用于释放或关联上传)
item_numberint计划数编号(该任务下的序号)
{
  "success": true,
  "message": "抢单成功",
  "data": {
    "item_id": 5,
    "item_number": 3
  }
}
8. 释放已锁定的计划数

POST https://sf6.xahrf.cn/api.php?action=release_task_item

员工可主动释放已锁定但未完成的任务,释放后其他员工可抢。

参数必填说明
item_id计划数ID(抢单成功返回的 item_id)
curl -X POST "https://sf6.xahrf.cn/api.php?action=release_task_item" \
  -H "Authorization: Bearer <access_token>" \
  -d "item_id=5"
{
  "success": true,
  "message": "已释放计划数"
}
9. 获取我的已锁定/已完成任务

GET https://sf6.xahrf.cn/api.php?action=my_task_items,请求头:Authorization: Bearer <access_token>

返回当前登录员工已锁定和已完成的任务列表,包含任务详情和计划数信息,无需传递 user_id。

返回字段说明:

字段类型说明
idint计划数ID
task_idint所属任务ID
item_numberint计划数编号
task_namestring任务名称
rated_valuestring额定值
alarm1_valuestring报警1值
lock1_valuestring锁定1值
lock2_valuestring锁定2值
overpressure_valuestring超压值
meter_rangestring表计量程
accuracy_levelstring精度等级
distribution_modestring分配模式
statusstring状态(locked=已锁定,completed=已完成)
assigned_user_idint分配的员工ID
{
  "success": true,
  "data": [{
    "id": 5,
    "task_id": 1,
    "item_number": 3,
    "task_name": "压力表任务A",
    "rated_value": "1.600",
    "alarm1_value": "1.800",
    "lock1_value": "2.000",
    "lock2_value": "2.200",
    "overpressure_value": "2.500",
    "meter_range": "0-2.5MPa",
    "accuracy_level": "1.6",
    "distribution_mode": "grab",
    "status": "locked",
    "assigned_user_id": 2
  }]
}
10. 表盘图片与表编号上传服务器

POST multipart/form-data https://sf6.xahrf.cn/api.php?action=upload_dial,请求头:Authorization: Bearer <access_token>

上传表盘时传入 task_item_id 可将上传与计划数关联,完成后系统自动标记该计划数为已完成。
自动获取:用户信息从 token 获取,规格/精度/量程从任务自动获取。

参数必填说明
task_item_id计划数ID(从 my_task_items 获取),传入后系统自动标记完成并获取任务信息
task_id生产任务ID(不传时从 task_item_id 获取)
meter_number表计编号
dial_image表盘图片,支持 jpg/png/webp/bmp
extra_json额外数据 JSON 字符串
curl -X POST "https://sf6.xahrf.cn/api.php?action=upload_dial" \
  -H "Authorization: Bearer <access_token>" \
  -F "task_item_id=5" \
  -F "meter_number=M20260427001" \
  -F "dial_image=@dial.png"

返回字段说明:

字段类型说明
idint记录ID
meter_numberstring表计编号
image_urlstring图片访问地址
created_atdatetime上传时间
{
  "success": true,
  "message": "上传成功",
  "data": {
    "id": 10,
    "meter_number": "M20260427001",
    "image_url": "https://sf6.xahrf.cn/uploads/dial_images/20260506103000_abc123.jpg",
    "created_at": "2026-05-06 10:30:00"
  }
}
11. 获取最新软件版本

GET https://sf6.xahrf.cn/api.php?action=latest_version

用于产线软件检测更新,返回当前版本信息。

返回字段说明:

字段类型说明
idint版本记录ID
version_namestring版本名称(如 Ver 1.0.0)
version_codeint版本代码(用于版本比较,数值越大版本越高)
is_force_updateint是否强制更新(1=是,0=否)
download_urlstring安装包下载地址
release_notestring更新说明
is_currentint是否为当前版本(1=是)
created_atdatetime发布时间
{
  "success": true,
  "data": {
    "id": 1,
    "version_name": "Ver 1.0.0",
    "version_code": 100,
    "is_force_update": 0,
    "download_url": "https://sf6.xahrf.cn/uploads/software/dial_production_v1.0.0.zip",
    "release_note": "1. 新增表盘检测功能\n2. 优化数据上传速度\n3. 修复已知bug",
    "is_current": 1,
    "created_at": "2026-04-30 10:00:00"
  }
}
12. 获取表计量程参数

GET https://sf6.xahrf.cn/api.php?action=meter_ranges

返回表计类型、类型编码、表计名称、最小量程、最大量程和单位。

返回字段说明:

字段类型说明
idint量程参数ID
type_codestring类型编码
type_namestring表计类型名称
min_rangestring最小量程
max_rangestring最大量程
unitstring单位
{
  "success": true,
  "data": [{
    "id": 1,
    "type_code": "YLB",
    "type_name": "压力表",
    "min_range": "0",
    "max_range": "2.5",
    "unit": "MPa"
  }]
}