Files
PartsInquiry/doc/openapi.yaml
2025-09-21 16:01:59 +08:00

1240 lines
38 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

openapi: 3.0.3
info:
title: PartsInquiry API
version: 0.1.0
description: >-
所有接口定义集中于此文件。每个 path 在 summary/description 中标注实现状态。
servers:
- url: /
paths:
/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: 成功
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: 'payments/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}:
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'
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
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
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: 成功 } }
- type: object
properties:
list:
type: array
items:
$ref: '#/components/schemas/Product'
/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|purchasetype=out|in|return返回 {list:[]}。后端已返回驼峰字段与名称sale: customerNamepurchase: 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 }
/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: 上传附件(❌ Partially Implemented已废弃采用纯URL引用
description: 方案A采用纯URL引用不再支持文件直传。历史兼容此接口仍存在但返回占位图 URL建议前端改用 `/api/attachments/validate-url` 进行URL校验后直接写入业务字段。
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
/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
description: 返回后端配置的本地占位图内容,路径由 `attachments.placeholder.image-path` 指定。
responses:
'200':
description: 图片二进制
content:
image/png:
schema:
type: string
format: binary
components:
schemas:
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
pinned:
type: boolean
startsAt:
type: string
format: date-time
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 }
level: { type: string }
priceLevel: { type: string, enum: [零售价, 批发价, 大单报价] }
remark: { type: string }
receivable: { type: number }
CreateCustomerRequest:
type: object
properties:
name: { type: string }
level: { type: string, nullable: true }
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 }