Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
H
hanni-external-api
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
杨向龙
hanni-external-api
Commits
6f6dffbd
Commit
6f6dffbd
authored
Mar 20, 2026
by
yangxianglong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
自采联营门店系统开发
parent
48906a68
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
204 additions
and
72 deletions
+204
-72
README.md
README.md
+96
-31
ItemController.java
.../java/cn/nhsoft/hanni/item/controller/ItemController.java
+4
-4
LemonToHanniItemConverter.java
...hsoft/hanni/item/converter/LemonToHanniItemConverter.java
+1
-35
ItemSyncServiceImpl.java
...n/nhsoft/hanni/item/service/impl/ItemSyncServiceImpl.java
+7
-0
LemonItemFindRequestMapper.java
...nhsoft/hanni/item/support/LemonItemFindRequestMapper.java
+3
-2
mysql-item-sync.sql
src/main/resources/db/mysql-item-sync.sql
+93
-0
No files found.
README.md
View file @
6f6dffbd
# 汉尼外部
API - 自采联营门店系统
# 汉尼外部
API(hanni-external-api)
养馋记与汉尼系统自采联营门店业务协同的后端 API 服务
。
**养馋记与汉尼系统自采联营门店**
的后端对接服务:从
**乐檬**
拉取商品档案并推送
**汉尼**
,管理乐檬
**OAuth Token**
(含持久化与定时刷新)
。
## 功能模块
---
1.
**商品档案同步**
:从乐檬获取商品档案,加工后传入汉尼;支持增量(
`lastDownloadTime`
)、变更检测与定时/手动任务
## 功能概览
## 技术栈
-
Java 8、Spring Boot 2.7.18、Maven
-
乐檬:
**RestTemplate**
(商品查询、OAuth token),
**无 apicloud-sdk**
| 能力 | 说明 |
|------|------|
| 商品同步 | 按乐檬
`nhsoft.amazon.basic.item.find`
多页拉取,映射为汉尼字段后调用新增/变更接口 |
| 增量 | 定时同步时根据上次
**SUCCESS**
日志的结束时间设置
`last_download_time`
|
| 跳过未变化 | 依赖快照表比对乐檬「最后修改时间」字符串,减少重复推送 |
| 过滤策略 |
**仅通过乐檬查询参数**
`filter_sleep`
、
`filter_weed_out`
控制是否排除休眠/淘汰;请求体不在本地再按淘汰/休眠二次过滤 |
| Token | OAuth 授权码换 Token、手动设置、refresh;落库
`lemeng_oauth_token`
,启动加载到内存 |
## 主要接口(context-path: `/api`)
---
| 模块 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 商品 | GET |
`/item/sync`
| 定时同款:按上次成功结束时间增量、
**多页**
拉取后同步汉尼 |
| 商品 | GET |
`/item/sync/manual`
| 手动:查询参数与乐檬
`item.find`
一致,
**多页**
拉取后同步(与
`/sync`
分页策略相同) |
| 商品 | GET |
`/item/lemon`
| 仅查乐檬
**当前页**
JSON,不同步 |
| 商品 | GET |
`/item/sync-logs`
| 同步日志分页(DB 分页,
`status`
可选) |
| Token | POST |
`/lemeng/token/set`
| 写入数据库
`lemeng_oauth_token`
并同步内存 |
| Token | POST |
`/lemeng/token/refresh`
|
`refresh_token`
刷新(HTTP 状态码区分 401/400) |
| 授权 | GET |
`/auth/code`
| OAuth2 回调换 token |
## 技术栈
## 乐檬配置
-
Java 8、Spring Boot
**2.7.18**
、Maven
-
Spring Web、Spring Data JPA、Actuator、SpringDoc OpenAPI 3
-
乐檬侧:
**仅 RestTemplate**
(商品 GET、OAuth),
**不使用 apicloud-sdk**
-
开发默认
**H2 内存库**
;生产建议使用
**MySQL**
(
`spring.profiles.active=prod`
)
-
`lemon.api.*`
:商品 GET 地址与静态
`access-token`
(可选,优先内存中的 OAuth Token)
-
`lemeng.auth-server-url`
、
`lemeng.redirect-url`
、
`lemeng.app.*`
:OAuth 与应用凭证
-
**Token 持久化**
:OAuth 回调、
`/lemeng/token/set`
、手动/定时刷新均会更新库表
`lemeng_oauth_token`
;
**服务启动时自动加载到内存**
。MySQL 可执行
`src/main/resources/db/mysql-lemeng-oauth-token.sql`
;本地 H2 可通过
`ddl-auto=update`
自动建表。
---
## 快速开始
```
bash
cd
hanni-external-api
mvn clean compile
mvn spring-boot:run
```
-
根地址:
`http://localhost:8081/api`
-
Swagger:
`/swagger-ui.html`
-
健康:
`/actuator/health`
-
**服务根路径**
:
`http://localhost:8081/api`
(
`server.servlet.context-path=/api`
)
-
**Swagger UI**
:
`http://localhost:8081/api/swagger-ui.html`
-
**OpenAPI JSON**
:
`/api/v3/api-docs`
-
**健康检查**
:
`/api/actuator/health`
---
## HTTP 接口(相对 `/api`)
### 商品档案
| 方法 | 路径 | 说明 |
|------|------|------|
| GET |
`/item/sync`
| 与定时任务同类:按上次成功结束时间增量,
**多页**
拉取后同步汉尼;请求乐檬时默认
`filter_sleep`
、
`filter_weed_out`
为
`true`
|
| GET |
`/item/sync/manual`
| 手动同步;查询参数与乐檬
`item.find`
对齐,多页拉到底;
`filterSleep`
/
`filterWeedOut`
**未传时默认为 true**
|
| GET |
`/item/lemon`
| 只查乐檬
**当前页**
JSON,
**不同步**
;过滤参数默认同上 |
| GET |
`/item/sync-logs`
| 同步日志分页,
`status`
可选 |
| GET |
`/item/sync-logs/{logId}/details`
| 某次任务商品明细分页(ADD/UPDATE/SKIP 等) |
手动/调试时若需包含休眠或淘汰品,可显式传
`filterSleep=false`
或
`filterWeedOut=false`
。
### 乐檬 Token 与授权
| 方法 | 路径 | 说明 |
|------|------|------|
| GET |
`/auth/code`
| OAuth2 回调:用
`code`
换 Token,写入库并刷新内存 |
| POST |
`/lemeng/token/set`
| 手工写入
`access_token`
/
`refresh_token`
(按账套),
**落库 + 内存**
|
| POST |
`/lemeng/token/refresh`
|
`grant_type=refresh_token`
,成功后备份到库与内存 |
商品请求鉴权:
**优先**
内存
`TokenHolder`
(OAuth/上述接口写入),
**否则**
`application.yml`
中
`lemon.api.access-token`
。
---
## 配置说明(`application.yml`)
## 项目结构(摘要)
| 前缀 | 用途 |
|------|------|
|
`server.port`
/
`server.servlet.context-path`
| 默认
`8081`
、上下文
`/api`
|
|
`spring.datasource.*`
| 本地 H2;生产见
`application-prod.yml`
|
|
`spring.jpa.hibernate.ddl-auto`
| 开发常用
`update`
;生产请结合规范评估 |
|
`lemon.api.*`
|
`base-url`
、
`item-find-url`
、可选静态
`access-token`
、
`auth-type`
(
`bearer`
/
`header`
) |
|
`lemeng.*`
|
`auth-server-url`
、
`redirect-url`
、
`lemeng.app.app-id`
/
`app-secret`
/
`system-book-code`
|
|
`hanni.api.*`
| 汉尼
`receive-goods-url`
、
`update-goods-url`
(可选)、
`sign-key`
(MD5 签名) |
|
`task.item-sync.*`
|
`enabled`
、
`cron`
(默认定时同步,示例:每天 0 点) |
|
`task.token-refresh.*`
| 是否启用乐檬 Token 定时刷新(约每 50 分钟) |
环境变量示例(OAuth):
`SYSTEM_BOOK_CODE`
、
`APP_ID`
、
`APP_SECRET`
。
**生产库**
:激活
`prod`
后在
`application-prod.yml`
中配置数据源;
**密码等敏感项建议改为环境变量注入,勿提交仓库。**
---
## 数据库
-
**脚本位置**
:
`src/main/resources/db/mysql-item-sync.sql`
-
**主要表**
:
`item_sync_log`
(任务汇总)、
`item_sync_snapshot`
(条码快照/变更跳过)、
`item_sync_detail`
(单次明细)、
`item_sync_cache`
(旧版 MD5 缓存,可不用)、
`lemeng_oauth_token`
(Token 持久化)
-
本地 H2 可使用
`ddl-auto=update`
自动建表;MySQL 建议执行上述脚本或由 Hibernate 按策略创建(以运维规范为准)。
---
## 包结构(摘要)
```
cn.nhsoft.hanni/
├── client/ # LemonApiClient、HanniApiClient
├── common/util/ # Md5Util 等
├── item/ # 商品同步、LemonItemResponseParser、LemonItemFindRequestMapper
├── lemeng/ # Token、OAuth
└── task/ # ItemSyncTask
├── client/ # LemonApiClient、HanniApiClient
├── common/ # 统一响应、异常处理、工具类
├── config/ # RestTemplate、Swagger、各 Properties
├── item/ # 商品同步、转换器、仓储、控制器
├── lemeng/ # OAuth、Token、持久化、定时刷新 Job
└── task/ # ItemSyncTask 等定时入口
```
---
## 与前端联调
前端(
`ycj-cloud-ui`
)开发时将
**`/hanni-api`**
代理到本服务,并重写为
**`/api`**
,例如:
-
前端:
`GET /hanni-api/item/sync`
-
实际:
`GET http://localhost:8081/api/item/sync`
详见工作区根目录
[
`README.md`
](
../README.md
)
。
src/main/java/cn/nhsoft/hanni/item/controller/ItemController.java
View file @
6f6dffbd
...
...
@@ -50,8 +50,8 @@ public class ItemController {
@Parameter
(
description
=
"最后修改时间(yyyy-MM-dd HH:mm:ss)"
)
@RequestParam
(
required
=
false
)
String
lastDownloadTime
,
@Parameter
(
description
=
"商品类型"
)
@RequestParam
(
required
=
false
)
Integer
itemType
,
@Parameter
(
description
=
"商品类别代码"
)
@RequestParam
(
required
=
false
)
String
itemCategoryCode
,
@Parameter
(
description
=
"是否过滤休眠商品"
)
@RequestParam
(
required
=
false
)
Boolean
filterSleep
,
@Parameter
(
description
=
"是否过滤淘汰商品"
)
@RequestParam
(
required
=
false
)
Boolean
filterWeedOut
,
@Parameter
(
description
=
"是否过滤休眠商品
,默认 true(仅同步非休眠)
"
)
@RequestParam
(
required
=
false
)
Boolean
filterSleep
,
@Parameter
(
description
=
"是否过滤淘汰商品
,默认 true(仅同步非淘汰)
"
)
@RequestParam
(
required
=
false
)
Boolean
filterWeedOut
,
@Parameter
(
description
=
"商品编码,逗号分隔"
)
@RequestParam
(
required
=
false
)
String
itemNums
,
@Parameter
(
description
=
"商品代码,逗号分隔"
)
@RequestParam
(
required
=
false
)
String
itemCodes
)
{
itemSyncService
.
syncItemsWithParams
(
LemonItemFindRequestMapper
.
fromQuery
(
...
...
@@ -68,8 +68,8 @@ public class ItemController {
@Parameter
(
description
=
"最后修改时间(yyyy-MM-dd HH:mm:ss)"
)
@RequestParam
(
required
=
false
)
String
lastDownloadTime
,
@Parameter
(
description
=
"商品类型"
)
@RequestParam
(
required
=
false
)
Integer
itemType
,
@Parameter
(
description
=
"商品类别代码"
)
@RequestParam
(
required
=
false
)
String
itemCategoryCode
,
@Parameter
(
description
=
"是否过滤休眠商品"
)
@RequestParam
(
required
=
false
)
Boolean
filterSleep
,
@Parameter
(
description
=
"是否过滤淘汰商品"
)
@RequestParam
(
required
=
false
)
Boolean
filterWeedOut
,
@Parameter
(
description
=
"是否过滤休眠商品
,默认 true(仅同步非休眠)
"
)
@RequestParam
(
required
=
false
)
Boolean
filterSleep
,
@Parameter
(
description
=
"是否过滤淘汰商品
,默认 true(仅同步非淘汰)
"
)
@RequestParam
(
required
=
false
)
Boolean
filterWeedOut
,
@Parameter
(
description
=
"商品编码,逗号分隔"
)
@RequestParam
(
required
=
false
)
String
itemNums
,
@Parameter
(
description
=
"商品代码,逗号分隔"
)
@RequestParam
(
required
=
false
)
String
itemCodes
)
{
String
data
=
itemSyncService
.
getItemsFromLemon
(
LemonItemFindRequestMapper
.
fromQuery
(
...
...
src/main/java/cn/nhsoft/hanni/item/converter/LemonToHanniItemConverter.java
View file @
6f6dffbd
...
...
@@ -18,7 +18,7 @@ import java.util.Map;
/**
* 乐檬商品数据转汉尼格式
* <p>乐檬字段 -> 汉尼字段映射</p>
* <p>乐檬字段 -> 汉尼字段映射
。是否排除淘汰/休眠由乐檬接口查询参数 {@code filter_weed_out}、{@code filter_sleep} 控制,此处不再按返回体二次过滤。
</p>
*/
@Slf4j
@Component
...
...
@@ -89,9 +89,6 @@ public class LemonToHanniItemConverter {
private
HanniItemDTO
convertSingle
(
JsonNode
node
)
{
try
{
Map
<
String
,
Object
>
map
=
objectMapper
.
convertValue
(
node
,
new
TypeReference
<
Map
<
String
,
Object
>>()
{});
if
(!
shouldIncludeItem
(
map
))
{
return
null
;
}
return
convertFromMap
(
map
);
}
catch
(
Exception
e
)
{
log
.
warn
(
"单条商品转换失败: {}"
,
node
,
e
);
...
...
@@ -102,9 +99,6 @@ public class LemonToHanniItemConverter {
private
LemonItemRow
convertSingleToRow
(
JsonNode
node
)
{
try
{
Map
<
String
,
Object
>
map
=
objectMapper
.
convertValue
(
node
,
new
TypeReference
<
Map
<
String
,
Object
>>()
{});
if
(!
shouldIncludeItem
(
map
))
{
return
null
;
}
HanniItemDTO
dto
=
convertFromMap
(
map
);
String
lemonMod
=
extractLemonLastModified
(
map
);
return
new
LemonItemRow
(
dto
,
lemonMod
);
...
...
@@ -132,34 +126,6 @@ public class LemonToHanniItemConverter {
return
null
;
}
/**
* 养馋记商品过滤:是否停购=否,且不为淘汰、删除的商品才传入汉尼
*/
private
boolean
shouldIncludeItem
(
Map
<
String
,
Object
>
m
)
{
if
(
isTrue
(
m
,
"item_stop_purchase_flag"
,
"item_purchase_stop_flag"
,
"stop_purchase_flag"
))
{
return
false
;
}
if
(
isTrue
(
m
,
"item_weed_out_flag"
,
"weed_out_flag"
,
"weed_out"
))
{
return
false
;
}
if
(
isTrue
(
m
,
"item_delete_flag"
,
"deleted"
,
"delete_flag"
,
"is_deleted"
))
{
return
false
;
}
return
true
;
}
private
boolean
isTrue
(
Map
<
String
,
Object
>
m
,
String
...
keys
)
{
for
(
String
k
:
keys
)
{
Object
v
=
m
.
get
(
k
);
if
(
v
!=
null
)
{
if
(
Boolean
.
TRUE
.
equals
(
v
)
||
"true"
.
equalsIgnoreCase
(
v
.
toString
())
||
"1"
.
equals
(
v
.
toString
()))
{
return
true
;
}
}
}
return
false
;
}
private
HanniItemDTO
convertFromMap
(
Map
<
String
,
Object
>
m
)
{
HanniItemDTO
dto
=
new
HanniItemDTO
();
dto
.
setBarcode
(
getStr
(
m
,
"item_barcode"
,
"barcode"
));
...
...
src/main/java/cn/nhsoft/hanni/item/service/impl/ItemSyncServiceImpl.java
View file @
6f6dffbd
...
...
@@ -118,6 +118,13 @@ public class ItemSyncServiceImpl implements ItemSyncService {
}
private
void
doSyncIncremental
(
LemonItemFindRequest
request
,
String
syncType
)
{
// 未显式设置时与定时任务一致:向乐檬传 filter_sleep/filter_weed_out(仅依赖接口查询参数)
if
(
request
.
getFilterSleep
()
==
null
)
{
request
.
setFilterSleep
(
Boolean
.
TRUE
);
}
if
(
request
.
getFilterWeedOut
()
==
null
)
{
request
.
setFilterWeedOut
(
Boolean
.
TRUE
);
}
runWithSyncLog
(
syncType
,
syncLog
->
{
List
<
LemonItemRow
>
allRows
=
new
ArrayList
<>();
int
pageNo
=
request
.
getPageNo
()
!=
null
?
request
.
getPageNo
()
:
1
;
...
...
src/main/java/cn/nhsoft/hanni/item/support/LemonItemFindRequestMapper.java
View file @
6f6dffbd
...
...
@@ -29,8 +29,9 @@ public final class LemonItemFindRequestMapper {
request
.
setLastDownloadTime
(
lastDownloadTime
);
request
.
setItemType
(
itemType
);
request
.
setItemCategoryCode
(
itemCategoryCode
);
request
.
setFilterSleep
(
filterSleep
);
request
.
setFilterWeedOut
(
filterWeedOut
);
// 未传参时默认与乐檬 item.find 查询参数一致:filter_sleep/filter_weed_out=true(true=过滤掉休眠/淘汰)
request
.
setFilterSleep
(
filterSleep
!=
null
?
filterSleep
:
Boolean
.
TRUE
);
request
.
setFilterWeedOut
(
filterWeedOut
!=
null
?
filterWeedOut
:
Boolean
.
TRUE
);
if
(
itemNums
!=
null
&&
!
itemNums
.
isEmpty
())
{
request
.
setItemNums
(
Arrays
.
stream
(
itemNums
.
split
(
","
))
.
map
(
String:
:
trim
)
...
...
src/main/resources/db/mysql-item-sync.sql
0 → 100644
View file @
6f6dffbd
-- 汉尼外部 API 相关表(MySQL 8+, utf8mb4)
-- 含:商品同步、乐檬 OAuth Token 持久化
-- 执行前请替换库名: USE your_database;
SET
NAMES
utf8mb4
;
-- ----------------------------
-- 同步任务汇总日志
-- ----------------------------
CREATE
TABLE
IF
NOT
EXISTS
`item_sync_log`
(
`id`
BIGINT
NOT
NULL
AUTO_INCREMENT
COMMENT
'主键'
,
`sync_type`
VARCHAR
(
32
)
DEFAULT
NULL
COMMENT
'SCHEDULED/MANUAL/RUNNING 等'
,
`lemeng_count`
INT
DEFAULT
NULL
COMMENT
'乐檬返回商品条数'
,
`hanni_count`
INT
DEFAULT
NULL
COMMENT
'本批处理条数'
,
`status`
VARCHAR
(
16
)
DEFAULT
NULL
COMMENT
'SUCCESS/FAIL/SKIP/RUNNING'
,
`hanni_response`
TEXT
DEFAULT
NULL
COMMENT
'汉尼接口响应摘要'
,
`error_msg`
TEXT
DEFAULT
NULL
COMMENT
'失败原因'
,
`start_time`
DATETIME
(
3
)
DEFAULT
NULL
COMMENT
'开始时间'
,
`end_time`
DATETIME
(
3
)
DEFAULT
NULL
COMMENT
'结束时间'
,
`duration_ms`
BIGINT
DEFAULT
NULL
COMMENT
'耗时毫秒'
,
PRIMARY
KEY
(
`id`
),
KEY
`idx_item_sync_log_start_time`
(
`start_time`
),
KEY
`idx_item_sync_log_status`
(
`status`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
COMMENT
=
'乐檬→汉尼同步任务日志'
;
-- ----------------------------
-- 商品快照(汉尼字段 + 乐檬最后修改时间,用于跳过未变化)
-- ----------------------------
CREATE
TABLE
IF
NOT
EXISTS
`item_sync_snapshot`
(
`id`
BIGINT
NOT
NULL
AUTO_INCREMENT
COMMENT
'主键'
,
`barcode`
VARCHAR
(
64
)
NOT
NULL
COMMENT
'条码,唯一'
,
`gid`
BIGINT
DEFAULT
NULL
COMMENT
'商品编码'
,
`name`
VARCHAR
(
512
)
DEFAULT
NULL
,
`spec`
VARCHAR
(
255
)
DEFAULT
NULL
,
`saleunit`
VARCHAR
(
64
)
DEFAULT
NULL
,
`price`
DECIMAL
(
18
,
4
)
DEFAULT
NULL
,
`retailprice`
DECIMAL
(
18
,
4
)
DEFAULT
NULL
,
`parea`
VARCHAR
(
255
)
DEFAULT
NULL
,
`isweight`
VARCHAR
(
8
)
DEFAULT
NULL
,
`packratio`
VARCHAR
(
64
)
DEFAULT
NULL
,
`grade`
VARCHAR
(
64
)
DEFAULT
NULL
,
`model`
VARCHAR
(
128
)
DEFAULT
NULL
,
`lemon_last_modified`
VARCHAR
(
64
)
DEFAULT
NULL
COMMENT
'乐檬最后修改时间(原始字符串)'
,
`updated_at`
DATETIME
(
3
)
DEFAULT
NULL
COMMENT
'本行更新时间'
,
PRIMARY
KEY
(
`id`
),
UNIQUE
KEY
`uk_item_sync_snapshot_barcode`
(
`barcode`
),
KEY
`idx_snapshot_lemon_mod`
(
`lemon_last_modified`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
COMMENT
=
'商品同步快照'
;
-- ----------------------------
-- 单次同步商品明细
-- ----------------------------
CREATE
TABLE
IF
NOT
EXISTS
`item_sync_detail`
(
`id`
BIGINT
NOT
NULL
AUTO_INCREMENT
COMMENT
'主键'
,
`sync_log_id`
BIGINT
NOT
NULL
COMMENT
'关联 item_sync_log.id'
,
`barcode`
VARCHAR
(
64
)
DEFAULT
NULL
,
`gid`
BIGINT
DEFAULT
NULL
,
`name`
VARCHAR
(
512
)
DEFAULT
NULL
,
`action`
VARCHAR
(
32
)
DEFAULT
NULL
COMMENT
'ADD/UPDATE/SKIP_TIME/SKIP_NO_BARCODE'
,
`lemon_last_modified`
VARCHAR
(
64
)
DEFAULT
NULL
COMMENT
'本次乐檬修改时间'
,
`stored_lemon_modified`
VARCHAR
(
64
)
DEFAULT
NULL
COMMENT
'快照中上次时间'
,
`success`
TINYINT
(
1
)
DEFAULT
NULL
COMMENT
'是否成功(批量接口时为同一摘要)'
,
`remark`
VARCHAR
(
500
)
DEFAULT
NULL
,
`created_at`
DATETIME
(
3
)
DEFAULT
NULL
,
PRIMARY
KEY
(
`id`
),
KEY
`idx_detail_sync_log_id`
(
`sync_log_id`
),
KEY
`idx_detail_log_barcode`
(
`sync_log_id`
,
`barcode`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
COMMENT
=
'同步任务商品明细'
;
-- ----------------------------
-- 旧版 MD5 变更缓存(当前逻辑已改用 snapshot,可不再使用;历史数据可保留)
-- ----------------------------
CREATE
TABLE
IF
NOT
EXISTS
`item_sync_cache`
(
`id`
BIGINT
NOT
NULL
AUTO_INCREMENT
,
`barcode`
VARCHAR
(
64
)
NOT
NULL
,
`content_hash`
VARCHAR
(
64
)
DEFAULT
NULL
,
`update_time`
DATETIME
(
3
)
DEFAULT
NULL
,
PRIMARY
KEY
(
`id`
),
UNIQUE
KEY
`uk_item_sync_cache_barcode`
(
`barcode`
),
KEY
`idx_item_sync_cache_barcode`
(
`barcode`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
COMMENT
=
'商品同步缓存(旧)'
;
-- ----------------------------
-- 乐檬 OAuth Token 持久化(与 JPA 实体 LemengOAuthToken 对应;服务重启从库加载)
-- ----------------------------
CREATE
TABLE
IF
NOT
EXISTS
`lemeng_oauth_token`
(
`system_book_code`
VARCHAR
(
64
)
NOT
NULL
COMMENT
'账套号,主键'
,
`access_token`
TEXT
NOT
NULL
COMMENT
'访问令牌'
,
`refresh_token`
TEXT
DEFAULT
NULL
COMMENT
'刷新令牌'
,
`expires_at`
DATETIME
(
3
)
DEFAULT
NULL
COMMENT
'access 预计过期时间'
,
`updated_at`
DATETIME
(
3
)
DEFAULT
NULL
COMMENT
'更新时间'
,
PRIMARY
KEY
(
`system_book_code`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
COMMENT
=
'乐檬 OAuth Token(重启从库加载)'
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment