2923 lines
98 KiB
YAML
2923 lines
98 KiB
YAML
openapi: 3.0.3
|
||
info:
|
||
title: PartsInquiry API
|
||
version: 0.2.0
|
||
description: >-
|
||
所有接口定义集中于此文件。每个 path 在 summary/description 中标注实现状态。
|
||
2025-09-27:新增管理端公告、VIP 管理接口说明;管理员登录接口尚未与前端集成,保持「❌ Partially Implemented」。
|
||
servers:
|
||
- url: /
|
||
paths:
|
||
/api/user/me:
|
||
get:
|
||
summary: 用户端-我的资料(✅ Fully Implemented)
|
||
description: 返回当前登录用户的基础资料(name/phone/email/avatarUrl)。在使用默认用户调试模式时需携带 `X-User-Id`。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
shopId: { type: integer, format: int64 }
|
||
phone: { type: string, nullable: true }
|
||
email: { type: string, nullable: true }
|
||
name: { type: string }
|
||
avatarUrl: { type: string, nullable: true }
|
||
put:
|
||
summary: 用户端-更新资料(✅ Fully Implemented)
|
||
description: 支持修改 `name` 与 `avatarUrl`(头像为URL保存,后端校验域名、类型与大小)。默认用户模式必须附带 `X-User-Id`。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string, nullable: true }
|
||
avatarUrl: { type: string, nullable: true }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/user/me/password:
|
||
put:
|
||
summary: 用户端-修改密码(✅ Fully Implemented)
|
||
description: 若当前已设置密码则需要提供 `oldPassword` 验证;新密码至少6位。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
oldPassword: { type: string, nullable: true }
|
||
newPassword: { type: string }
|
||
required: [newPassword]
|
||
responses: { '200': { description: 成功 } }
|
||
/api/user/me/phone:
|
||
put:
|
||
summary: 用户端-保存手机号(✅ Fully Implemented)
|
||
description: 直接保存新的手机号,后端进行格式校验与唯一约束检查(不需要验证码)。当前在无 Token 的情况下需通过 `X-User-Id` 头完成身份传递。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
phone: { type: string }
|
||
required: [phone]
|
||
responses: { '200': { description: 成功 } }
|
||
/api/barcode/scan:
|
||
post:
|
||
summary: 条码识别-任意码制(❌ Partially Implemented)
|
||
description: 前端(小程序/安卓)尚未接入,后端代理接口已完成,将图片转发到 Python FastAPI 服务 `POST /api/barcode/scan` 识别条码。优先返回 EAN-13;若无则返回任意码制(如 CODE128/ITF/QRCODE 等)的第一个结果;同时返回 others 列表供前端兜底展示。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
file:
|
||
type: string
|
||
format: binary
|
||
required: [file]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
success: { type: boolean }
|
||
barcodeType: { type: string, nullable: true, description: '如 EAN13/CODE128/QRCODE 等' }
|
||
barcode: { type: string, nullable: true }
|
||
others:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
type: { type: string }
|
||
code: { type: string }
|
||
'400':
|
||
description: 识别失败或文件错误
|
||
/api/admin/auth/login:
|
||
post:
|
||
summary: 管理端-管理员登录(❌ Partially Implemented)
|
||
description: 使用用户名或手机号+密码登录,成功返回 Bearer Token;同时兼容旧方案 `X-Admin-Id` 头部。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
username: { type: string, nullable: true }
|
||
phone: { type: string, nullable: true }
|
||
password: { type: string }
|
||
oneOf:
|
||
- required: [username, password]
|
||
- required: [phone, password]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
token: { type: string }
|
||
expiresIn: { type: integer }
|
||
admin:
|
||
type: object
|
||
properties:
|
||
adminId: { type: integer, format: int64 }
|
||
username: { type: string }
|
||
phone: { type: string, nullable: true }
|
||
/api/admin/users:
|
||
get:
|
||
summary: 管理端-用户列表(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: query
|
||
name: shopId
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
phone: { type: string }
|
||
role: { type: string }
|
||
status: { type: integer, enum: [0,1] }
|
||
isOwner: { type: boolean }
|
||
shopId: { type: integer, format: int64 }
|
||
shopName: { type: string }
|
||
/api/admin/users/{id}:
|
||
put:
|
||
summary: 管理端-更新用户(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
phone: { type: string }
|
||
role: { type: string }
|
||
status: { type: integer, enum: [0,1] }
|
||
isOwner: { type: boolean }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/users/{id}/blacklist:
|
||
put:
|
||
summary: 管理端-拉黑用户(✅ Fully Implemented)
|
||
description: 将用户 `status` 置为 0,被拉黑用户登录将返回"你已被管理员拉黑"。
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/users/{id}/restore:
|
||
put:
|
||
summary: 管理端-解除拉黑(✅ Fully Implemented)
|
||
description: 将用户 `status` 置为 1,恢复正常登录。
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses: { '200': { description: 成功 } }
|
||
|
||
/api/admin/parts:
|
||
get:
|
||
summary: 管理端-用户配件列表(✅ Fully Implemented)
|
||
description: 返回商品列表;支持 shopId/kw 分页查询。
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: query
|
||
name: shopId
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
userId: { type: integer, format: int64 }
|
||
shopId: { type: integer, format: int64 }
|
||
shopName: { type: string }
|
||
name: { type: string }
|
||
brand: { type: string }
|
||
model: { type: string }
|
||
spec: { type: string }
|
||
images:
|
||
type: array
|
||
items: { type: string, description: '图片URL,可能为绝对或以 / 开头的相对路径' }
|
||
/api/admin/parts/{id}:
|
||
put:
|
||
summary: 管理端-更新配件(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
brand: { type: string, nullable: true }
|
||
model: { type: string, nullable: true }
|
||
spec: { type: string, nullable: true }
|
||
images:
|
||
oneOf:
|
||
- type: array
|
||
items: { type: string, description: '图片URL' }
|
||
- type: string
|
||
description: '逗号分隔的图片URL(兼容)'
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/parts/{id}/restore:
|
||
put:
|
||
summary: 管理端-配件恢复(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses: { '200': { description: 成功 } }
|
||
|
||
/api/consults:
|
||
post:
|
||
summary: 用户端-创建咨询(✅ Fully Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
topic: { type: string }
|
||
message: { type: string }
|
||
required: [message]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
get:
|
||
summary: 用户端-获取最近一次咨询(✅ Fully Implemented)
|
||
description: 返回当前用户最近一次咨询及最新回复(如有)。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
topic: { type: string }
|
||
message: { type: string }
|
||
status: { type: string, enum: [open, resolved, closed] }
|
||
createdAt: { type: string, format: date-time }
|
||
replied: { type: boolean }
|
||
latestReply: { type: string, nullable: true }
|
||
latestReplyAt: { type: string, format: date-time, nullable: true }
|
||
/api/consults/{id}:
|
||
get:
|
||
summary: 用户端-咨询详情(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
shopId: { type: integer, format: int64 }
|
||
userId: { type: integer, format: int64 }
|
||
topic: { type: string }
|
||
message: { type: string }
|
||
status: { type: string }
|
||
createdAt: { type: string, format: date-time }
|
||
replies:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
userId: { type: integer, format: int64 }
|
||
content: { type: string }
|
||
createdAt: { type: string, format: date-time }
|
||
/api/consults/{id}/ack:
|
||
put:
|
||
summary: 用户端-确认已读回复并恢复为"咨询"(✅ Fully Implemented)
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
updated: { type: integer }
|
||
|
||
/api/admin/consults:
|
||
get:
|
||
summary: 管理端-咨询列表(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: query
|
||
name: shopId
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: status
|
||
schema: { type: string, enum: [open, resolved, closed] }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
userId: { type: integer, format: int64 }
|
||
shopId: { type: integer, format: int64 }
|
||
shopName: { type: string }
|
||
topic: { type: string }
|
||
message: { type: string }
|
||
status: { type: string }
|
||
createdAt: { type: string, format: date-time }
|
||
/api/admin/consults/{id}/reply:
|
||
post:
|
||
summary: 管理端-回复咨询(✅ Fully Implemented,仅允许一次回复)
|
||
description: 当该咨询已存在回复时返回 409。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
content: { type: string }
|
||
required: [content]
|
||
responses:
|
||
'200': { description: 成功 }
|
||
'409': { description: 该咨询已被回复 }
|
||
/api/admin/consults/{id}/resolve:
|
||
put:
|
||
summary: 管理端-标记咨询已解决(✅ Fully Implemented)
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/consults/users/{userId}/history:
|
||
get:
|
||
summary: 管理端-查看用户历史咨询与回复(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: path
|
||
name: userId
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: shopId
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
topic: { type: string }
|
||
message: { type: string }
|
||
status: { type: string }
|
||
createdAt: { type: string, format: date-time }
|
||
replies:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
userId: { type: integer, format: int64 }
|
||
content: { type: string }
|
||
createdAt: { type: string, format: date-time }
|
||
|
||
/api/admin/notices:
|
||
get:
|
||
summary: 管理端-公告列表(✅ Fully Implemented)
|
||
description: 返回公告列表,支持状态/关键字过滤。公告数据已在管理端页面 `/notice/list` 使用。
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
- in: query
|
||
name: status
|
||
schema: { type: string, enum: [draft, published, offline] }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Notice'
|
||
post:
|
||
summary: 管理端-创建公告(✅ Fully Implemented)
|
||
description: 新增公告。后台限制:标题最长120字符,内容500字符。
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
title: { type: string }
|
||
content: { type: string }
|
||
tag: { type: string, nullable: true }
|
||
pinned: { type: boolean, nullable: true }
|
||
status: { type: string, enum: [draft, published, offline], nullable: true }
|
||
startsAt: { type: string, format: date-time, nullable: true }
|
||
endsAt: { type: string, format: date-time, nullable: true }
|
||
required: [title, content]
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/notices/{id}:
|
||
put:
|
||
summary: 管理端-更新公告(❌ Partially Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
title: { type: string, nullable: true }
|
||
content: { type: string, nullable: true }
|
||
tag: { type: string, nullable: true }
|
||
pinned: { type: boolean, nullable: true }
|
||
status: { type: string, enum: [draft, published, offline], nullable: true }
|
||
startsAt: { type: string, format: date-time, nullable: true }
|
||
endsAt: { type: string, format: date-time, nullable: true }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/notices/{id}/publish:
|
||
post:
|
||
summary: 管理端-发布公告(❌ Partially Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/notices/{id}/offline:
|
||
post:
|
||
summary: 管理端-下线公告(❌ Partially Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/finance/categories:
|
||
get:
|
||
summary: 财务分类(✅ Fully Implemented)
|
||
description: 返回其他收入/支出的分类。读取顺序:finance_categories 表 → system_parameters → app.finance.* 默认配置;前端已接入开单页分类chips。
|
||
parameters:
|
||
- in: header
|
||
name: X-Shop-Id
|
||
required: false
|
||
schema: { type: integer }
|
||
description: 店铺ID,缺省 1
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
incomeCategories:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
key: { type: string }
|
||
label: { type: string }
|
||
expenseCategories:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
key: { type: string }
|
||
label: { type: string }
|
||
/api/dashboard/overview:
|
||
get:
|
||
summary: 首页概览(✅ Fully Implemented)
|
||
description: 订单口径的今日销售额(approved)、近似本月毛利(按当前进价近似)与库存总量。支持 X-Shop-Id 或 X-User-Id(优先从用户解析店铺)。后端与前端均已接入。
|
||
parameters:
|
||
- in: header
|
||
name: X-Shop-Id
|
||
required: false
|
||
schema:
|
||
type: integer
|
||
description: 店铺ID,缺省为 1
|
||
- in: header
|
||
name: X-User-Id
|
||
required: false
|
||
schema:
|
||
type: integer
|
||
description: 用户ID;当未提供 X-Shop-Id 时将用其所属店铺进行统计
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/DashboardOverview'
|
||
/api/notices:
|
||
get:
|
||
summary: 公告列表(✅ Fully Implemented)
|
||
description: 返回全局公告列表(与租户无关)。后端与前端均已接入。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
/api/vip/status:
|
||
get:
|
||
summary: 用户端-VIP状态查询(❌ Partially Implemented)
|
||
description: 返回当前用户的 VIP 有效状态与到期时间。判定规则:status=1 && is_vip=1 && (expireAt 为空或 >= now)。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
isVip: { type: boolean }
|
||
status: { type: integer, enum: [0,1] }
|
||
expireAt: { type: string, format: date-time, nullable: true }
|
||
price: { type: number, description: '当前平台统一会员单月价格,来自 vip_price' }
|
||
nonVipRetentionDays: { type: integer, description: '非VIP数据保留天数(默认60)' }
|
||
|
||
/api/vip/pay:
|
||
post:
|
||
summary: 用户端-一键开通VIP(❌ Partially Implemented)
|
||
description: 临时方案:点击即视为支付成功。行为:若非VIP或已过期则开通;若在有效期内则从当前时间起顺延 durationDays。写入/更新 vip_users。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
/api/normal-admin/apply:
|
||
post:
|
||
summary: 普通管理员-提交申请(❌ Partially Implemented)
|
||
description: 需已登录用户(X-User-Id),默认要求 VIP 有效;根据配置可自动通过。
|
||
responses:
|
||
'200': { description: 成功 }
|
||
|
||
/api/admin/normal-admin/applications:
|
||
get:
|
||
summary: 平台-普通管理员申请列表(❌ Partially Implemented)
|
||
description: 返回最后状态为 apply 且尚未被通过/驳回的申请。
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list: { type: array, items: { type: object } }
|
||
total: { type: integer }
|
||
|
||
/api/admin/normal-admin/applications/{userId}/approve:
|
||
post:
|
||
summary: 平台-审批通过普通管理员(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: userId
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200': { description: 成功 }
|
||
|
||
/api/admin/normal-admin/applications/{userId}/reject:
|
||
post:
|
||
summary: 平台-驳回普通管理员申请(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: userId
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200': { description: 成功 }
|
||
|
||
/api/admin/normal-admin/users/{userId}/revoke:
|
||
post:
|
||
summary: 平台-撤销普通管理员权限(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: userId
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200': { description: 成功 }
|
||
|
||
/api/normal-admin/parts/submissions:
|
||
get:
|
||
summary: 普通管理端-配件提交列表(❌ Partially Implemented)
|
||
description: 与平台管理端一致,但范围强制限定为当前用户所属店铺。
|
||
parameters:
|
||
- in: query
|
||
name: status
|
||
schema: { type: string, enum: [pending, approved, rejected] }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200': { description: 成功 }
|
||
|
||
/api/normal-admin/parts/submissions/{id}:
|
||
get:
|
||
summary: 普通管理端-提交详情(❌ Partially Implemented)
|
||
parameters: [ { in: path, name: id, required: true, schema: { type: integer, format: int64 } } ]
|
||
responses: { '200': { description: 成功 } }
|
||
put:
|
||
summary: 普通管理端-编辑提交内容(❌ Partially Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
responses: { '200': { description: 成功 } }
|
||
|
||
/api/normal-admin/parts/submissions/{id}/approve:
|
||
post:
|
||
summary: 普通管理端-审核通过(❌ Partially Implemented)
|
||
responses: { '200': { description: 成功 } }
|
||
|
||
/api/normal-admin/parts/submissions/{id}/reject:
|
||
post:
|
||
summary: 普通管理端-审核驳回(❌ Partially Implemented)
|
||
responses: { '200': { description: 成功 } }
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
isVip: { type: boolean }
|
||
status: { type: integer, enum: [0,1] }
|
||
expireAt: { type: string, format: date-time }
|
||
|
||
/api/vip/recharges:
|
||
get:
|
||
summary: 用户端-VIP支付记录(✅ Fully Implemented)
|
||
description: 返回当前用户的 VIP 充值记录,按时间倒序;读取 `X-User-Id`。
|
||
parameters:
|
||
- in: header
|
||
name: X-User-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
price: { type: number }
|
||
durationDays: { type: integer }
|
||
expireFrom: { type: string, format: date-time, nullable: true }
|
||
expireTo: { type: string, format: date-time }
|
||
channel: { type: string }
|
||
createdAt: { type: string, format: date-time }
|
||
|
||
/api/admin/vip/price:
|
||
get:
|
||
summary: 管理端-读取VIP价格(✅ Fully Implemented)
|
||
description: 平台统一价,读取 `vip_price` 表(仅一条记录)。管理端页面 `/vip/system` 使用。
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
price: { type: number }
|
||
put:
|
||
summary: 管理端-设置VIP价格(❌ Partially Implemented)
|
||
description: 覆盖写入 vip_price.price。
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
price: { type: number }
|
||
required: [price]
|
||
responses:
|
||
'200': { description: 成功 }
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Notice'
|
||
/api/metrics/overview:
|
||
get:
|
||
summary: 概览统计(❌ Partially Implemented)
|
||
description: 返回今日/本月销售额、本月利润与库存商品数量。前端已接入,后端待实现。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/MetricsOverview'
|
||
/api/accounts:
|
||
get:
|
||
summary: 账户列表(❌ Partially Implemented)
|
||
description: 返回启用账户列表;支持数组或 {list:[]} 两种返回格式以兼容前端。
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: status
|
||
schema: { type: integer, enum: [0,1] }
|
||
description: 仅后台使用;前端默认不传即等同 status=1
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 50 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
oneOf:
|
||
- type: array
|
||
items:
|
||
$ref: '#/components/schemas/Account'
|
||
- type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Account'
|
||
post:
|
||
summary: 新增账户(❌ Partially Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateAccountRequest'
|
||
responses:
|
||
'200': { description: 成功 }
|
||
/api/accounts/{id}:
|
||
put:
|
||
summary: 更新账户(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateAccountRequest'
|
||
responses:
|
||
'200': { description: 成功 }
|
||
/api/accounts/{id}/ledger:
|
||
get:
|
||
summary: 账户流水(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: startDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: endDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
opening: { type: number }
|
||
income: { type: number }
|
||
expense: { type: number }
|
||
ending: { type: number }
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
txTime: { type: string, format: date-time }
|
||
direction: { type: string, enum: [in, out] }
|
||
amount: { type: number }
|
||
src: { type: string, description: 'sale|purchase|other' }
|
||
category: { type: string, nullable: true }
|
||
remark: { type: string, nullable: true }
|
||
/api/suppliers:
|
||
get:
|
||
summary: 供应商搜索(✅ Fully Implemented)
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema:
|
||
type: string
|
||
- in: query
|
||
name: debtOnly
|
||
schema:
|
||
type: boolean
|
||
- in: query
|
||
name: page
|
||
schema:
|
||
type: integer
|
||
default: 1
|
||
- in: query
|
||
name: size
|
||
schema:
|
||
type: integer
|
||
default: 50
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
oneOf:
|
||
- type: array
|
||
items:
|
||
$ref: '#/components/schemas/Supplier'
|
||
- type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Supplier'
|
||
post:
|
||
summary: 新建供应商(✅ Fully Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateSupplierRequest'
|
||
responses:
|
||
'200': { description: 成功 }
|
||
/api/suppliers/{id}:
|
||
get:
|
||
summary: 供应商详情(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
contactName: { type: string, nullable: true }
|
||
mobile: { type: string, nullable: true }
|
||
phone: { type: string, nullable: true }
|
||
address: { type: string, nullable: true }
|
||
apOpening: { type: number }
|
||
apPayable: { type: number }
|
||
remark: { type: string, nullable: true }
|
||
put:
|
||
summary: 更新供应商(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateSupplierRequest'
|
||
responses:
|
||
'200': { description: 成功 }
|
||
/api/other-transactions:
|
||
post:
|
||
summary: 新建其他收入/支出(✅ Fully Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateOtherTransactionRequest'
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
/api/products:
|
||
get:
|
||
summary: 商品搜索(✅ Fully Implemented)
|
||
description: 支持 kw/page/size/categoryId;返回 {list:[]} 以兼容前端。
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema:
|
||
type: string
|
||
- in: query
|
||
name: page
|
||
schema:
|
||
type: integer
|
||
default: 1
|
||
- in: query
|
||
name: size
|
||
schema:
|
||
type: integer
|
||
default: 50
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
oneOf:
|
||
- type: array
|
||
items:
|
||
$ref: '#/components/schemas/Product'
|
||
- type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Product'
|
||
post:
|
||
summary: 新建商品(✅ Fully Implemented)
|
||
description: 保存商品、价格、库存与图片(当前图片统一占位图 URL)。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateProductRequest'
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
/api/products/{id}:
|
||
get:
|
||
summary: 商品详情(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ProductDetail'
|
||
put:
|
||
summary: 更新商品(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateProductRequest'
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
/api/product-categories:
|
||
get:
|
||
summary: 类别列表(✅ Fully Implemented)
|
||
description: 仅返回全局字典(shop_id=0)的类别列表。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
oneOf:
|
||
- type: array
|
||
items: { $ref: '#/components/schemas/Category' }
|
||
- type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/Category' }
|
||
post:
|
||
summary: 新增类别(❌ Partially Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
/api/product-categories/{id}:
|
||
put:
|
||
summary: 更新类别(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
delete:
|
||
summary: 删除类别(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/product-units:
|
||
get:
|
||
summary: 单位列表(✅ Fully Implemented)
|
||
description: 仅返回全局字典(shop_id=0)的单位列表。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
oneOf:
|
||
- type: array
|
||
items: { $ref: '#/components/schemas/Unit' }
|
||
- type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/Unit' }
|
||
post:
|
||
summary: 新增单位(❌ Partially Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
/api/product-units/{id}:
|
||
put:
|
||
summary: 更新单位(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
delete:
|
||
summary: 删除单位(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/product-settings:
|
||
get:
|
||
summary: 货品设置读取(❌ Partially Implemented)
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ProductSettings'
|
||
put:
|
||
summary: 货品设置保存(❌ Partially Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ProductSettings'
|
||
responses: { '200': { description: 成功 } }
|
||
/api/customers:
|
||
get:
|
||
summary: 客户搜索(✅ Fully Implemented)
|
||
description: 支持 kw/page/size/debtOnly;返回 {list:[]},含动态计算的 receivable 字段。
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema:
|
||
type: string
|
||
- in: query
|
||
name: debtOnly
|
||
schema:
|
||
type: boolean
|
||
- in: query
|
||
name: page
|
||
schema:
|
||
type: integer
|
||
default: 1
|
||
- in: query
|
||
name: size
|
||
schema:
|
||
type: integer
|
||
default: 50
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
oneOf:
|
||
- type: array
|
||
items:
|
||
$ref: '#/components/schemas/Customer'
|
||
- type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Customer'
|
||
post:
|
||
summary: 新建客户(✅ Fully Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateCustomerRequest'
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
/api/orders:
|
||
post:
|
||
summary: 新建单据(✅ Fully Implemented)
|
||
description: 销售/进货出入库与退货:保存即 approved;后端重算金额并联动库存。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateOrderRequest'
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
orderNo:
|
||
type: string
|
||
/api/orders:
|
||
get:
|
||
summary: 单据列表查询(✅ Fully Implemented)
|
||
description: 支持按时间范围与关键字筛选;参数 biz=sale|purchase,type=out|in|return;返回 {list:[]}。后端已返回驼峰字段与名称(sale: customerName;purchase: supplierName)。
|
||
parameters:
|
||
- in: query
|
||
name: biz
|
||
schema: { type: string }
|
||
- in: query
|
||
name: type
|
||
schema: { type: string }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
- in: query
|
||
name: startDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: endDate
|
||
schema: { type: string, format: date }
|
||
/api/payments/{biz}:
|
||
post:
|
||
summary: 创建收款/付款(✅ Fully Implemented)
|
||
description: biz=sale|purchase;根据 payments 写入多条记录,可选挂单并累加订单已付金额。
|
||
parameters:
|
||
- in: path
|
||
name: biz
|
||
required: true
|
||
schema: { type: string }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/PaymentItem'
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
paymentIds:
|
||
type: array
|
||
items: { type: integer, format: int64 }
|
||
description: 收/付款创建。注意:根据约束,sale/purchase 收/付款必须绑定订单(orderId 不可为空)。
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
- in: query
|
||
name: startDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: endDate
|
||
schema: { type: string, format: date }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
orderNo: { type: string }
|
||
orderTime: { type: string, format: date-time }
|
||
amount: { type: number }
|
||
customerName: { type: string }
|
||
|
||
/api/purchase-orders:
|
||
get:
|
||
summary: 进货单列表查询(✅ Fully Implemented)
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
- in: query
|
||
name: startDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: endDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: status
|
||
schema:
|
||
type: string
|
||
enum: [draft, approved, void, returned]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
orderNo: { type: string }
|
||
orderTime: { type: string, format: date-time }
|
||
amount: { type: number }
|
||
supplierName: { type: string }
|
||
|
||
/api/payments:
|
||
get:
|
||
summary: 收付款流水列表(✅ Fully Implemented)
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
- in: query
|
||
name: startDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: endDate
|
||
schema: { type: string, format: date }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
totalAmount: { type: number }
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
bizType: { type: string }
|
||
direction: { type: string }
|
||
orderTime: { type: string, format: date-time, description: '支付时间,原 payTime' }
|
||
amount: { type: number }
|
||
accountName: { type: string }
|
||
category: { type: string, nullable: true }
|
||
|
||
/api/inventories/logs:
|
||
get:
|
||
summary: 库存/盘点流水列表(✅ Fully Implemented)
|
||
parameters:
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
- in: query
|
||
name: startDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: endDate
|
||
schema: { type: string, format: date }
|
||
- in: query
|
||
name: productId
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: reason
|
||
schema: { type: string }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
totalAmount: { type: number }
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
txTime: { type: string, format: date-time }
|
||
amount: { type: number, description: '金额变化(若无则0)' }
|
||
remark: { type: string }
|
||
productId: { type: integer, format: int64 }
|
||
qtyDelta: { type: number }
|
||
amountDelta: { type: number, nullable: true }
|
||
|
||
/api/orders/{id}:
|
||
get:
|
||
summary: 销售单详情(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
orderNo: { type: string }
|
||
orderTime: { type: string, format: date-time }
|
||
status: { type: string }
|
||
amount: { type: number }
|
||
paidAmount: { type: number }
|
||
customerId: { type: integer, format: int64, nullable: true }
|
||
customerName: { type: string, nullable: true }
|
||
remark: { type: string, nullable: true }
|
||
items:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
productId: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
spec: { type: string }
|
||
quantity: { type: number }
|
||
unitPrice: { type: number }
|
||
discountRate: { type: number }
|
||
amount: { type: number }
|
||
payments:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
amount: { type: number }
|
||
payTime: { type: string, format: date-time }
|
||
accountId: { type: integer, format: int64 }
|
||
accountName: { type: string }
|
||
direction: { type: string }
|
||
|
||
/api/purchase-orders/{id}:
|
||
get:
|
||
summary: 进货单详情(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
orderNo: { type: string }
|
||
orderTime: { type: string, format: date-time }
|
||
status: { type: string }
|
||
amount: { type: number }
|
||
paidAmount: { type: number }
|
||
supplierId: { type: integer, format: int64, nullable: true }
|
||
supplierName: { type: string, nullable: true }
|
||
remark: { type: string, nullable: true }
|
||
items:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
productId: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
spec: { type: string }
|
||
quantity: { type: number }
|
||
unitPrice: { type: number }
|
||
amount: { type: number }
|
||
payments:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
amount: { type: number }
|
||
payTime: { type: string, format: date-time }
|
||
accountId: { type: integer, format: int64 }
|
||
accountName: { type: string }
|
||
direction: { type: string }
|
||
/api/attachments:
|
||
post:
|
||
summary: 上传附件(✅ Fully Implemented)
|
||
description: 直传本地存储。后端校验大小与类型,计算内容哈希并存储于配置目录。返回可直接访问的 `url`(`/api/attachments/content/{sha256}`)。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
file:
|
||
type: string
|
||
format: binary
|
||
ownerType:
|
||
type: string
|
||
ownerId:
|
||
type: string
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
url:
|
||
type: string
|
||
contentType:
|
||
type: string
|
||
contentLength:
|
||
type: integer
|
||
format: int64
|
||
/api/attachments/validate-url:
|
||
post:
|
||
summary: 校验图片URL(✅ Fully Implemented)
|
||
description: 提交外部图片URL,后端进行白名单、SSR防护、类型与大小校验,返回标准化后的可用URL和元信息。支持 `application/json` 与 `application/x-www-form-urlencoded`。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
url: { type: string }
|
||
required: [url]
|
||
application/x-www-form-urlencoded:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
url: { type: string }
|
||
required: [url]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
url: { type: string }
|
||
contentType: { type: string }
|
||
contentLength: { type: integer, format: int64, nullable: true }
|
||
/api/attachments/placeholder:
|
||
get:
|
||
summary: 附件占位图读取(✅ Fully Implemented)
|
||
/api/attachments/content/{sha256}:
|
||
get:
|
||
summary: 读取附件内容(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: sha256
|
||
required: true
|
||
schema: { type: string }
|
||
responses:
|
||
'200':
|
||
description: 图片二进制
|
||
content:
|
||
image/*:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
description: 返回后端配置的本地占位图内容,路径由 `attachments.placeholder.image-path` 指定。
|
||
responses:
|
||
'200':
|
||
description: 图片二进制
|
||
content:
|
||
image/png:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
/api/auth/register:
|
||
post:
|
||
summary: 手机号注册创建店铺与店主(✅ Fully Implemented)
|
||
description: |
|
||
直接提交手机号进行注册:若手机号尚不存在,则创建店铺与店主用户(owner,`users.is_owner=1`),并初始化默认账户(现金/银行存款/微信)。
|
||
若手机号已存在,则直接签发 JWT 并返回用户/店铺信息。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
phone: { type: string }
|
||
name: { type: string, nullable: true }
|
||
password: { type: string, nullable: true, description: '预留字段,当前不校验' }
|
||
required: [phone]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
token: { type: string }
|
||
expiresIn: { type: integer }
|
||
user:
|
||
type: object
|
||
properties:
|
||
userId: { type: integer }
|
||
shopId: { type: integer }
|
||
phone: { type: string }
|
||
/api/auth/email/send:
|
||
post:
|
||
summary: 邮箱验证码发送(✅ Fully Implemented)
|
||
description: 后端已实现 SMTP 发信并写入 email_codes。scene 支持 login/register/reset。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
email: { type: string }
|
||
scene: { type: string, nullable: true, default: login }
|
||
required: [email]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok: { type: boolean }
|
||
cooldownSec: { type: integer }
|
||
/api/auth/sms/login:
|
||
post:
|
||
summary: 短信验证码登录/注册(❌ Partially Implemented)
|
||
description: 校验通过后,若手机号不存在则自动创建店铺与店主用户(owner),并签发 JWT(包含 phone 声明)。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
phone: { type: string }
|
||
code: { type: string }
|
||
name: { type: string, nullable: true, description: '展示名:若提供则保存到 users.name;否则按手机号脱敏生成' }
|
||
required: [phone, code]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
token: { type: string }
|
||
expiresIn: { type: integer }
|
||
user:
|
||
type: object
|
||
properties:
|
||
userId: { type: integer }
|
||
shopId: { type: integer }
|
||
phone: { type: string }
|
||
/api/auth/email/login:
|
||
post:
|
||
summary: 邮箱验证码登录(✅ Fully Implemented)
|
||
/api/auth/email/register:
|
||
post:
|
||
summary: 邮箱注册(设置密码,需验证码)(✅ Fully Implemented)
|
||
description: 使用邮箱+验证码注册并设置密码;若邮箱已存在则更新密码。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
email: { type: string }
|
||
code: { type: string }
|
||
name: { type: string, nullable: true }
|
||
password: { type: string }
|
||
required: [email, code, password]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
token: { type: string }
|
||
expiresIn: { type: integer }
|
||
user:
|
||
type: object
|
||
properties:
|
||
userId: { type: integer }
|
||
shopId: { type: integer }
|
||
email: { type: string }
|
||
description: 校验通过后,若邮箱不存在则自动创建店铺与店主用户(owner),保存密码并签发 JWT。
|
||
/api/auth/email/reset-password:
|
||
post:
|
||
summary: 邮箱重置密码(✅ Fully Implemented)
|
||
description: 使用邮箱验证码更新已存在用户的密码;验证码场景为 reset。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
email: { type: string }
|
||
code: { type: string }
|
||
password: { type: string }
|
||
required: [email, code, password]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok: { type: boolean }
|
||
/api/admin/vips:
|
||
get:
|
||
summary: 管理端-会员列表(✅ Fully Implemented)
|
||
description: 返回店铺会员(或待启用)列表,基于 `vip_users` 表。管理端页面 `/vip/list` 已接入。
|
||
parameters:
|
||
- in: query
|
||
name: phone
|
||
schema: { type: string }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/VipUser'
|
||
total: { type: integer }
|
||
post:
|
||
summary: 管理端-新增/申请会员(❌ Partially Implemented)
|
||
description: 向 `vip_users` 插入一条记录,支持作为"申请"进入待启用状态。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateVipUserRequest'
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
/api/admin/vips/{id}:
|
||
put:
|
||
summary: 管理端-更新会员(❌ Partially Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UpdateVipUserRequest'
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
/api/admin/vips/{id}/approve:
|
||
post:
|
||
summary: [已移除]
|
||
description: 审核流程已取消;请改用 /api/vip/pay 一键开通与 /api/admin/vip/system 接口。
|
||
responses:
|
||
'410': { description: Gone }
|
||
/api/admin/vips/{id}/reject:
|
||
post:
|
||
summary: [已移除]
|
||
description: 审核流程已取消;请改用 /api/vip/pay 一键开通与 /api/admin/vip/system 接口。
|
||
responses:
|
||
'410': { description: Gone }
|
||
/api/admin/dicts/units:
|
||
post:
|
||
summary: 管理端-新增主单位(✅ Fully Implemented)
|
||
description: 仅平台管理员可用;写入 `shop_id=0` 全局字典。
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
/api/admin/dicts/units/{id}:
|
||
put:
|
||
summary: 管理端-更新主单位(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
responses: { '200': { description: 成功 } }
|
||
delete:
|
||
summary: 管理端-删除主单位(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/dicts/categories:
|
||
post:
|
||
summary: 管理端-新增主类别(✅ Fully Implemented)
|
||
description: 仅平台管理员可用;写入 `shop_id=0` 全局字典。
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
/api/admin/dicts/categories/{id}:
|
||
put:
|
||
summary: 管理端-更新主类别(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
responses: { '200': { description: 成功 } }
|
||
delete:
|
||
summary: 管理端-删除主类别(✅ Fully Implemented)
|
||
parameters:
|
||
- in: header
|
||
name: X-Admin-Id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
description: 管理员ID(来自 admins 表)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/report/sales:
|
||
get:
|
||
summary: 销售报表(✅ Fully Implemented)
|
||
description: 按客户或按货品聚合销售额与成本,自动计算利润和利润率。后端已对接,前端待接入。
|
||
parameters:
|
||
- in: header
|
||
name: X-Shop-Id
|
||
required: false
|
||
schema: { type: integer, format: int64 }
|
||
description: 指定店铺ID,缺省使用当前默认店铺
|
||
- in: query
|
||
name: dimension
|
||
required: false
|
||
schema:
|
||
type: string
|
||
enum: [customer, product]
|
||
description: 聚合维度,默认为 customer
|
||
- in: query
|
||
name: startDate
|
||
required: false
|
||
schema: { type: string, format: date }
|
||
description: 起始日期(含),格式 yyyy-MM-dd;缺省不限制
|
||
- in: query
|
||
name: endDate
|
||
required: false
|
||
schema: { type: string, format: date }
|
||
description: 结束日期(含),格式 yyyy-MM-dd;缺省不限制
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/SalesReportResponse'
|
||
|
||
/api/products/submissions:
|
||
post:
|
||
summary: 用户端-提交配件(✅ Fully Implemented)
|
||
description: 用户提交配件资料进入待审核列表;型号全局唯一(需标准化为大写并去除首尾空格)。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
model: { type: string }
|
||
name: { type: string, nullable: true }
|
||
brand: { type: string, nullable: true }
|
||
spec: { type: string, nullable: true }
|
||
origin: { type: string, nullable: true }
|
||
barcode: { type: string, nullable: true }
|
||
unitId: { type: integer, format: int64, nullable: true }
|
||
categoryId: { type: integer, format: int64, nullable: true }
|
||
parameters: { type: object, additionalProperties: true, nullable: true }
|
||
images:
|
||
type: array
|
||
items: { type: string }
|
||
remark: { type: string, nullable: true }
|
||
safeMin: { type: number, nullable: true }
|
||
safeMax: { type: number, nullable: true }
|
||
required: [model]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
status: { type: string }
|
||
get:
|
||
summary: 用户端-提交记录列表(✅ Fully Implemented)
|
||
parameters:
|
||
- in: query
|
||
name: status
|
||
schema: { type: string, enum: [pending, approved, rejected] }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
name: { type: string, nullable: true }
|
||
model: { type: string }
|
||
brand: { type: string, nullable: true }
|
||
status: { type: string }
|
||
createdAt: { type: string, format: date-time }
|
||
reviewedAt: { type: string, format: date-time, nullable: true }
|
||
total: { type: integer }
|
||
page: { type: integer }
|
||
size: { type: integer }
|
||
/api/products/submissions/{id}:
|
||
get:
|
||
summary: 用户端-提交详情(✅ Fully Implemented)
|
||
description: 仅允许查询当前用户的提交记录。
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
model: { type: string }
|
||
name: { type: string, nullable: true }
|
||
brand: { type: string, nullable: true }
|
||
spec: { type: string, nullable: true }
|
||
origin: { type: string, nullable: true }
|
||
barcode: { type: string, nullable: true }
|
||
unitId: { type: integer, format: int64, nullable: true }
|
||
categoryId: { type: integer, format: int64, nullable: true }
|
||
parameters: { type: object, additionalProperties: true, nullable: true }
|
||
images:
|
||
type: array
|
||
items: { type: string }
|
||
remark: { type: string, nullable: true }
|
||
safeMin: { type: number, nullable: true }
|
||
safeMax: { type: number, nullable: true }
|
||
status: { type: string }
|
||
reviewerId: { type: integer, format: int64, nullable: true }
|
||
reviewRemark: { type: string, nullable: true }
|
||
reviewedAt: { type: string, format: date-time, nullable: true }
|
||
createdAt: { type: string, format: date-time }
|
||
/api/admin/parts/submissions:
|
||
get:
|
||
summary: 管理端-配件提交列表(✅ Fully Implemented)
|
||
description: 管理员按状态/关键字/时间筛选用户提交记录。
|
||
parameters:
|
||
- in: query
|
||
name: status
|
||
schema: { type: string, enum: [pending, approved, rejected] }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: shopId
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: reviewerId
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: startAt
|
||
schema: { type: string, format: date-time }
|
||
- in: query
|
||
name: endAt
|
||
schema: { type: string, format: date-time }
|
||
- in: query
|
||
name: page
|
||
schema: { type: integer, default: 1 }
|
||
- in: query
|
||
name: size
|
||
schema: { type: integer, default: 20 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
list:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
model: { type: string }
|
||
name: { type: string, nullable: true }
|
||
brand: { type: string, nullable: true }
|
||
status: { type: string }
|
||
shopId: { type: integer, format: int64 }
|
||
createdAt: { type: string, format: date-time }
|
||
reviewedAt: { type: string, format: date-time, nullable: true }
|
||
total: { type: integer }
|
||
page: { type: integer }
|
||
size: { type: integer }
|
||
/api/admin/parts/submissions/{id}:
|
||
get:
|
||
summary: 管理端-提交详情(✅ Fully Implemented)
|
||
parameters:
|
||
- in: path
|
||
name: id
|
||
required: true
|
||
schema: { type: integer, format: int64 }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
put:
|
||
summary: 管理端-编辑提交内容(✅ Fully Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name: { type: string, nullable: true }
|
||
brand: { type: string, nullable: true }
|
||
spec: { type: string, nullable: true }
|
||
unitId: { type: integer, format: int64, nullable: true }
|
||
categoryId: { type: integer, format: int64, nullable: true }
|
||
parameters: { type: object, additionalProperties: true, nullable: true }
|
||
images:
|
||
type: array
|
||
items: { type: string }
|
||
remark: { type: string, nullable: true }
|
||
barcode: { type: string, nullable: true }
|
||
responses:
|
||
'200': { description: 成功 }
|
||
/api/admin/parts/submissions/{id}/approve:
|
||
post:
|
||
summary: 管理端-审核通过(✅ Fully Implemented)
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
remark: { type: string, nullable: true }
|
||
assignGlobalSkuId: { type: integer, format: int64, nullable: true }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
ok: { type: boolean }
|
||
productId: { type: integer, format: int64 }
|
||
globalSkuId: { type: integer, format: int64, nullable: true }
|
||
/api/admin/parts/submissions/{id}/reject:
|
||
post:
|
||
summary: 管理端-审核驳回(✅ Fully Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
remark: { type: string }
|
||
required: [remark]
|
||
responses:
|
||
'200': { description: 成功 }
|
||
/api/admin/parts/submissions/export:
|
||
get:
|
||
summary: 管理端-提交记录导出(✅ Fully Implemented)
|
||
description: 按当前筛选条件导出 Excel;限制 2000 条以内的同步导出。
|
||
parameters:
|
||
- in: query
|
||
name: status
|
||
schema: { type: string, enum: [pending, approved, rejected] }
|
||
- in: query
|
||
name: kw
|
||
schema: { type: string }
|
||
- in: query
|
||
name: shopId
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: reviewerId
|
||
schema: { type: integer, format: int64 }
|
||
- in: query
|
||
name: startAt
|
||
schema: { type: string, format: date-time }
|
||
- in: query
|
||
name: endAt
|
||
schema: { type: string, format: date-time }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
|
||
/api/admin/part-templates:
|
||
get:
|
||
summary: 管理端-模板列表(❌ Partially Implemented)
|
||
responses: { '200': { description: 成功 } }
|
||
post:
|
||
summary: 管理端-创建模板(❌ Partially Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
categoryId: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
modelRule: { type: string, nullable: true }
|
||
status: { type: integer, enum: [0,1], default: 1 }
|
||
params:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
fieldKey: { type: string }
|
||
fieldLabel: { type: string }
|
||
type: { type: string, enum: [string, number, boolean, enum, date] }
|
||
required: { type: boolean }
|
||
unit: { type: string, nullable: true }
|
||
enumOptions: { type: array, items: { type: string }, nullable: true }
|
||
searchable: { type: boolean }
|
||
dedupeParticipate: { type: boolean }
|
||
sortOrder: { type: integer }
|
||
responses: { '200': { description: 成功 } }
|
||
/api/admin/part-templates/{id}:
|
||
get:
|
||
summary: 管理端-模板详情(❌ Partially Implemented)
|
||
parameters: [ { in: path, name: id, required: true, schema: { type: integer, format: int64 } } ]
|
||
responses: { '200': { description: 成功 } }
|
||
put:
|
||
summary: 管理端-更新模板(❌ Partially Implemented)
|
||
parameters: [ { in: path, name: id, required: true, schema: { type: integer, format: int64 } } ]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
categoryId: { type: integer, format: int64, nullable: true }
|
||
name: { type: string, nullable: true }
|
||
modelRule: { type: string, nullable: true }
|
||
status: { type: integer, enum: [0,1], nullable: true }
|
||
deleteAllRelatedProductsAndSubmissions: { type: boolean, default: true }
|
||
params:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
fieldKey: { type: string }
|
||
fieldLabel: { type: string }
|
||
type: { type: string, enum: [string, number, boolean, enum, date] }
|
||
required: { type: boolean }
|
||
unit: { type: string, nullable: true }
|
||
enumOptions: { type: array, items: { type: string }, nullable: true }
|
||
searchable: { type: boolean }
|
||
dedupeParticipate: { type: boolean }
|
||
sortOrder: { type: integer }
|
||
responses: { '200': { description: 成功 } }
|
||
|
||
/api/products/submissions/check-model:
|
||
post:
|
||
summary: 型号查重(❌ Partially Implemented)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
templateId: { type: integer, format: int64, nullable: true }
|
||
name: { type: string, nullable: true }
|
||
model: { type: string }
|
||
required: [model]
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
available: { type: boolean }
|
||
model: { type: string }
|
||
similarAcrossTemplates: { type: integer, description: '跨模板同名同型号的命中数量(提示用)' }
|
||
|
||
components:
|
||
schemas:
|
||
SalesReportItem:
|
||
type: object
|
||
properties:
|
||
key: { type: integer, format: int64, nullable: true, description: 聚合键(客户ID或商品ID),为0/NULL表示未指定 }
|
||
name: { type: string, description: 客户或货品名称 }
|
||
spec: { type: string, nullable: true, description: 货品规格,仅在按货品维度时返回 }
|
||
salesAmount: { type: number, description: 销售额(退货为负值) }
|
||
costAmount: { type: number, description: 成本额(退货为负值) }
|
||
profit: { type: number, description: 利润 = 销售额 - 成本额 }
|
||
profitRate: { type: number, description: 利润率(%),单位:百分比,保留两位小数 }
|
||
SalesReportSummary:
|
||
type: object
|
||
properties:
|
||
salesAmount: { type: number, description: 汇总销售额,已扣除退货 }
|
||
costAmount: { type: number, description: 汇总成本额,退货为负值 }
|
||
profit: { type: number, description: 汇总利润 = 销售额 - 成本额 }
|
||
profitRate: { type: number, description: 汇总利润率(%),保留两位小数 }
|
||
itemCount: { type: integer, description: 聚合项数量 }
|
||
SalesReportResponse:
|
||
type: object
|
||
properties:
|
||
dimension: { type: string, enum: [customer, product] }
|
||
startDate: { type: string, nullable: true }
|
||
endDate: { type: string, nullable: true }
|
||
summary: { $ref: '#/components/schemas/SalesReportSummary' }
|
||
items:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/SalesReportItem' }
|
||
VipUser:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
userId: { type: integer, format: int64 }
|
||
isVip: { type: integer, enum: [0,1] }
|
||
status: { type: integer, enum: [0,1] }
|
||
expireAt: { type: string, format: date-time, nullable: true }
|
||
remark: { type: string, nullable: true }
|
||
reviewerId: { type: integer, format: int64, nullable: true }
|
||
reviewedAt: { type: string, format: date-time, nullable: true }
|
||
CreateVipUserRequest:
|
||
type: object
|
||
properties:
|
||
userId: { type: integer, format: int64 }
|
||
isVip: { type: integer, enum: [0,1], default: 1 }
|
||
expireAt: { type: string, format: date-time, nullable: true }
|
||
remark: { type: string, nullable: true }
|
||
UpdateVipUserRequest:
|
||
type: object
|
||
properties:
|
||
isVip: { type: integer, enum: [0,1] }
|
||
status: { type: integer, enum: [0,1] }
|
||
expireAt: { type: string, format: date-time, nullable: true }
|
||
remark: { type: string, nullable: true }
|
||
DashboardOverview:
|
||
type: object
|
||
properties:
|
||
todaySalesAmount:
|
||
type: number
|
||
example: 1250.00
|
||
monthSalesAmount:
|
||
type: number
|
||
example: 26500.00
|
||
monthGrossProfit:
|
||
type: number
|
||
example: 3560.25
|
||
stockTotalQuantity:
|
||
type: number
|
||
example: 1300
|
||
Notice:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
title:
|
||
type: string
|
||
content:
|
||
type: string
|
||
tag:
|
||
type: string
|
||
nullable: true
|
||
pinned:
|
||
type: boolean
|
||
startsAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
endsAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
status:
|
||
type: string
|
||
enum: [draft, published, offline]
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
MetricsOverview:
|
||
type: object
|
||
properties:
|
||
todaySales:
|
||
type: string
|
||
example: '1234.56'
|
||
monthSales:
|
||
type: string
|
||
example: '23456.78'
|
||
monthProfit:
|
||
type: string
|
||
example: '3456.78'
|
||
stockCount:
|
||
type: string
|
||
example: '1200'
|
||
Account:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
name:
|
||
type: string
|
||
type:
|
||
type: string
|
||
enum: [cash, bank, alipay, wechat, other]
|
||
balance:
|
||
type: number
|
||
bankName:
|
||
type: string
|
||
nullable: true
|
||
bankAccount:
|
||
type: string
|
||
nullable: true
|
||
CreateAccountRequest:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
type: { type: string, enum: [cash, bank, alipay, wechat, other] }
|
||
bankName: { type: string, nullable: true }
|
||
bankAccount: { type: string, nullable: true }
|
||
openingBalance: { type: number, nullable: true }
|
||
status: { type: integer, enum: [0,1], default: 1 }
|
||
Supplier:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
contactName: { type: string, nullable: true }
|
||
mobile: { type: string, nullable: true }
|
||
phone: { type: string, nullable: true }
|
||
address: { type: string, nullable: true }
|
||
apOpening: { type: number }
|
||
apPayable: { type: number }
|
||
remark: { type: string, nullable: true }
|
||
CreateSupplierRequest:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
contactName: { type: string, nullable: true }
|
||
mobile: { type: string, nullable: true }
|
||
phone: { type: string, nullable: true }
|
||
address: { type: string, nullable: true }
|
||
apOpening: { type: number, nullable: true }
|
||
apPayable: { type: number, nullable: true }
|
||
remark: { type: string, nullable: true }
|
||
CreateOtherTransactionRequest:
|
||
type: object
|
||
properties:
|
||
type:
|
||
type: string
|
||
enum: [income, expense]
|
||
category:
|
||
type: string
|
||
counterpartyType:
|
||
type: string
|
||
enum: [customer, supplier, other]
|
||
counterpartyId:
|
||
type: integer
|
||
format: int64
|
||
nullable: true
|
||
accountId:
|
||
type: integer
|
||
format: int64
|
||
amount:
|
||
type: number
|
||
txTime:
|
||
type: string
|
||
format: date
|
||
remark:
|
||
type: string
|
||
endsAt:
|
||
type: string
|
||
format: date-time
|
||
status:
|
||
type: string
|
||
enum: [DRAFT, PUBLISHED, OFFLINE]
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
Product:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
code:
|
||
type: string
|
||
name:
|
||
type: string
|
||
price:
|
||
type: number
|
||
stock:
|
||
type: number
|
||
ProductDetail:
|
||
allOf:
|
||
- $ref: '#/components/schemas/Product'
|
||
- type: object
|
||
properties:
|
||
brand: { type: string }
|
||
model: { type: string }
|
||
spec: { type: string }
|
||
categoryId: { type: integer, format: int64, nullable: true }
|
||
unitId: { type: integer, format: int64 }
|
||
safeMin: { type: number, nullable: true }
|
||
safeMax: { type: number, nullable: true }
|
||
purchasePrice: { type: number }
|
||
retailPrice: { type: number }
|
||
distributionPrice: { type: number }
|
||
wholesalePrice: { type: number }
|
||
bigClientPrice: { type: number }
|
||
images:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties: { url: { type: string } }
|
||
CreateProductRequest:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
barcode: { type: string, nullable: true }
|
||
brand: { type: string, nullable: true }
|
||
model: { type: string, nullable: true }
|
||
spec: { type: string, nullable: true }
|
||
categoryId: { type: integer, format: int64, nullable: true }
|
||
unitId: { type: integer, format: int64 }
|
||
safeMin: { type: number, nullable: true }
|
||
safeMax: { type: number, nullable: true }
|
||
prices:
|
||
type: object
|
||
properties:
|
||
purchasePrice: { type: number }
|
||
retailPrice: { type: number }
|
||
distributionPrice: { type: number }
|
||
wholesalePrice: { type: number }
|
||
bigClientPrice: { type: number }
|
||
stock: { type: number, nullable: true }
|
||
images:
|
||
type: array
|
||
items: { type: string, description: '图片URL' }
|
||
Category:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
Unit:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
ProductSettings:
|
||
type: object
|
||
properties:
|
||
hideZeroStock: { type: boolean }
|
||
hidePurchasePrice: { type: boolean }
|
||
Customer:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
name: { type: string }
|
||
contactName: { type: string }
|
||
mobile: { type: string }
|
||
phone: { type: string }
|
||
priceLevel: { type: string, enum: [零售价, 批发价, 大单报价] }
|
||
remark: { type: string }
|
||
receivable: { type: number }
|
||
CreateCustomerRequest:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
priceLevel: { type: string, enum: [零售价, 批发价, 大单报价] }
|
||
contactName: { type: string, nullable: true }
|
||
mobile: { type: string, nullable: true }
|
||
phone: { type: string, nullable: true }
|
||
address: { type: string, nullable: true }
|
||
arOpening: { type: number, nullable: true }
|
||
remark: { type: string, nullable: true }
|
||
CreateOrderRequest:
|
||
type: object
|
||
properties:
|
||
type:
|
||
type: string
|
||
description: 'sale.out/sale.return/sale.collect/purchase.in/purchase.return/purchase.pay'
|
||
orderTime:
|
||
type: string
|
||
format: date-time
|
||
customerId:
|
||
type: integer
|
||
format: int64
|
||
nullable: true
|
||
supplierId:
|
||
type: integer
|
||
format: int64
|
||
nullable: true
|
||
items:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
productId:
|
||
type: integer
|
||
format: int64
|
||
quantity:
|
||
type: number
|
||
unitPrice:
|
||
type: number
|
||
discountRate:
|
||
type: number
|
||
amount:
|
||
type: number
|
||
payments:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/PaymentItem'
|
||
PaymentItem:
|
||
type: object
|
||
properties:
|
||
method: { type: string, enum: [cash, bank, wechat] }
|
||
amount: { type: number }
|
||
orderId: { type: integer, format: int64, nullable: true }
|
||
|