图片功能url实现

This commit is contained in:
2025-09-21 16:01:59 +08:00
parent e5eb8d6174
commit 39679f7330
15 changed files with 538 additions and 73 deletions

View File

@@ -14,7 +14,12 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_shops_status` (`status`)
字段说明:
- id: 主键,自增
- name: 店铺名称
- status: 店铺状态1启用/0停用
- created_at/updated_at: 创建/更新时间
- deleted_at: 逻辑删除时间
### users
| Column Name | Data Type | Nullable | Default | Comment |
@@ -31,8 +36,11 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_users_shop` (`shop_id`) - UNIQUE: `ux_users_shop_phone` (`shop_id`,`phone`)
**Foreign Keys**: - `fk_users_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
字段说明:
- shop_id: 归属店铺
- role: 角色标识字符串
- is_owner: 是否店主标记
- 其余同名含义
### user_identities
| Column Name | Data Type | Nullable | Default | Comment |
@@ -49,8 +57,9 @@
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_identity_shop` (`shop_id`) - KEY: `idx_identity_user` (`user_id`) - UNIQUE: `ux_identity_provider_openid` (`provider`,`openid`) - UNIQUE: `ux_identity_unionid` (`unionid`)
**Foreign Keys**: - `fk_identity_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_identity_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
字段说明:
- provider: wechat_mp小程序、wechat_appAPP
- openid/unionid: 微信身份标识
### wechat_sessions
| Column Name | Data Type | Nullable | Default | Comment |
@@ -62,7 +71,8 @@
| expires_at | DATETIME | NOT NULL | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_wechat_session_expires` (`expires_at`) - UNIQUE: `ux_wechat_session` (`provider`,`openid`)
字段说明:
- session_key/expires_at: 会话密钥与过期时间
### system_parameters
| Column Name | Data Type | Nullable | Default | Comment |
@@ -75,8 +85,8 @@
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_sysparams_shop` (`shop_id`) - UNIQUE: `ux_sysparams_shop_key` (`shop_id`,`key`)
**Foreign Keys**: - `fk_sysparams_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_sysparams_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
字段说明:
- key/value: 键/值JSON
### product_units
| Column Name | Data Type | Nullable | Default | Comment |
@@ -89,6 +99,9 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明product_units
- name: 单位名称,如 件/个/箱
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_units_shop` (`shop_id`) - UNIQUE: `ux_units_shop_name` (`shop_id`,`name`)
**Foreign Keys**: - `fk_units_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_units_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
@@ -108,6 +121,12 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明global_skus
- name/brand/model/spec/barcode: SKU 基本属性
- unit_id: 对应的计量单位
- tags: 结构化标签 JSON
- status: 上架状态published/offline
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_global_skus_brand_model` (`brand`,`model`) - UNIQUE: `ux_global_skus_barcode` (`barcode`)
**Foreign Keys**: - `fk_globalsku_unit`: `unit_id``product_units(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
@@ -124,6 +143,10 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明product_categories
- parent_id: 父分类,可为空
- sort_order: 排序
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_categories_shop` (`shop_id`) - KEY: `idx_categories_parent` (`parent_id`) - UNIQUE: `ux_categories_shop_name` (`shop_id`,`name`)
**Foreign Keys**: - `fk_categories_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_categories_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_categories_parent`: `parent_id``product_categories(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
@@ -151,6 +174,11 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明products
- category_id/unit_id/global_sku_id: 归属分类/单位/全局SKU
- safe_min/safe_max: 安全库存上下限
- search_text: 聚合检索字段(触发器维护)
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_products_shop` (`shop_id`) - KEY: `idx_products_category` (`category_id`) - KEY: `idx_products_unit` (`unit_id`) - FULLTEXT: `ft_products_search` (`name`,`brand`,`model`,`spec`,`search_text`) - UNIQUE: `ux_products_shop_barcode` (`shop_id`,`barcode`)
**Foreign Keys**: - `fk_products_shop`: `shop_id``shops(id)` - `fk_products_user`: `user_id``users(id)` - `fk_products_category`: `category_id``product_categories(id)` - `fk_products_unit`: `unit_id``product_units(id)` - `fk_products_globalsku`: `global_sku_id``global_skus(id)`
@@ -166,6 +194,9 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明product_aliases
- alias: 商品别名(同义词)
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_product_alias_product` (`product_id`) - UNIQUE: `ux_product_alias` (`product_id`,`alias`)
**Foreign Keys**: - `fk_alias_shop`: `shop_id``shops(id)` - `fk_alias_user`: `user_id``users(id)` - `fk_alias_product`: `product_id``products(id)`
@@ -181,6 +212,10 @@
| sort_order | INT | NOT NULL | 0 | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
字段说明product_images
- url/hash: 图片地址/内容哈希
- sort_order: 展示顺序
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_product_images_product` (`product_id`) - UNIQUE: `ux_product_image_hash` (`product_id`,`hash`)
**Foreign Keys**: - `fk_pimg_shop`: `shop_id``shops(id)` - `fk_pimg_user`: `user_id``users(id)` - `fk_pimg_product`: `product_id``products(id)` ON DELETE CASCADE
@@ -196,6 +231,10 @@
| big_client_price | DECIMAL(18,2) | NOT NULL | 0.00 | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
字段说明product_prices
- purchase_price: 当前进价(用于近似毛利)
- retail/wholesale/big_client_price: 售价列
**Indexes**: - PRIMARY KEY: `product_id` - KEY: `idx_prices_shop` (`shop_id`)
**Foreign Keys**: - `fk_prices_product`: `product_id``products(id)` ON DELETE CASCADE - `fk_prices_shop`: `shop_id``shops(id)` - `fk_prices_user`: `user_id``users(id)`
@@ -208,6 +247,9 @@
| quantity | DECIMAL(18,3) | NOT NULL | 0.000 | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
字段说明inventories
- quantity: 当前库存数量(按商品一行聚合)
**Indexes**: - PRIMARY KEY: `product_id` - KEY: `idx_inventories_shop` (`shop_id`)
**Foreign Keys**: - `fk_inv_product`: `product_id``products(id)` ON DELETE CASCADE - `fk_inv_shop`: `shop_id``shops(id)` - `fk_inv_user`: `user_id``users(id)`
@@ -231,6 +273,11 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明customers
- level: 等级标签
- price_level: 默认售价列(中文存储:零售价/批发价/大单报价)
- ar_opening: 期初应收
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_customers_shop` (`shop_id`) - KEY: `idx_customers_phone` (`phone`) - KEY: `idx_customers_mobile` (`mobile`)
**Foreign Keys**: - `fk_customers_shop`: `shop_id``shops(id)` - `fk_customers_user`: `user_id``users(id)`
@@ -253,6 +300,9 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明suppliers
- ap_opening/ap_payable: 期初应付/当前应付
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_suppliers_shop` (`shop_id`) - KEY: `idx_suppliers_phone` (`phone`) - KEY: `idx_suppliers_mobile` (`mobile`)
**Foreign Keys**: - `fk_suppliers_shop`: `shop_id``shops(id)` - `fk_suppliers_user`: `user_id``users(id)`
@@ -272,6 +322,10 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明accounts
- type: 账户类型cash/bank/alipay/wechat/other
- bank_name/bank_account: 银行账户信息type=bank 时使用)
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_accounts_shop` (`shop_id`) - UNIQUE: `ux_accounts_shop_name` (`shop_id`,`name`)
**Foreign Keys**: - `fk_accounts_shop`: `shop_id``shops(id)` - `fk_accounts_user`: `user_id``users(id)`
@@ -292,6 +346,10 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明sales_orders
- status: 单据状态draft/approved/returned/void
- amount/paid_amount: 应收/已收合计
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_sales_shop_time` (`shop_id`,`order_time`) - KEY: `idx_sales_customer` (`customer_id`) - UNIQUE: `ux_sales_order_no` (`shop_id`,`order_no`)
**Foreign Keys**: - `fk_sales_shop`: `shop_id``shops(id)` - `fk_sales_user`: `user_id``users(id)` - `fk_sales_customer`: `customer_id``customers(id)`
@@ -306,6 +364,9 @@
| discount_rate | DECIMAL(5,2) | NOT NULL | 0.00 | 折扣百分比0-100 |
| amount | DECIMAL(18,2) | NOT NULL | | |
字段说明sales_order_items
- quantity/unit_price/discount_rate/amount: 数量/单价/折扣%/行金额
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_soi_order` (`order_id`) - KEY: `idx_soi_product` (`product_id`)
**Foreign Keys**: - `fk_soi_order`: `order_id``sales_orders(id)` ON DELETE CASCADE - `fk_soi_product`: `product_id``products(id)`
@@ -326,6 +387,9 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明purchase_orders/purchase_order_items
- 与销售单结构类似,含应付与明细
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_purchase_shop_time` (`shop_id`,`order_time`) - KEY: `idx_purchase_supplier` (`supplier_id`) - UNIQUE: `ux_purchase_order_no` (`shop_id`,`order_no`)
**Foreign Keys**: - `fk_purchase_shop`: `shop_id``shops(id)` - `fk_purchase_user`: `user_id``users(id)` - `fk_purchase_supplier`: `supplier_id``suppliers(id)`
@@ -357,6 +421,11 @@
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
字段说明payments
- biz_type/biz_id: 业务来源及关联主键
- direction: in 收款 / out 付款
- account_id: 使用的结算账户
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_payments_shop_time` (`shop_id`,`pay_time`) - KEY: `idx_payments_biz` (`biz_type`,`biz_id`)
**Foreign Keys**: - `fk_payments_shop`: `shop_id``shops(id)` - `fk_payments_user`: `user_id``users(id)` - `fk_payments_account`: `account_id``accounts(id)`
@@ -378,6 +447,10 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明other_transactions
- type/category: 收入/支出与分类
- counterparty_type/id: 往来单位(可空)
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_ot_shop_time` (`shop_id`,`tx_time`) - KEY: `idx_ot_account` (`account_id`)
**Foreign Keys**: - `fk_ot_shop`: `shop_id``shops(id)` - `fk_ot_user`: `user_id``users(id)` - `fk_ot_account`: `account_id``accounts(id)`
@@ -394,6 +467,10 @@
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
字段说明finance_categories
- key: 稳定标识(代码不随展示文案改变)
- label: 展示名称
**Indexes**: - PRIMARY KEY: `id` - UNIQUE: `ux_finance_cat` (`shop_id`,`type`,`key`) - KEY: `idx_finance_cat_shop_type` (`shop_id`,`type`)
**Foreign Keys**: - `fk_finance_cat_shop`: `shop_id``shops(id)`
@@ -420,6 +497,11 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明notices
- is_pinned: 是否置顶
- starts_at/ends_at: 生效时间窗
- status: 草稿/发布/下线
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_notices_time` (`starts_at`,`ends_at`)
**Foreign Keys**: - 无
@@ -439,6 +521,11 @@
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
字段说明inventory_movements
- qty_delta: 数量变动(入库为正、出库为负)
- amount_delta: 金额变动(可选)
- source_type/source_id: 变动来源追溯
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_im_shop_time` (`shop_id`,`tx_time`) - KEY: `idx_im_product` (`product_id`)
**Foreign Keys**: - `fk_im_shop`: `shop_id``shops(id)` - `fk_im_user`: `user_id``users(id)` - `fk_im_product`: `product_id``products(id)`
@@ -466,6 +553,9 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明sales_return_orders
- 与销售单结构一致,用于退货业务;状态为 approved/void
**Indexes**: - PRIMARY KEY: `id` - UNIQUE: `ux_sr_order_no` (`shop_id`,`order_no`) - KEY: `idx_sr_shop_time` (`shop_id`,`order_time`)
**Foreign Keys**: - `fk_sr_shop`: `shop_id``shops(id)` - `fk_sr_user`: `user_id``users(id)` - `fk_sr_customer`: `customer_id``customers(id)`
@@ -500,6 +590,9 @@
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
字段说明purchase_return_orders
- 与销售单结构一致,用于退货业务;状态为 approved/void
**Indexes**: - PRIMARY KEY: `id` - UNIQUE: `ux_pr_order_no` (`shop_id`,`order_no`) - KEY: `idx_pr_shop_time` (`shop_id`,`order_time`)
**Foreign Keys**: - `fk_pr_shop`: `shop_id``shops(id)` - `fk_pr_user`: `user_id``users(id)` - `fk_pr_supplier`: `supplier_id``suppliers(id)`

View File

@@ -876,8 +876,8 @@ paths:
direction: { type: string }
/api/attachments:
post:
summary: 上传附件(✅ Fully Implemented占位图方案
description: 接收 multipart 上传但忽略文件内容,始终返回占位图 URL后端配置项 `attachments.placeholder.image-path` 指向本地占位图片URL 固定 `/api/attachments/placeholder` 可通过 `attachments.placeholder.url-path` 覆盖)
summary: 上传附件(❌ Partially Implemented已废弃采用纯URL引用
description: 方案A采用纯URL引用不再支持文件直传。历史兼容此接口仍存在但返回占位图 URL建议前端改用 `/api/attachments/validate-url` 进行URL校验后直接写入业务字段
requestBody:
required: true
content:
@@ -902,6 +902,36 @@ paths:
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