feat: 添加企业微信用户ID缓存功能
- 新增qyUseridCache用于缓存企业微信用户ID - 调整缓存过期时间为10小时 - 在登录服务中添加缓存逻辑 - 修复机柜模板枚举值错误 - 完善智能柜删除逻辑,同时删除关联数据 - 优化逾期商品检测逻辑,支持自定义逾期天数 - 添加智能柜相关SQL表结构文档
This commit is contained in:
parent
8c29745228
commit
ddc3c914b7
|
|
@ -110,19 +110,12 @@ public class QywxMessageJob {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 筛选createTime超过一周的记录
|
// 5. 筛选逾期记录
|
||||||
Date oneWeekAgo = DateUtil.offsetDay(new Date(), -7);
|
List<ShopOrderGoodsEntity> overdueRecords = new ArrayList<>();
|
||||||
List<ShopOrderGoodsEntity> overdueRecords = unReturnOrderGoods.stream()
|
for (ShopOrderGoodsEntity record : unReturnOrderGoods) {
|
||||||
.filter(record -> record.getCreateTime().before(oneWeekAgo))
|
// 获取逾期天数
|
||||||
.collect(Collectors.toList());
|
int overdueDays = 7; // 默认一周
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(overdueRecords)) {
|
|
||||||
log.info("企业[{}]没有超过一周未归还的商品记录", authCorpInfo.getCorpid());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. 遍历逾期记录发送消息
|
|
||||||
for (ShopOrderGoodsEntity record : overdueRecords) {
|
|
||||||
if (record.getCellId() != null) {
|
if (record.getCellId() != null) {
|
||||||
CabinetCellEntity cell = cabinetCellService.getById(record.getCellId());
|
CabinetCellEntity cell = cabinetCellService.getById(record.getCellId());
|
||||||
if (cell == null) {
|
if (cell == null) {
|
||||||
|
|
@ -136,12 +129,36 @@ public class QywxMessageJob {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否为购买订单,如果是则跳过
|
||||||
if (record.getMode().equals(0) && cabinet.getMode().equals(0)
|
if (record.getMode().equals(0) && cabinet.getMode().equals(0)
|
||||||
&& cabinet.getReturnDeadline() != null && cabinet.getReturnDeadline() > 0) {
|
&& cabinet.getReturnDeadline() != null && cabinet.getReturnDeadline() > 0) {
|
||||||
log.info("订单[{}]为购买订单,无需发送逾期提醒", record.getOrderId());
|
log.info("订单[{}]为购买订单,无需发送逾期提醒", record.getOrderId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据智能柜的归还期限设置逾期天数
|
||||||
|
if (cabinet.getReturnDeadline() != null && cabinet.getReturnDeadline() > 0) {
|
||||||
|
overdueDays = cabinet.getReturnDeadline();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算逾期截止日期
|
||||||
|
Date deadlineDate = DateUtil.offsetDay(record.getCreateTime(), overdueDays);
|
||||||
|
Date now = new Date();
|
||||||
|
|
||||||
|
// 如果当前时间晚于逾期截止日期,则商品已逾期
|
||||||
|
if (now.after(deadlineDate)) {
|
||||||
|
overdueRecords.add(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(overdueRecords)) {
|
||||||
|
log.info("企业[{}]没有逾期未归还的商品记录", authCorpInfo.getCorpid());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 遍历逾期记录发送消息
|
||||||
|
for (ShopOrderGoodsEntity record : overdueRecords) {
|
||||||
sendSingleReminder(accessToken.getAccessToken(), authCorpInfo, record);
|
sendSingleReminder(accessToken.getAccessToken(), authCorpInfo, record);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,16 @@ public class LoginService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getQyUserid(String corpid, String code) {
|
private String getQyUserid(String corpid, String code) {
|
||||||
|
// 构建缓存键
|
||||||
|
String cacheKey = corpid + ":" + code;
|
||||||
|
|
||||||
|
// 先从缓存获取
|
||||||
|
String cachedUserid = caffeineCache.qyUseridCache.get(cacheKey);
|
||||||
|
if (cachedUserid != null) {
|
||||||
|
log.debug("从缓存获取企业微信用户ID,corpid: {}, code: {}, userid: {}", corpid, code, cachedUserid);
|
||||||
|
return cachedUserid;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
QyAuthCorpInfoEntity authCorpInfo = authCorpInfoApplicationService.selectByCorpid(corpid);
|
QyAuthCorpInfoEntity authCorpInfo = authCorpInfoApplicationService.selectByCorpid(corpid);
|
||||||
if (authCorpInfo == null) {
|
if (authCorpInfo == null) {
|
||||||
|
|
@ -281,7 +291,13 @@ public class LoginService {
|
||||||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "无效的code参数");
|
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "无效的code参数");
|
||||||
}
|
}
|
||||||
|
|
||||||
return String.valueOf(result.get("userid"));
|
String userid = String.valueOf(result.get("userid"));
|
||||||
|
|
||||||
|
// 将结果存入缓存
|
||||||
|
caffeineCache.qyUseridCache.put(cacheKey, userid);
|
||||||
|
log.debug("缓存企业微信用户ID,corpid: {}, code: {}, userid: {}", corpid, code, userid);
|
||||||
|
|
||||||
|
return userid;
|
||||||
} catch (RestClientException e) {
|
} catch (RestClientException e) {
|
||||||
log.error("获取openid失败", e);
|
log.error("获取openid失败", e);
|
||||||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "微信服务调用失败");
|
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "微信服务调用失败");
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public enum CabinetTemplateEnum {
|
||||||
/** 4口机柜模板,1块主板,每块主板4个单元格 */
|
/** 4口机柜模板,1块主板,每块主板4个单元格 */
|
||||||
CABINET_4(9, "cabinet_4.jpg","4口机柜", 1, 4),
|
CABINET_4(9, "cabinet_4.jpg","4口机柜", 1, 4),
|
||||||
/** 10口机柜模板,1块主板,每块主板10个单元格 */
|
/** 10口机柜模板,1块主板,每块主板10个单元格 */
|
||||||
CABINET_10(1, "cabinet_16.jpg", "10口机柜", 1, 10);
|
CABINET_10(10, "cabinet_16.jpg", "10口机柜", 1, 10);
|
||||||
|
|
||||||
/** 模板代码 */
|
/** 模板代码 */
|
||||||
private final int code;
|
private final int code;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import com.agileboot.domain.cabinet.cell.db.CabinetCellService;
|
||||||
import com.agileboot.domain.cabinet.cell.model.CabinetCellModel;
|
import com.agileboot.domain.cabinet.cell.model.CabinetCellModel;
|
||||||
import com.agileboot.domain.cabinet.cell.model.CabinetCellModelFactory;
|
import com.agileboot.domain.cabinet.cell.model.CabinetCellModelFactory;
|
||||||
import com.agileboot.domain.cabinet.mainboard.command.AddCabinetMainboardCommand;
|
import com.agileboot.domain.cabinet.mainboard.command.AddCabinetMainboardCommand;
|
||||||
|
import com.agileboot.domain.cabinet.mainboard.db.CabinetMainboardEntity;
|
||||||
|
import com.agileboot.domain.cabinet.mainboard.db.CabinetMainboardService;
|
||||||
import com.agileboot.domain.cabinet.mainboard.model.CabinetMainboardModel;
|
import com.agileboot.domain.cabinet.mainboard.model.CabinetMainboardModel;
|
||||||
import com.agileboot.domain.cabinet.mainboard.model.CabinetMainboardModelFactory;
|
import com.agileboot.domain.cabinet.mainboard.model.CabinetMainboardModelFactory;
|
||||||
import com.agileboot.domain.cabinet.smartCabinet.db.SmartCabinetDO;
|
import com.agileboot.domain.cabinet.smartCabinet.db.SmartCabinetDO;
|
||||||
|
|
@ -43,6 +45,7 @@ public class SmartCabinetApplicationService {
|
||||||
private final SmartCabinetService smartCabinetService;
|
private final SmartCabinetService smartCabinetService;
|
||||||
private final SmartCabinetModelFactory smartCabinetModelFactory;
|
private final SmartCabinetModelFactory smartCabinetModelFactory;
|
||||||
private final CabinetCellService cabinetCellService;
|
private final CabinetCellService cabinetCellService;
|
||||||
|
private final CabinetMainboardService cabinetMainboardService;
|
||||||
private final ShopGoodsService shopGoodsService;
|
private final ShopGoodsService shopGoodsService;
|
||||||
private final ShopService shopService;
|
private final ShopService shopService;
|
||||||
private final CabinetMainboardModelFactory cabinetMainboardModelFactory;
|
private final CabinetMainboardModelFactory cabinetMainboardModelFactory;
|
||||||
|
|
@ -138,6 +141,17 @@ public class SmartCabinetApplicationService {
|
||||||
|
|
||||||
public void deleteSmartCabinet(BulkOperationCommand<Long> command) {
|
public void deleteSmartCabinet(BulkOperationCommand<Long> command) {
|
||||||
for (Long cabinetId : command.getIds()) {
|
for (Long cabinetId : command.getIds()) {
|
||||||
|
// 先删除相关的 cabinet_cell 数据
|
||||||
|
QueryWrapper<CabinetCellEntity> cellWrapper = new QueryWrapper<>();
|
||||||
|
cellWrapper.eq("cabinet_id", cabinetId);
|
||||||
|
cabinetCellService.remove(cellWrapper);
|
||||||
|
|
||||||
|
// 再删除相关的 cabinet_mainboard 数据
|
||||||
|
QueryWrapper<CabinetMainboardEntity> mainboardWrapper = new QueryWrapper<>();
|
||||||
|
mainboardWrapper.eq("cabinet_id", cabinetId);
|
||||||
|
cabinetMainboardService.remove(mainboardWrapper);
|
||||||
|
|
||||||
|
// 最后删除智能柜本身
|
||||||
SmartCabinetModel model = smartCabinetModelFactory.loadById(cabinetId);
|
SmartCabinetModel model = smartCabinetModelFactory.loadById(cabinetId);
|
||||||
model.deleteById();
|
model.deleteById();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ public class CacheCenter {
|
||||||
|
|
||||||
public static AbstractCaffeineCacheTemplate<SysPostEntity> postCache;
|
public static AbstractCaffeineCacheTemplate<SysPostEntity> postCache;
|
||||||
|
|
||||||
|
public static AbstractCaffeineCacheTemplate<String> qyUseridCache;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
GuavaCacheService guavaCache = SpringUtil.getBean(GuavaCacheService.class);
|
GuavaCacheService guavaCache = SpringUtil.getBean(GuavaCacheService.class);
|
||||||
|
|
@ -47,6 +49,7 @@ public class CacheCenter {
|
||||||
userCache = caffeineCache.userCache;
|
userCache = caffeineCache.userCache;
|
||||||
roleCache = caffeineCache.roleCache;
|
roleCache = caffeineCache.roleCache;
|
||||||
postCache = caffeineCache.postCache;
|
postCache = caffeineCache.postCache;
|
||||||
|
qyUseridCache = caffeineCache.qyUseridCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,14 @@ public class CaffeineCacheService {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public AbstractCaffeineCacheTemplate<String> qyUseridCache = new AbstractCaffeineCacheTemplate<String>() {
|
||||||
|
@Override
|
||||||
|
public String getObjectFromDb(Object id) {
|
||||||
|
// 企业微信用户ID需要通过API获取,这里返回null,由调用方处理
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取缓存统计信息
|
* 获取缓存统计信息
|
||||||
* @return 统计信息字符串
|
* @return 统计信息字符串
|
||||||
|
|
@ -73,6 +81,7 @@ public class CaffeineCacheService {
|
||||||
stats.append("User Cache: ").append(userCache.getStats()).append("\n");
|
stats.append("User Cache: ").append(userCache.getStats()).append("\n");
|
||||||
stats.append("Role Cache: ").append(roleCache.getStats()).append("\n");
|
stats.append("Role Cache: ").append(roleCache.getStats()).append("\n");
|
||||||
stats.append("Post Cache: ").append(postCache.getStats()).append("\n");
|
stats.append("Post Cache: ").append(postCache.getStats()).append("\n");
|
||||||
|
stats.append("QyUserid Cache: ").append(qyUseridCache.getStats()).append("\n");
|
||||||
return stats.toString();
|
return stats.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,7 +32,9 @@ public class ShopApplicationService {
|
||||||
private final CabinetCellService cabinetCellService;
|
private final CabinetCellService cabinetCellService;
|
||||||
|
|
||||||
public PageDTO<ShopDTO> getShopPage(SearchShopQuery<ShopEntity> query) {
|
public PageDTO<ShopDTO> getShopPage(SearchShopQuery<ShopEntity> query) {
|
||||||
Page<ShopEntity> page = shopService.getShopList(query.toPage(), query.toQueryWrapper());
|
QueryWrapper<ShopEntity> queryWrapper = query.toQueryWrapper();
|
||||||
|
queryWrapper.eq("s.deleted", false);
|
||||||
|
Page<ShopEntity> page = shopService.getShopList(query.toPage(), queryWrapper);
|
||||||
List<ShopDTO> dtoList = page.getRecords().stream()
|
List<ShopDTO> dtoList = page.getRecords().stream()
|
||||||
.map(ShopDTO::new)
|
.map(ShopDTO::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
@ -40,7 +42,10 @@ public class ShopApplicationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ShopDTO> getShopList(SearchShopQuery<ShopEntity> query) {
|
public List<ShopDTO> getShopList(SearchShopQuery<ShopEntity> query) {
|
||||||
List<ShopEntity> list = shopService.list();
|
// 1. 先查询所有商店
|
||||||
|
QueryWrapper<ShopEntity> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("deleted", false);
|
||||||
|
List<ShopEntity> list = shopService.list(queryWrapper);
|
||||||
return list.stream()
|
return list.stream()
|
||||||
.map(ShopDTO::new)
|
.map(ShopDTO::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@ public abstract class AbstractCaffeineCacheTemplate<T> {
|
||||||
// 设置软引用值
|
// 设置软引用值
|
||||||
.softValues()
|
.softValues()
|
||||||
// 设置过期时间 - 最后一次写入后经过固定时间过期
|
// 设置过期时间 - 最后一次写入后经过固定时间过期
|
||||||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
.expireAfterWrite(10, TimeUnit.HOURS)
|
||||||
// 设置刷新时间 - 写入后经过固定时间刷新
|
// 设置刷新时间 - 写入后经过固定时间刷新
|
||||||
.refreshAfterWrite(5, TimeUnit.MINUTES)
|
.refreshAfterWrite(10, TimeUnit.HOURS)
|
||||||
// 所有segment的初始总容量大小
|
// 所有segment的初始总容量大小
|
||||||
.initialCapacity(128)
|
.initialCapacity(128)
|
||||||
// 开启缓存统计
|
// 开启缓存统计
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
-- `agileboot-pure`.smart_cabinet definition
|
||||||
|
|
||||||
|
CREATE TABLE `smart_cabinet` (
|
||||||
|
`cabinet_id` bigint NOT NULL AUTO_INCREMENT COMMENT '柜机唯一ID',
|
||||||
|
`cabinet_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '柜机名称',
|
||||||
|
`cabinet_type` tinyint NOT NULL DEFAULT '0' COMMENT '柜机类型(0主柜 1副柜)',
|
||||||
|
`main_cabinet` bigint DEFAULT NULL COMMENT '归属主柜ID',
|
||||||
|
`balance_enable` tinyint NOT NULL DEFAULT '1' COMMENT '借呗支付(1-正常使用 0-禁止使用)',
|
||||||
|
`mode` tinyint NOT NULL DEFAULT '0' COMMENT '运行模式(0-支付模式 1-审批模式 2-借还模式 3-会员模式)',
|
||||||
|
`belong_type` tinyint NOT NULL DEFAULT '0' COMMENT '归属类型(0-借还柜 1-固资通)',
|
||||||
|
`shop_id` bigint DEFAULT NULL COMMENT '归属商店ID',
|
||||||
|
`mqtt_server_id` bigint DEFAULT NULL COMMENT 'MQTT服务ID',
|
||||||
|
`template_no` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '柜机模版编号',
|
||||||
|
`lock_control_no` int NOT NULL COMMENT '锁控板序号',
|
||||||
|
`location` int NOT NULL COMMENT '柜机位置',
|
||||||
|
`creator_id` bigint NOT NULL DEFAULT '0' COMMENT '创建者ID',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`updater_id` bigint NOT NULL DEFAULT '0' COMMENT '更新者ID',
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0存在 1删除)',
|
||||||
|
`return_deadline` int NOT NULL DEFAULT '0' COMMENT '归还期限(天),0表示不限制',
|
||||||
|
PRIMARY KEY (`cabinet_id`),
|
||||||
|
KEY `idx_template_no` (`template_no`),
|
||||||
|
KEY `idx_location` (`location`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='智能柜信息表';
|
||||||
|
|
||||||
|
|
||||||
|
-- `agileboot-pure`.cabinet_mainboard definition
|
||||||
|
|
||||||
|
CREATE TABLE `cabinet_mainboard` (
|
||||||
|
`mainboard_id` bigint NOT NULL AUTO_INCREMENT COMMENT '主板唯一ID',
|
||||||
|
`cabinet_id` bigint NOT NULL COMMENT '关联柜机ID',
|
||||||
|
`lock_control_no` int NOT NULL COMMENT '锁控板序号',
|
||||||
|
`creator_id` bigint DEFAULT '0' COMMENT '创建者ID',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`updater_id` bigint DEFAULT '0' COMMENT '更新者ID',
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0存在 1删除)',
|
||||||
|
PRIMARY KEY (`mainboard_id`),
|
||||||
|
KEY `idx_cabinet` (`cabinet_id`),
|
||||||
|
CONSTRAINT `fk_mainboard_cabinet` FOREIGN KEY (`cabinet_id`) REFERENCES `smart_cabinet` (`cabinet_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='机柜主板信息表';
|
||||||
|
|
||||||
|
|
||||||
|
-- `agileboot-pure`.cabinet_cell definition
|
||||||
|
|
||||||
|
CREATE TABLE `cabinet_cell` (
|
||||||
|
`cell_id` bigint NOT NULL AUTO_INCREMENT COMMENT '格口唯一ID',
|
||||||
|
`cabinet_id` bigint NOT NULL COMMENT '关联柜机ID',
|
||||||
|
`mainboard_id` bigint DEFAULT NULL COMMENT '归属主板ID',
|
||||||
|
`goods_id` bigint DEFAULT NULL COMMENT '关联商品ID',
|
||||||
|
`cell_no` int NOT NULL COMMENT '格口号',
|
||||||
|
`pin_no` int NOT NULL COMMENT '针脚序号',
|
||||||
|
`stock` int NOT NULL DEFAULT '0' COMMENT '库存数量',
|
||||||
|
`cell_price` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '格口租用价格',
|
||||||
|
`is_rented` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已租用:0-未租用,1-已租用',
|
||||||
|
`cell_type` tinyint NOT NULL DEFAULT '1' COMMENT '格口类型(1小格 2中格 3大格 4超大格)',
|
||||||
|
`usage_status` tinyint NOT NULL DEFAULT '1' COMMENT '使用状态(1空闲 2已占用)',
|
||||||
|
`available_status` tinyint NOT NULL DEFAULT '1' COMMENT '可用状态(1正常 2故障)',
|
||||||
|
`creator_id` bigint NOT NULL DEFAULT '0' COMMENT '创建者ID',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`updater_id` bigint NOT NULL DEFAULT '0' COMMENT '更新者ID',
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0存在 1删除)',
|
||||||
|
PRIMARY KEY (`cell_id`),
|
||||||
|
KEY `idx_cabinet` (`cabinet_id`),
|
||||||
|
KEY `idx_usage_status` (`usage_status`),
|
||||||
|
KEY `idx_available_status` (`available_status`),
|
||||||
|
KEY `idx_goods` (`goods_id`),
|
||||||
|
CONSTRAINT `fk_cell_cabinet` FOREIGN KEY (`cabinet_id`) REFERENCES `smart_cabinet` (`cabinet_id`),
|
||||||
|
CONSTRAINT `fk_cell_goods` FOREIGN KEY (`goods_id`) REFERENCES `shop_goods` (`goods_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=712 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='柜机格口信息表';
|
||||||
Loading…
Reference in New Issue