Compare commits
25 Commits
2943caf779
...
feature/xu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
720937581f | ||
|
|
261a8b4797 | ||
| c283800915 | |||
| 483abcfd83 | |||
| 4ebe4f9ac6 | |||
| 90e28f056a | |||
| a5a10898a2 | |||
|
|
00d4e0c3e8 | ||
| 4042fd297d | |||
|
|
0ce1eae772 | ||
|
|
3497962627 | ||
|
|
15e801e426 | ||
|
|
b2e0cca804 | ||
| 22b96b6feb | |||
| fc62fa3167 | |||
| 190e0e1605 | |||
| 3fbb1383fd | |||
| 191eadbf77 | |||
|
|
7fdf546585 | ||
| b6630f3f61 | |||
| f7d4ef8e4c | |||
|
|
ef99dbe035 | ||
| e5f0d57286 | |||
| de062744b4 | |||
| 4ae13cf1e6 |
@@ -1,51 +0,0 @@
|
||||
-- 会员用户表 (tz_member_user)
|
||||
CREATE TABLE `tz_member_user` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
|
||||
`mobile` varchar(11) NOT NULL COMMENT '手机',
|
||||
`password` varchar(128) NOT NULL COMMENT '加密后的密码',
|
||||
`status` tinyint(4) NOT NULL COMMENT '帐号状态 (枚举 CommonStatusEnum)',
|
||||
`register_ip` varchar(32) DEFAULT NULL COMMENT '注册 IP',
|
||||
`register_terminal` tinyint(4) DEFAULT NULL COMMENT '注册终端 (枚举 TerminalEnum)',
|
||||
`login_ip` varchar(32) DEFAULT NULL COMMENT '最后登录IP',
|
||||
`login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
|
||||
`nickname` varchar(64) DEFAULT NULL COMMENT '用户昵称',
|
||||
`avatar` varchar(512) DEFAULT NULL COMMENT '用户头像',
|
||||
`name` varchar(64) DEFAULT NULL COMMENT '真实名字',
|
||||
`sex` tinyint(4) DEFAULT NULL COMMENT '性别 (枚举 SexEnum)',
|
||||
`birthday` datetime DEFAULT NULL COMMENT '出生日期',
|
||||
`area_id` int(11) DEFAULT NULL COMMENT '所在地 (关联 Area.id 字段)',
|
||||
`mark` varchar(512) DEFAULT NULL COMMENT '用户备注',
|
||||
`point` int(11) DEFAULT NULL COMMENT '积分',
|
||||
`tag_ids` varchar(512) DEFAULT NULL COMMENT '会员标签列表,以逗号分隔',
|
||||
`level_id` bigint(20) DEFAULT NULL COMMENT '会员级别编号 (关联 MemberLevelDO.id 字段)',
|
||||
`experience` int(11) DEFAULT NULL COMMENT '会员经验',
|
||||
`group_id` bigint(20) DEFAULT NULL COMMENT '用户分组编号 (关联 MemberGroupDO.id 字段)',
|
||||
`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_mobile` (`mobile`),
|
||||
KEY `idx_level_id` (`level_id`),
|
||||
KEY `idx_group_id` (`group_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员用户表';
|
||||
|
||||
-- 用户收件地址表 (tz_member_address)
|
||||
CREATE TABLE `tz_member_address` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`name` varchar(64) NOT NULL COMMENT '收件人名称',
|
||||
`mobile` varchar(11) NOT NULL COMMENT '手机号',
|
||||
`area_id` bigint(20) NOT NULL COMMENT '地区编号',
|
||||
`detail_address` varchar(512) NOT NULL COMMENT '收件详细地址',
|
||||
`default_status` tinyint(1) DEFAULT NULL COMMENT '是否默认 (true - 默认收件地址)',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_user_id` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户收件地址表';
|
||||
@@ -1,266 +1,326 @@
|
||||
-- 基础实体表结构 (BaseDO) 不单独建表,字段会被继承到其他表中
|
||||
|
||||
-- 交易订单表 (trade_order)
|
||||
CREATE TABLE `tz_trade_order`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单编号,主键自增',
|
||||
`order_num` varchar(64) NOT NULL COMMENT '订单流水号',
|
||||
`order_type` tinyint(4) NOT NULL COMMENT '订单类型 (枚举 TradeOrderTypeEnum)',
|
||||
`order_terminal` tinyint(4) NOT NULL COMMENT '订单来源 (枚举 TerminalEnum)',
|
||||
`order_status` tinyint(4) NOT NULL COMMENT '订单状态 (枚举 TradeOrderStatusEnum)',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`user_ip` varchar(64) DEFAULT NULL COMMENT '用户IP',
|
||||
`user_remark` varchar(512) DEFAULT NULL COMMENT '用户备注',
|
||||
`finish_time` datetime DEFAULT NULL COMMENT '订单完成时间',
|
||||
`cancel_time` datetime DEFAULT NULL COMMENT '订单取消时间',
|
||||
`cancel_type` tinyint(4) DEFAULT NULL COMMENT '取消类型 (枚举 TradeOrderCancelTypeEnum)',
|
||||
`merchant_remark` varchar(512) DEFAULT NULL COMMENT '商家备注',
|
||||
`comment_status` tinyint(1) DEFAULT NULL COMMENT '是否评价 (true-已评价, false-未评价)',
|
||||
`total_price` int(11) NOT NULL COMMENT '商品原价,单位:分',
|
||||
`discount_price` int(11) NOT NULL COMMENT '优惠金额,单位:分',
|
||||
`delivery_price` int(11) NOT NULL COMMENT '运费金额,单位:分',
|
||||
`adjust_price` int(11) NOT NULL COMMENT '订单调价,单位:分',
|
||||
`pay_price` int(11) NOT NULL COMMENT '应付金额(总),单位:分',
|
||||
`pay_order_id` bigint(20) DEFAULT NULL COMMENT '支付订单编号',
|
||||
`pay_status` tinyint(1) NOT NULL COMMENT '是否已支付 (true-已支付, false-未支付)',
|
||||
`pay_time` datetime DEFAULT NULL COMMENT '付款时间',
|
||||
`pay_channel_code` varchar(64) DEFAULT NULL COMMENT '支付渠道',
|
||||
`delivery_type` tinyint(4) NOT NULL COMMENT '配送方式 (枚举 DeliveryTypeEnum)',
|
||||
`logistics_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '发货物流公司编号',
|
||||
`logistics_no` varchar(64) DEFAULT '' COMMENT '发货物流单号',
|
||||
`delivery_time` datetime DEFAULT NULL COMMENT '发货时间',
|
||||
`receive_time` datetime DEFAULT NULL COMMENT '收货时间',
|
||||
`receiver_name` varchar(64) NOT NULL COMMENT '收件人名称',
|
||||
`receiver_mobile` varchar(20) NOT NULL COMMENT '收件人手机',
|
||||
`receiver_area_id` int(11) NOT NULL COMMENT '收件人地区编号',
|
||||
`receiver_detail_address` varchar(512) NOT NULL COMMENT '收件人详细地址',
|
||||
`pick_up_store_id` bigint(20) DEFAULT NULL COMMENT '自提门店编号',
|
||||
`pick_up_verify_code` varchar(64) DEFAULT NULL COMMENT '自提核销码',
|
||||
`refund_status` tinyint(4) NOT NULL COMMENT '退款状态 (枚举 TradeOrderRefundStatusEnum)',
|
||||
`refund_price` int(11) NOT NULL COMMENT '退款金额,单位:分',
|
||||
`after_sale_id` bigint(20) DEFAULT NULL COMMENT '售后单编号',
|
||||
`after_sale_status` tinyint(4) NOT NULL COMMENT '售后状态 (枚举 TradeOrderItemAfterSaleStatusEnum)',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单编号,主键自增',
|
||||
`order_num` varchar(64) NOT NULL COMMENT '订单流水号',
|
||||
`order_category_id` bigint NOT NULL COMMENT '订单类目id',
|
||||
`order_category_name` varchar(64) NOT NULL COMMENT '订单类目名称',
|
||||
`order_type` tinyint NOT NULL COMMENT '订单类型 (枚举 TradeOrderTypeEnum)',
|
||||
`order_terminal` tinyint NOT NULL COMMENT '订单来源 (枚举 TerminalEnum)',
|
||||
`order_status` tinyint NOT NULL COMMENT '订单状态 (枚举 TradeOrderStatusEnum)',
|
||||
`user_id` bigint NOT NULL COMMENT '用户编号',
|
||||
`user_ip` varchar(64) DEFAULT NULL COMMENT '用户IP',
|
||||
`user_name` varchar(64) DEFAULT NULL COMMENT '用户昵称',
|
||||
`user_mobile` varchar(11) DEFAULT NULL COMMENT '用户手机号',
|
||||
`user_remark` varchar(512) DEFAULT NULL COMMENT '用户备注',
|
||||
`finish_time` datetime DEFAULT NULL COMMENT '订单完成时间',
|
||||
`cancel_time` datetime DEFAULT NULL COMMENT '订单取消时间',
|
||||
`cancel_type` tinyint DEFAULT NULL COMMENT '取消类型 (枚举 TradeOrderCancelTypeEnum)',
|
||||
`cancel_reason` varchar(128) DEFAULT NULL COMMENT '取消原因',
|
||||
`merchant_id` bigint DEFAULT NULL COMMENT '商家编号',
|
||||
`merchant_name` varchar(64) DEFAULT NULL COMMENT '商家名称',
|
||||
`merchant_remark` varchar(512) DEFAULT NULL COMMENT '商家备注',
|
||||
`comment_status` tinyint(1) DEFAULT NULL COMMENT '是否评价 (true-已评价, false-未评价)',
|
||||
`sub_type` tinyint(1) NOT NULL DEFAULT 1 COMMENT '预约类型(1预约 2 加急)',
|
||||
`sub_time` datetime NOT NULL COMMENT '预约时间',
|
||||
`expense_price` int(11) DEFAULT NULL COMMENT '商品成本(单),单位:分',
|
||||
`price` int(11) DEFAULT NULL COMMENT '商品原价(单),单位:分',
|
||||
`discount_price` int(11) DEFAULT NULL COMMENT '优惠金额(总),单位:分',
|
||||
`delivery_price` int(11) DEFAULT NULL COMMENT '运费金额(总),单位:分',
|
||||
`adjust_price` int(11) DEFAULT NULL COMMENT '订单调价(总),单位:分',
|
||||
`pay_price` int(11) DEFAULT NULL COMMENT '应付金额(总),单位:分',
|
||||
`live_price` int(11) DEFAULT NULL COMMENT '实收金额(总),单位:分',
|
||||
`pay_order_id` bigint DEFAULT NULL COMMENT '支付订单编号',
|
||||
`pay_status` tinyint(1) DEFAULT NULL COMMENT '是否已支付 (true-已支付, false-未支付)',
|
||||
`pay_type` tinyint DEFAULT NULL COMMENT '支付方式(PayTypeEnum)',
|
||||
`pay_time` datetime DEFAULT NULL COMMENT '付款时间',
|
||||
`pay_channel_code` tinyint DEFAULT NULL COMMENT '支付渠道(PayTypeEnum)',
|
||||
`delivery_type` tinyint DEFAULT NULL COMMENT '配送方式 (枚举 DeliveryTypeEnum)',
|
||||
`logistics_id` bigint DEFAULT '0' COMMENT '发货物流公司编号',
|
||||
`logistics_no` varchar(64) DEFAULT '' COMMENT '发货物流单号',
|
||||
`delivery_time` datetime DEFAULT NULL COMMENT '发货时间',
|
||||
`receive_time` datetime DEFAULT NULL COMMENT '收货时间',
|
||||
`receiver_name` varchar(64) DEFAULT NULL COMMENT '收件人名称',
|
||||
`receiver_mobile` varchar(20) DEFAULT NULL COMMENT '收件人手机',
|
||||
`receiver_area_id` int DEFAULT NULL COMMENT '收件人地区编号',
|
||||
`receiver_detail_address` varchar(512) DEFAULT NULL COMMENT '收件人详细地址',
|
||||
`pick_up_store_id` bigint DEFAULT NULL COMMENT '自提门店编号',
|
||||
`pick_up_verify_code` varchar(64) DEFAULT NULL COMMENT '自提核销码',
|
||||
`refund_status` tinyint DEFAULT NULL COMMENT '退款状态 (枚举 TradeOrderRefundStatusEnum)',
|
||||
`refund_price` int DEFAULT NULL COMMENT '退款金额,单位:分',
|
||||
`refund_time` datetime DEFAULT NULL COMMENT '退款时间',
|
||||
`after_sale_id` bigint DEFAULT NULL COMMENT '售后单编号',
|
||||
`after_sale_status` tinyint DEFAULT NULL COMMENT '售后状态 (枚举 TradeOrderItemAfterSaleStatusEnum)',
|
||||
`finance_id` bigint DEFAULT NULL COMMENT '财务单编号',
|
||||
`finance_status` tinyint DEFAULT NULL COMMENT '财务状态 (枚举 TradeOrderItemFinanceEnum)',
|
||||
`version` int NOT NULL DEFAULT '0' COMMENT '版本号(乐观锁)',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) DEFAULT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) DEFAULT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_order_num` (`order_num`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_status` (`order_status`),
|
||||
KEY `idx_pay_status` (`pay_status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易订单表';
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_status` (`order_status`),
|
||||
KEY `idx_pay_status` (`pay_status`)
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 2
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci COMMENT ='交易订单表';
|
||||
|
||||
|
||||
-- 交易订单项表 (trade_order_item)
|
||||
CREATE TABLE `tz_trade_order_item`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`order_id` bigint(20) NOT NULL COMMENT '订单编号',
|
||||
`cart_id` bigint(20) DEFAULT NULL COMMENT '购物车项编号',
|
||||
`prod_id` bigint(20) NOT NULL COMMENT '商品 SPU 编号',
|
||||
`prod_name` varchar(256) NOT NULL COMMENT '商品 SPU 名称',
|
||||
`sku_id` bigint(20) NOT NULL COMMENT '商品 SKU 编号',
|
||||
`properties` json DEFAULT NULL COMMENT '属性数组',
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`order_id` bigint(20) NOT NULL COMMENT '订单编号',
|
||||
`cart_id` bigint(20) DEFAULT NULL COMMENT '购物车项编号',
|
||||
`spu_id` bigint(20) NOT NULL COMMENT '商品 SPU 编号',
|
||||
`spu_name` varchar(256) NOT NULL COMMENT '商品 SPU 名称',
|
||||
`spu_type` tinyint(1) NOT NULL COMMENT '商品类型(1商品 2服务)',
|
||||
`sku_id` bigint(20) NOT NULL COMMENT '商品 SKU 编号',
|
||||
`sku_name` bigint(20) NOT NULL COMMENT '商品 SKU 名称',
|
||||
`pic_url` varchar(512) NOT NULL COMMENT '商品图片',
|
||||
`count` int(11) NOT NULL COMMENT '购买数量',
|
||||
`price` int(11) NOT NULL COMMENT '商品原价(单),单位:分',
|
||||
`discount_price` int(11) NOT NULL COMMENT '优惠金额(总),单位:分',
|
||||
`delivery_price` int(11) NOT NULL COMMENT '运费金额(总),单位:分',
|
||||
`adjust_price` int(11) NOT NULL COMMENT '订单调价(总),单位:分',
|
||||
`pay_price` int(11) NOT NULL COMMENT '应付金额(总),单位:分',
|
||||
`serve_ext_info` json DEFAULT NULL COMMENT '扩展服务信息,存储额外的服务相关数据',
|
||||
`price_ext_info` json DEFAULT NULL COMMENT '附加费信息',
|
||||
`count` int(11) NOT NULL COMMENT '购买数量',
|
||||
`unit` varchar(16) NOT NULL COMMENT '商品单位',
|
||||
`expense_price` int(11) NOT NULL COMMENT '商品成本(单),单位:分',
|
||||
`price` int(11) NOT NULL COMMENT '商品原价(单),单位:分',
|
||||
`discount_price` int(11) NOT NULL COMMENT '优惠金额(总),单位:分',
|
||||
`delivery_price` int(11) NOT NULL COMMENT '运费金额(总),单位:分',
|
||||
`adjust_price` int(11) NOT NULL COMMENT '订单调价(总),单位:分',
|
||||
`pay_price` int(11) NOT NULL COMMENT '应付金额(总),单位:分',
|
||||
`live_price` int(11) NOT NULL COMMENT '实收金额(总),单位:分',
|
||||
|
||||
`serve_address` datetime NOT NULL COMMENT '服务地址',
|
||||
`properties` json DEFAULT NULL COMMENT '属性数组',
|
||||
`serve_info` json DEFAULT NULL COMMENT '服务信息',
|
||||
`serve_ext_info` json DEFAULT NULL COMMENT '扩展服务信息,存储额外的服务相关数据',
|
||||
`price_ext_info` json DEFAULT NULL COMMENT '附加费信息',
|
||||
`version` int(11) DEFAULT '0' COMMENT '版本号(乐观锁)',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_sku_id` (`sku_id`),
|
||||
KEY `idx_user_id` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易订单项表';
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_sku_id` (`sku_id`),
|
||||
KEY `idx_user_id` (`user_id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='交易订单项表';
|
||||
|
||||
|
||||
-- 订单日志表 (trade_order_log)
|
||||
CREATE TABLE `tz_trade_order_log`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`user_type` tinyint(4) NOT NULL COMMENT '用户类型 (枚举 UserTypeEnum)',
|
||||
`order_id` bigint(20) NOT NULL COMMENT '订单号',
|
||||
`before_status` int(11) DEFAULT NULL COMMENT '操作前状态',
|
||||
`after_status` int(11) DEFAULT NULL COMMENT '操作后状态',
|
||||
`operate_type` tinyint(4) NOT NULL COMMENT '操作类型 (枚举 TradeOrderOperateTypeEnum)',
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`user_type` tinyint(4) NOT NULL COMMENT '用户类型 (枚举 UserTypeEnum)',
|
||||
`order_id` bigint(20) NOT NULL COMMENT '订单号',
|
||||
`before_status` int(11) DEFAULT NULL COMMENT '操作前状态',
|
||||
`after_status` int(11) DEFAULT NULL COMMENT '操作后状态',
|
||||
`operate_type` tinyint(4) NOT NULL COMMENT '操作类型 (枚举 TradeOrderOperateTypeEnum)',
|
||||
`content` varchar(1024) NOT NULL COMMENT '订单日志信息',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_user_id` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单日志表';
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_user_id` (`user_id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='订单日志表';
|
||||
|
||||
-- 售后订单表 (tz_trade_after_sale)
|
||||
CREATE TABLE `tz_trade_after_sale` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '售后编号,主键自增',
|
||||
`no` varchar(64) NOT NULL COMMENT '售后单号',
|
||||
`status` tinyint(4) NOT NULL COMMENT '退款状态 (枚举 AfterSaleStatusEnum)',
|
||||
`way` tinyint(4) NOT NULL COMMENT '售后方式 (枚举 AfterSaleWayEnum)',
|
||||
`type` tinyint(4) NOT NULL COMMENT '售后类型 (枚举 AfterSaleTypeEnum)',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`apply_reason` varchar(256) NOT NULL COMMENT '申请原因',
|
||||
`apply_description` varchar(512) DEFAULT NULL COMMENT '补充描述',
|
||||
`apply_pic_urls` json DEFAULT NULL COMMENT '补充凭证图片',
|
||||
`order_id` bigint(20) NOT NULL COMMENT '交易订单编号',
|
||||
`order_no` varchar(64) NOT NULL COMMENT '订单流水号',
|
||||
`order_item_id` bigint(20) NOT NULL COMMENT '交易订单项编号',
|
||||
`prod_id` bigint(20) NOT NULL COMMENT '商品 SPU 编号',
|
||||
`prod_name` varchar(256) NOT NULL COMMENT '商品 SPU 名称',
|
||||
`sku_id` bigint(20) NOT NULL COMMENT '商品 SKU 编号',
|
||||
`properties` json DEFAULT NULL COMMENT '属性数组',
|
||||
`pic_url` varchar(512) DEFAULT NULL COMMENT '商品图片',
|
||||
`count` int(11) NOT NULL COMMENT '退货商品数量',
|
||||
`audit_time` datetime DEFAULT NULL COMMENT '审批时间',
|
||||
`audit_user_id` bigint(20) DEFAULT NULL COMMENT '审批人',
|
||||
`audit_reason` varchar(512) DEFAULT NULL COMMENT '审批备注',
|
||||
`refund_price` int(11) NOT NULL COMMENT '退款金额,单位:分',
|
||||
`pay_refund_id` bigint(20) DEFAULT NULL COMMENT '支付退款编号',
|
||||
`refund_time` datetime DEFAULT NULL COMMENT '退款时间',
|
||||
`logistics_id` bigint(20) DEFAULT NULL COMMENT '退货物流公司编号',
|
||||
`logistics_no` varchar(64) DEFAULT NULL COMMENT '退货物流单号',
|
||||
`delivery_time` datetime DEFAULT NULL COMMENT '退货时间',
|
||||
`receive_time` datetime DEFAULT NULL COMMENT '收货时间',
|
||||
`receive_reason` varchar(512) DEFAULT NULL COMMENT '收货备注',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_no` (`no`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_order_item_id` (`order_item_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='售后订单表';
|
||||
CREATE TABLE `tz_trade_after_sale`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '售后编号,主键自增',
|
||||
`no` varchar(64) NOT NULL COMMENT '售后单号',
|
||||
`status` tinyint(4) NOT NULL COMMENT '退款状态 (枚举 AfterSaleStatusEnum)',
|
||||
`way` tinyint(4) NOT NULL COMMENT '售后方式 (枚举 AfterSaleWayEnum)',
|
||||
`type` tinyint(4) NOT NULL COMMENT '售后类型 (枚举 AfterSaleTypeEnum)',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`apply_reason` varchar(256) NOT NULL COMMENT '申请原因',
|
||||
`apply_description` varchar(512) DEFAULT NULL COMMENT '补充描述',
|
||||
`apply_pic_urls` json DEFAULT NULL COMMENT '补充凭证图片',
|
||||
`order_id` bigint(20) NOT NULL COMMENT '交易订单编号',
|
||||
`order_no` varchar(64) NOT NULL COMMENT '订单流水号',
|
||||
`order_item_id` bigint(20) NOT NULL COMMENT '交易订单项编号',
|
||||
`prod_id` bigint(20) NOT NULL COMMENT '商品 SPU 编号',
|
||||
`prod_name` varchar(256) NOT NULL COMMENT '商品 SPU 名称',
|
||||
`sku_id` bigint(20) NOT NULL COMMENT '商品 SKU 编号',
|
||||
`properties` json DEFAULT NULL COMMENT '属性数组',
|
||||
`pic_url` varchar(512) DEFAULT NULL COMMENT '商品图片',
|
||||
`count` int(11) NOT NULL COMMENT '退货商品数量',
|
||||
`audit_time` datetime DEFAULT NULL COMMENT '审批时间',
|
||||
`audit_user_id` bigint(20) DEFAULT NULL COMMENT '审批人',
|
||||
`audit_reason` varchar(512) DEFAULT NULL COMMENT '审批备注',
|
||||
`refund_price` int(11) NOT NULL COMMENT '退款金额,单位:分',
|
||||
`pay_refund_id` bigint(20) DEFAULT NULL COMMENT '支付退款编号',
|
||||
`refund_time` datetime DEFAULT NULL COMMENT '退款时间',
|
||||
`logistics_id` bigint(20) DEFAULT NULL COMMENT '退货物流公司编号',
|
||||
`logistics_no` varchar(64) DEFAULT NULL COMMENT '退货物流单号',
|
||||
`delivery_time` datetime DEFAULT NULL COMMENT '退货时间',
|
||||
`receive_time` datetime DEFAULT NULL COMMENT '收货时间',
|
||||
`receive_reason` varchar(512) DEFAULT NULL COMMENT '收货备注',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_no` (`no`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_order_item_id` (`order_item_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='售后订单表';
|
||||
|
||||
-- 交易售后日志表 (tz_trade_after_sale_log)
|
||||
CREATE TABLE `tz_trade_after_sale_log` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`user_type` tinyint(4) NOT NULL COMMENT '用户类型 (枚举 UserTypeEnum)',
|
||||
`after_sale_id` bigint(20) NOT NULL COMMENT '售后编号',
|
||||
`before_status` tinyint(4) DEFAULT NULL COMMENT '操作前状态',
|
||||
`after_status` tinyint(4) DEFAULT NULL COMMENT '操作后状态',
|
||||
`operate_type` tinyint(4) NOT NULL COMMENT '操作类型 (枚举 AfterSaleOperateTypeEnum)',
|
||||
`content` varchar(512) NOT NULL COMMENT '操作明细',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_after_sale_id` (`after_sale_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_operate_type` (`operate_type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易售后日志表';
|
||||
CREATE TABLE `tz_trade_after_sale_log`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`user_type` tinyint(4) NOT NULL COMMENT '用户类型 (枚举 UserTypeEnum)',
|
||||
`after_sale_id` bigint(20) NOT NULL COMMENT '售后编号',
|
||||
`before_status` tinyint(4) DEFAULT NULL COMMENT '操作前状态',
|
||||
`after_status` tinyint(4) DEFAULT NULL COMMENT '操作后状态',
|
||||
`operate_type` tinyint(4) NOT NULL COMMENT '操作类型 (枚举 AfterSaleOperateTypeEnum)',
|
||||
`content` varchar(512) NOT NULL COMMENT '操作明细',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_after_sale_id` (`after_sale_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_operate_type` (`operate_type`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='交易售后日志表';
|
||||
|
||||
|
||||
-- 快递公司表 (trade_delivery_express)
|
||||
CREATE TABLE `tz_trade_delivery_express` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号,自增',
|
||||
`code` varchar(64) NOT NULL COMMENT '快递公司 code',
|
||||
`name` varchar(128) NOT NULL COMMENT '快递公司名称',
|
||||
`logo` varchar(512) DEFAULT NULL COMMENT '快递公司 logo',
|
||||
`sort` int(11) DEFAULT NULL COMMENT '排序',
|
||||
`status` tinyint(4) NOT NULL COMMENT '状态 (枚举 CommonStatusEnum)',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_code` (`code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='快递公司表';
|
||||
CREATE TABLE `tz_trade_delivery_express`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号,自增',
|
||||
`code` varchar(64) NOT NULL COMMENT '快递公司 code',
|
||||
`name` varchar(128) NOT NULL COMMENT '快递公司名称',
|
||||
`logo` varchar(512) DEFAULT NULL COMMENT '快递公司 logo',
|
||||
`sort` int(11) DEFAULT NULL COMMENT '排序',
|
||||
`status` tinyint(4) NOT NULL COMMENT '状态 (枚举 CommonStatusEnum)',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_code` (`code`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='快递公司表';
|
||||
|
||||
-- 快递运费模板表 (trade_delivery_express_template)
|
||||
CREATE TABLE `tz_trade_delivery_express_template` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号,自增',
|
||||
`name` varchar(128) NOT NULL COMMENT '模板名称',
|
||||
`charge_mode` tinyint(4) NOT NULL COMMENT '配送计费方式 (枚举 DeliveryExpressChargeModeEnum)',
|
||||
`sort` int(11) DEFAULT NULL COMMENT '排序',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='快递运费模板表';
|
||||
CREATE TABLE `tz_trade_delivery_express_template`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号,自增',
|
||||
`name` varchar(128) NOT NULL COMMENT '模板名称',
|
||||
`charge_mode` tinyint(4) NOT NULL COMMENT '配送计费方式 (枚举 DeliveryExpressChargeModeEnum)',
|
||||
`sort` int(11) DEFAULT NULL COMMENT '排序',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='快递运费模板表';
|
||||
|
||||
-- 快递运费模板计费配置表 (trade_delivery_express_template_charge)
|
||||
CREATE TABLE `tz_trade_delivery_express_template_charge` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号,自增',
|
||||
`template_id` bigint(20) NOT NULL COMMENT '配送模板编号',
|
||||
`area_ids` varchar(512) NOT NULL COMMENT '配送区域编号列表',
|
||||
`charge_mode` tinyint(4) NOT NULL COMMENT '配送计费方式',
|
||||
`start_count` double NOT NULL COMMENT '首件数量(件数,重量,或体积)',
|
||||
`start_price` int(11) NOT NULL COMMENT '起步价,单位:分',
|
||||
`extra_count` double NOT NULL COMMENT '续件数量(件, 重量,或体积)',
|
||||
`extra_price` int(11) NOT NULL COMMENT '额外价,单位:分',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_template_id` (`template_id`),
|
||||
CONSTRAINT `fk_express_template_charge_template_id` FOREIGN KEY (`template_id`) REFERENCES `tz_trade_delivery_express_template` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='快递运费模板计费配置表';
|
||||
CREATE TABLE `tz_trade_delivery_express_template_charge`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号,自增',
|
||||
`template_id` bigint(20) NOT NULL COMMENT '配送模板编号',
|
||||
`area_ids` varchar(512) NOT NULL COMMENT '配送区域编号列表',
|
||||
`charge_mode` tinyint(4) NOT NULL COMMENT '配送计费方式',
|
||||
`start_count` double NOT NULL COMMENT '首件数量(件数,重量,或体积)',
|
||||
`start_price` int(11) NOT NULL COMMENT '起步价,单位:分',
|
||||
`extra_count` double NOT NULL COMMENT '续件数量(件, 重量,或体积)',
|
||||
`extra_price` int(11) NOT NULL COMMENT '额外价,单位:分',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_template_id` (`template_id`),
|
||||
CONSTRAINT `fk_express_template_charge_template_id` FOREIGN KEY (`template_id`) REFERENCES `tz_trade_delivery_express_template` (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='快递运费模板计费配置表';
|
||||
|
||||
-- 快递运费模板包邮配置表 (trade_delivery_express_template_free)
|
||||
CREATE TABLE `tz_trade_delivery_express_template_free` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`template_id` bigint(20) NOT NULL COMMENT '配送模板编号',
|
||||
`area_ids` varchar(512) NOT NULL COMMENT '配送区域编号列表',
|
||||
`free_price` int(11) DEFAULT NULL COMMENT '包邮金额,单位:分',
|
||||
`free_count` int(11) DEFAULT NULL COMMENT '包邮件数',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_template_id` (`template_id`),
|
||||
CONSTRAINT `fk_express_template_free_template_id` FOREIGN KEY (`template_id`) REFERENCES `tz_trade_delivery_express_template` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='快递运费模板包邮配置表';
|
||||
CREATE TABLE `tz_trade_delivery_express_template_free`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`template_id` bigint(20) NOT NULL COMMENT '配送模板编号',
|
||||
`area_ids` varchar(512) NOT NULL COMMENT '配送区域编号列表',
|
||||
`free_price` int(11) DEFAULT NULL COMMENT '包邮金额,单位:分',
|
||||
`free_count` int(11) DEFAULT NULL COMMENT '包邮件数',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_template_id` (`template_id`),
|
||||
CONSTRAINT `fk_express_template_free_template_id` FOREIGN KEY (`template_id`) REFERENCES `tz_trade_delivery_express_template` (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='快递运费模板包邮配置表';
|
||||
|
||||
-- 自提门店表 (trade_delivery_pick_up_store)
|
||||
CREATE TABLE `tz_trade_delivery_pick_up_store` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`name` varchar(128) NOT NULL COMMENT '门店名称',
|
||||
`introduction` varchar(512) DEFAULT NULL COMMENT '门店简介',
|
||||
`phone` varchar(20) NOT NULL COMMENT '门店手机',
|
||||
`area_id` int(11) NOT NULL COMMENT '区域编号',
|
||||
`detail_address` varchar(512) NOT NULL COMMENT '门店详细地址',
|
||||
`logo` varchar(512) DEFAULT NULL COMMENT '门店 logo',
|
||||
`opening_time` time NOT NULL COMMENT '营业开始时间',
|
||||
`closing_time` time NOT NULL COMMENT '营业结束时间',
|
||||
`latitude` double DEFAULT NULL COMMENT '纬度',
|
||||
`longitude` double DEFAULT NULL COMMENT '经度',
|
||||
`verify_user_ids` varchar(512) DEFAULT NULL COMMENT '核销员工用户编号数组',
|
||||
`status` tinyint(4) NOT NULL COMMENT '门店状态 (枚举 CommonStatusEnum)',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_area_id` (`area_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='自提门店表';
|
||||
CREATE TABLE `tz_trade_delivery_pick_up_store`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`name` varchar(128) NOT NULL COMMENT '门店名称',
|
||||
`introduction` varchar(512) DEFAULT NULL COMMENT '门店简介',
|
||||
`phone` varchar(20) NOT NULL COMMENT '门店手机',
|
||||
`area_id` int(11) NOT NULL COMMENT '区域编号',
|
||||
`detail_address` varchar(512) NOT NULL COMMENT '门店详细地址',
|
||||
`logo` varchar(512) DEFAULT NULL COMMENT '门店 logo',
|
||||
`opening_time` time NOT NULL COMMENT '营业开始时间',
|
||||
`closing_time` time NOT NULL COMMENT '营业结束时间',
|
||||
`latitude` double DEFAULT NULL COMMENT '纬度',
|
||||
`longitude` double DEFAULT NULL COMMENT '经度',
|
||||
`verify_user_ids` varchar(512) DEFAULT NULL COMMENT '核销员工用户编号数组',
|
||||
`status` tinyint(4) NOT NULL COMMENT '门店状态 (枚举 CommonStatusEnum)',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_area_id` (`area_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='自提门店表';
|
||||
|
||||
-- 订单预约时间修改记录表 (tz_trade_sub_log)
|
||||
CREATE TABLE `tz_trade_sub_log`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
|
||||
`order_id` bigint(20) NOT NULL COMMENT '订单号',
|
||||
`sub_time` datetime NOT NULL COMMENT '预约时间',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_user_id` (`user_id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='订单预约时间修改记录表';
|
||||
|
||||
|
||||
90
sql/mysql/user.sql
Normal file
90
sql/mysql/user.sql
Normal file
@@ -0,0 +1,90 @@
|
||||
-- 登录用户表 (tz_login_user) 后续拓展用户信息表
|
||||
CREATE TABLE `tz_user_login`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
|
||||
`mobile` varchar(11) NOT NULL COMMENT '手机',
|
||||
`password` varchar(128) NOT NULL COMMENT '加密后的密码',
|
||||
`status` tinyint(4) NOT NULL COMMENT '帐号状态 (枚举 CommonStatusEnum)',
|
||||
`register_ip` varchar(32) DEFAULT NULL COMMENT '注册 IP',
|
||||
`register_terminal` tinyint(4) DEFAULT NULL COMMENT '注册渠道 (枚举 TerminalEnum)',
|
||||
`register_date` datetime DEFAULT NULL COMMENT '注册时间',
|
||||
`login_ip` varchar(32) DEFAULT NULL COMMENT '最后登录IP',
|
||||
`login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
|
||||
`login_terminal` varchar(32) DEFAULT NULL COMMENT '最后登录设备',
|
||||
`nickname` varchar(64) DEFAULT NULL COMMENT '用户昵称',
|
||||
`avatar` varchar(512) DEFAULT NULL COMMENT '用户头像',
|
||||
`remark` varchar(512) DEFAULT NULL COMMENT '用户备注',
|
||||
`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_mobile` (`mobile`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='登录用户表';
|
||||
|
||||
-- 会员信息表 (tz_user_member)
|
||||
CREATE TABLE `tz_user_member`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
|
||||
`name` varchar(64) DEFAULT NULL COMMENT '真实名字',
|
||||
`sex` tinyint DEFAULT NULL COMMENT '性别 (枚举 SexEnum)',
|
||||
`birthday` datetime DEFAULT NULL COMMENT '出生日期',
|
||||
`area_id` int DEFAULT NULL COMMENT '所在地 (关联 Area.id 字段)',
|
||||
`point` int DEFAULT NULL COMMENT '积分',
|
||||
`tag_ids` varchar(512) DEFAULT NULL COMMENT '会员标签列表,以逗号分隔',
|
||||
`level_id` bigint DEFAULT NULL COMMENT '会员级别编号 (关联 MemberLevelDO.id 字段)',
|
||||
`experience` int DEFAULT NULL COMMENT '会员经验',
|
||||
`group_id` bigint DEFAULT NULL COMMENT '用户分组编号 (关联 MemberGroupDO.id 字段)',
|
||||
`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='会员信息表';
|
||||
|
||||
-- 会员地址表 (tz_user_member_address)
|
||||
CREATE TABLE `tz_user_member_address`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
|
||||
`name` varchar(128) DEFAULT NULL COMMENT '收件人名称',
|
||||
`mobile` varchar(11) DEFAULT NULL COMMENT '手机号',
|
||||
`areaId` bigint(20) DEFAULT NULL COMMENT '地区编号',
|
||||
`detailAddress` varchar(255) DEFAULT NULL COMMENT '收件详细地址',
|
||||
`defaultStatus` int DEFAULT NULL COMMENT '是否默认',
|
||||
`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='会员地址表';
|
||||
|
||||
-- 会员等级表 (tz_user_member_level)
|
||||
CREATE TABLE `tz_user_member_level`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`level_name` varchar(64) DEFAULT NULL COMMENT '等级名称',
|
||||
`level` int DEFAULT NULL COMMENT '性别 (枚举 SexEnum)',
|
||||
`experience` int DEFAULT NULL COMMENT '会员经验',
|
||||
`discount_percent` int DEFAULT NULL COMMENT '享受折扣',
|
||||
`icon` varchar(128) DEFAULT NULL COMMENT '等级图标',
|
||||
`background_url` varchar(128) DEFAULT NULL COMMENT '等级背景图',
|
||||
`status` int DEFAULT NULL COMMENT '状态',
|
||||
`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL COMMENT '最后更新时间',
|
||||
`creator` varchar(64) NOT NULL COMMENT '创建者',
|
||||
`updater` varchar(64) NOT NULL COMMENT '更新者',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='会员等级表';
|
||||
|
||||
@@ -193,6 +193,11 @@
|
||||
<artifactId>tashow-sdk-payment</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-product-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring 核心 -->
|
||||
<dependency>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.tashow.cloud.productapi.api.product;
|
||||
|
||||
import com.tashow.cloud.common.pojo.CommonResult;
|
||||
import com.tashow.cloud.common.pojo.PageResult;
|
||||
import com.tashow.cloud.productapi.api.product.dto.ProdDO;
|
||||
import com.tashow.cloud.productapi.api.product.vo.prod.ProdListVO;
|
||||
import com.tashow.cloud.productapi.api.product.vo.prod.ProdPageReqVO;
|
||||
import com.tashow.cloud.productapi.api.product.vo.prod.ProdServiceVO;
|
||||
import com.tashow.cloud.productapi.enums.ApiConstants;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
/** RPC 服务 - 参数配置 */
|
||||
public interface ProdApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/prod";
|
||||
/**
|
||||
* 获取商品详情
|
||||
*
|
||||
* @param id 商品id
|
||||
* @return 编号
|
||||
*/
|
||||
|
||||
@GetMapping(PREFIX + "/getProdInfo")
|
||||
@PermitAll
|
||||
CommonResult<ProdDO> getProdInfo(@RequestParam(value = "id", required = false) Long id);
|
||||
|
||||
/**
|
||||
* 获取商品服务配置
|
||||
*
|
||||
* @param id 商品id
|
||||
* @return 编号
|
||||
*/
|
||||
@GetMapping(PREFIX + "/getProdService")
|
||||
ProdServiceVO getProdService(@RequestParam(value = "id", required = false) Long id);
|
||||
|
||||
/**
|
||||
* 获得商品分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 商品分页
|
||||
*/
|
||||
@GetMapping(PREFIX + "/getProdPage")
|
||||
PageResult<ProdListVO> getProdPage(ProdPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 扣减库存
|
||||
* @param skuId 单品ID
|
||||
* @param stocksNum 扣减数量
|
||||
*/
|
||||
@GetMapping(PREFIX + "/reduceStocks")
|
||||
CommonResult<Boolean> reduceStocks(Long skuId, Integer stocksNum) ;
|
||||
/**
|
||||
* 增加库存
|
||||
* @param skuId 单品ID
|
||||
* @param stocksNum 增加数量
|
||||
*/
|
||||
@GetMapping(PREFIX + "/increaseStocks")
|
||||
CommonResult<Boolean> increaseStocks(Long skuId, Integer stocksNum);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.tashow.cloud.productapi.api.product;
|
||||
|
||||
import com.tashow.cloud.productapi.api.product.dto.CategoryDO;
|
||||
import com.tashow.cloud.productapi.api.product.dto.ShopDetailDO;
|
||||
import com.tashow.cloud.productapi.enums.ApiConstants;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
/** RPC 服务 - 参数配置 */
|
||||
public interface ShopDetailApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/shop";
|
||||
|
||||
@GetMapping(PREFIX + "/getShopInfo")
|
||||
ShopDetailDO getShopInfo(@RequestParam(value = "id", required = false) Long id);
|
||||
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import java.util.List;
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
|
||||
public class CategoryDto {
|
||||
|
||||
/**
|
||||
|
||||
@@ -70,6 +70,10 @@ public class ProdListVO {
|
||||
* 还剩多少天
|
||||
*/
|
||||
private Long remainingDays;
|
||||
/**
|
||||
* 图片
|
||||
*/
|
||||
private String pic;
|
||||
|
||||
/**
|
||||
* 审核备注
|
||||
|
||||
@@ -17,7 +17,7 @@ public class ApiConstants {
|
||||
*/
|
||||
public static final String NAME = "product-server";
|
||||
|
||||
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/infra";
|
||||
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/product";
|
||||
|
||||
public static final String VERSION = "1.0.0";
|
||||
|
||||
|
||||
@@ -32,4 +32,10 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode SKU_SERVICES_FORM_NOT_EXISTS = new ErrorCode(10021, "商品SKU扩展服务表单不存在");
|
||||
ErrorCode SKU_SERVICE_TRANSPORT_NOT_EXISTS = new ErrorCode(10022, "服务遗体运输不存在");
|
||||
ErrorCode SKU_SERVICE_DETAILS_NOT_EXISTS = new ErrorCode(10023, "服务详情不存在");
|
||||
|
||||
ErrorCode SKU_DOES_NOT_EXIST = new ErrorCode(10030, "商品不存在");
|
||||
ErrorCode SKU_DELETE = new ErrorCode(10030, "商品已删除");
|
||||
ErrorCode SKU_DISABLE = new ErrorCode(10031, "商品已禁用");
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode ORDER_ITEM_NOT_FOUND = new ErrorCode(1_011_000_010, "交易订单项不存在");
|
||||
ErrorCode ORDER_NOT_FOUND = new ErrorCode(1_011_000_011, "交易订单不存在");
|
||||
ErrorCode ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL = new ErrorCode(1_011_000_012, "交易订单项更新售后状态失败,请重试");
|
||||
ErrorCode ORDER_UPDATE_UNWAITACCEPT_FAIL = new ErrorCode(1_011_000_012, "交易订单更新状态失败,当前订单不处于待验收状态");
|
||||
ErrorCode ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1_011_000_013, "交易订单更新支付状态失败,订单不是【未支付】状态");
|
||||
ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1_011_000_014, "交易订单更新支付状态失败,支付单编号不匹配");
|
||||
ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1_011_000_015, "交易订单更新支付状态失败,支付单状态不是【支付成功】状态");
|
||||
|
||||
@@ -25,6 +25,7 @@ public enum TradeOrderOperateTypeEnum {
|
||||
SYSTEM_COMMENT(34, "到期未评价,系统自动评价"),
|
||||
MEMBER_CANCEL(40, "取消订单"),
|
||||
SYSTEM_CANCEL(41, "到期未支付,系统自动取消订单"),
|
||||
ADMIN_CANCEL(42, "管理员取消订单"),
|
||||
// 42 预留:管理员取消订单
|
||||
ADMIN_CANCEL_AFTER_SALE(43, "订单全部售后,管理员自动取消订单"),
|
||||
MEMBER_DELETE(49, "删除订单"),
|
||||
|
||||
@@ -17,11 +17,15 @@ import java.util.Arrays;
|
||||
@Getter
|
||||
public enum TradeOrderStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
UNPAID(0, "待支付"),
|
||||
UNDELIVERED(10, "待发货"),
|
||||
DELIVERED(20, "已发货"),
|
||||
COMPLETED(30, "已完成"),
|
||||
CANCELED(40, "已取消");
|
||||
WAITPAID(10, "等待付款"),
|
||||
WAITCONFIRM(20, "等待确定"),
|
||||
WAITSERVE(30, "等待服务"),
|
||||
WAITACCEPT(40, "等待验收"),
|
||||
COMPLETED(50, "已完成"),
|
||||
CANCELED(60, "已取消"),
|
||||
DELIVERED(70, "已退款"),
|
||||
WAITDELIVERED(80, "待发货"),
|
||||
;
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(TradeOrderStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
@@ -49,7 +53,16 @@ public enum TradeOrderStatusEnum implements ArrayValuable<Integer> {
|
||||
* @return 是否
|
||||
*/
|
||||
public static boolean isUnpaid(Integer status) {
|
||||
return ObjectUtil.equal(UNPAID.getStatus(), status);
|
||||
return ObjectUtil.equal(WAITPAID.getStatus(), status);
|
||||
}
|
||||
/**
|
||||
* 判断指定状态,是否正处于【待验收】状态
|
||||
*
|
||||
* @param status 指定状态
|
||||
* @return 是否
|
||||
*/
|
||||
public static boolean isWaitAccept(Integer status) {
|
||||
return ObjectUtil.equal(WAITACCEPT.getStatus(), status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +72,7 @@ public enum TradeOrderStatusEnum implements ArrayValuable<Integer> {
|
||||
* @return 是否
|
||||
*/
|
||||
public static boolean isUndelivered(Integer status) {
|
||||
return ObjectUtil.equal(UNDELIVERED.getStatus(), status);
|
||||
return ObjectUtil.equal(WAITDELIVERED.getStatus(), status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +112,7 @@ public enum TradeOrderStatusEnum implements ArrayValuable<Integer> {
|
||||
* @return 是否
|
||||
*/
|
||||
public static boolean havePaid(Integer status) {
|
||||
return ObjectUtils.equalsAny(status, UNDELIVERED.getStatus(),
|
||||
return ObjectUtils.equalsAny(status, WAITCONFIRM.getStatus(),
|
||||
DELIVERED.getStatus(), COMPLETED.getStatus());
|
||||
}
|
||||
|
||||
|
||||
@@ -196,6 +196,15 @@ public class LocalDateTimeUtils {
|
||||
return LocalDateTimeUtil.beginOfDay(LocalDateTime.now().minusDays(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取day 天后的日期
|
||||
*
|
||||
* @return 昨天
|
||||
*/
|
||||
public static LocalDateTime getPlusDay(Integer day) {
|
||||
return LocalDateTimeUtil.beginOfDay(LocalDateTime.now().plusDays(day));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本月的开始时间
|
||||
*
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.tashow.cloud.common.util.json.databind;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 基于字符串的 LocalDateTime 序列化器
|
||||
*
|
||||
* @author 老五
|
||||
*/
|
||||
public class StringLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
|
||||
|
||||
public static final StringLocalDateTimeSerializer INSTANCE = new StringLocalDateTimeSerializer();
|
||||
|
||||
@Override
|
||||
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
// 将 LocalDateTime 对象,转换为 Long 时间戳
|
||||
gen.writeString(LocalDateTimeUtil.format(value, DatePattern.NORM_DATETIME_FORMATTER) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
* 1. {@link BaseMapper} 为 MyBatis Plus 的基础接口,提供基础的 CRUD 能力
|
||||
* 2. {@link MPJBaseMapper} 为 MyBatis Plus Join 的基础接口,提供连表 Join 能力
|
||||
*/
|
||||
public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
||||
public interface BaseMapperX<T> extends MPJBaseMapper<T>,BaseMapper<T> {
|
||||
|
||||
default PageResult<T> selectPage(SortablePageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
|
||||
return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class EnvEnvironmentPostProcessor implements EnvironmentPostProcessor {
|
||||
environment.getSystemProperties().put(hostNameKey, EnvUtils.getHostName());
|
||||
}
|
||||
|
||||
// 1.1 如果没有 yudao.env.tag 配置项,则不进行配置项的修改
|
||||
// 1.1 如果没有 tashow.env.tag 配置项,则不进行配置项的修改
|
||||
String tag = EnvUtils.getTag(environment);
|
||||
if (StrUtil.isEmpty(tag)) {
|
||||
return;
|
||||
|
||||
@@ -136,7 +136,7 @@ public class WebSecurityConfigurerAdapter {
|
||||
.requestMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll()
|
||||
.requestMatchers(HttpMethod.HEAD, permitAllUrls.get(HttpMethod.HEAD).toArray(new String[0])).permitAll()
|
||||
.requestMatchers(HttpMethod.PATCH, permitAllUrls.get(HttpMethod.PATCH).toArray(new String[0])).permitAll()
|
||||
// 1.3 基于 yudao.security.permit-all-urls 无需认证
|
||||
// 1.3 基于 tashow.security.permit-all-urls 无需认证
|
||||
.requestMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()
|
||||
)
|
||||
// ②:每个项目的自定义规则
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
server-addr: localhost:8848 # Nacos 服务器地址
|
||||
username: # Nacos 账号
|
||||
password: # Nacos 密码
|
||||
server-addr: 43.139.42.137:8848 # Nacos 服务器地址
|
||||
username: nacos # Nacos 账号
|
||||
password: nacos # Nacos 密码
|
||||
discovery: # 【配置中心】配置项
|
||||
namespace: dev # 命名空间。这里使用 dev 开发环境
|
||||
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<module>tashow-module-ai</module>
|
||||
<module>tashow-module-pay</module>
|
||||
<module>tashow-module-trade</module>
|
||||
<module>tashow-module-member</module>
|
||||
<module>tashow-module-user</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.tashow.cloud.ai.controller.app.dialog.vo.TranslateReqVo;
|
||||
import com.tashow.cloud.ai.controller.app.dialog.vo.TranslateRespVo;
|
||||
import com.tashow.cloud.ai.service.dialog.AiDialogService;
|
||||
import com.tashow.cloud.common.pojo.CommonResult;
|
||||
import com.tashow.cloud.common.pojo.PageParam;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -15,8 +16,6 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.tashow.cloud.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
@@ -28,8 +27,6 @@ import static com.tashow.cloud.common.pojo.CommonResult.success;
|
||||
@Slf4j
|
||||
public class DialogController {
|
||||
|
||||
List<String> message = List.of("渴了", "饿了", "想睡觉", "想出去玩", "想溜达", "情绪低落", "很开心", "很伤心", "想哭");
|
||||
|
||||
@Resource
|
||||
private AiDialogService aiDialogService;
|
||||
|
||||
@@ -39,10 +36,10 @@ public class DialogController {
|
||||
*/
|
||||
@GetMapping("/getDialog")
|
||||
@PermitAll
|
||||
public CommonResult<DialogResp> msList() {
|
||||
public CommonResult<DialogResp> msList(PageParam pageParam) {
|
||||
//获取当前登录用户
|
||||
Long userId = 1L;
|
||||
return success(aiDialogService.getDialog(userId));
|
||||
return success(aiDialogService.getDialog(userId,pageParam));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package com.tashow.cloud.ai.controller.app.dialog.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.tashow.cloud.common.util.json.databind.StringLocalDateTimeSerializer;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static com.tashow.cloud.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* ai-对话消息 DO
|
||||
@@ -70,7 +69,13 @@ public class AiDialogMessageRespVo {
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date createTime;
|
||||
//发送时间
|
||||
@JsonSerialize(using = StringLocalDateTimeSerializer.class)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
private Integer emotion;
|
||||
private String terminal;
|
||||
private String fileType;
|
||||
private String fileName;
|
||||
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
package com.tashow.cloud.ai.controller.app.dialog.vo;
|
||||
|
||||
import com.tashow.cloud.common.pojo.PageResult;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Schema(description = "api - 对话 Response VO")
|
||||
@Data
|
||||
@@ -17,5 +16,5 @@ public class DialogResp {
|
||||
@Schema(description = "对话状态")
|
||||
private String dialogStatus;
|
||||
@Schema(description = "对话消息内容")
|
||||
private List<AiDialogMessageRespVo> messages;
|
||||
private PageResult<AiDialogMessageRespVo> messages;
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@ public class TranslateReqVo {
|
||||
//消息id
|
||||
private Long msgId;
|
||||
|
||||
private String terminal;
|
||||
|
||||
/** 文件附件 */
|
||||
private MultipartFile file;
|
||||
|
||||
//文件时长
|
||||
private String contentDuration;
|
||||
private Long contentDuration;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.tashow.cloud.ai.controller.app.dialog.vo;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.tashow.cloud.common.util.json.databind.StringLocalDateTimeSerializer;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static com.tashow.cloud.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 翻译接口结果vo
|
||||
@@ -39,9 +39,9 @@ public class TranslateRespVo {
|
||||
private String transResult;
|
||||
//文件时长
|
||||
private Long contentDuration;
|
||||
private String terminal;
|
||||
//发送时间
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private String createTime;
|
||||
@JsonSerialize(using = StringLocalDateTimeSerializer.class)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.tashow.cloud.ai.dal.dataobject.dialog;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.*;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.tashow.cloud.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* ai-对话消息 DO
|
||||
*
|
||||
@@ -89,6 +93,11 @@ public class AiDialogMessageDO {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
private Integer emotion;
|
||||
private String terminal;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.tashow.cloud.ai.dal.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum EmotionEnums {
|
||||
|
||||
XF(1,"兴奋/玩耍","兴奋"),
|
||||
PJ(2,"平静/放松","平静"),
|
||||
je(3,"乞求/饥饿/口渴","饥饿"),
|
||||
yk(4,"愉快/满足","愉快"),
|
||||
tt(5,"疼痛/沮丧","疼痛"),
|
||||
kj(6,"恐惧/不安","恐惧"),
|
||||
hq(7,"问候/好奇","好奇"),
|
||||
ng(8,"难过/焦虑","难过"),
|
||||
fn(9,"愤怒/警告","愤怒"),
|
||||
;
|
||||
|
||||
|
||||
private Integer code;
|
||||
private String name;
|
||||
private String aiName;
|
||||
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.tashow.cloud.ai.controller.app.dialog.vo.DialogResp;
|
||||
import com.tashow.cloud.ai.controller.app.dialog.vo.TranslateReqVo;
|
||||
import com.tashow.cloud.ai.controller.app.dialog.vo.TranslateRespVo;
|
||||
import com.tashow.cloud.ai.dal.dataobject.dialog.AiDialogDO;
|
||||
import com.tashow.cloud.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* ai-对话 Service 接口
|
||||
@@ -14,7 +15,7 @@ import com.tashow.cloud.ai.dal.dataobject.dialog.AiDialogDO;
|
||||
public interface AiDialogService extends IService<AiDialogDO> {
|
||||
|
||||
|
||||
DialogResp getDialog(Long userId);
|
||||
DialogResp getDialog(Long userId, PageParam pageParam);
|
||||
|
||||
TranslateRespVo translate(TranslateReqVo fileReqVo);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.tashow.cloud.ai.service.dialog;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
@@ -15,6 +17,8 @@ import com.tashow.cloud.ai.dal.dataobject.dialog.AiDialogDO;
|
||||
import com.tashow.cloud.ai.dal.dataobject.dialog.AiDialogMessageDO;
|
||||
import com.tashow.cloud.ai.dal.mysql.dialog.AiDialogMapper;
|
||||
import com.tashow.cloud.ai.dal.mysql.dialog.AiDialogMessageMapper;
|
||||
import com.tashow.cloud.common.pojo.PageParam;
|
||||
import com.tashow.cloud.common.pojo.PageResult;
|
||||
import com.tashow.cloud.common.util.object.BeanUtils;
|
||||
import com.tashow.cloud.infraapi.api.file.FileApi;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -27,11 +31,8 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -54,9 +55,65 @@ public class AiDialogServiceImpl extends ServiceImpl<AiDialogMapper, AiDialogDO>
|
||||
@Resource
|
||||
private FileApi fileApi;
|
||||
|
||||
private List<String> failedStr =List.of(
|
||||
"刚刚的音符太独特了,我没听清呢~可以再对我说一次吗?",
|
||||
"哇,这是哪来的小可爱?声音太有魅力了,让我一时走了神。请靠近一点,慢慢再说一遍好?",
|
||||
"背景音有点热闹,我有点分心啦~能在一个更安静的地方,让我专心听听TA的声音吗",
|
||||
"报告主人!声波受到不明干扰(可能是零食袋的声音?),翻译任务失败,请求二次输入!",
|
||||
"我的‘物种雷达’刚才打了个盹儿~快让我再听一次这美妙的声音!",
|
||||
"这声音太迷人了,让我CPU过载了!请简化一下环境音,我们再来一次?"
|
||||
);
|
||||
|
||||
private Map<String,List<String>> failedMap =new HashMap<>(){{
|
||||
put("cat",List.of(
|
||||
"听得出是猫猫在说话,但TA似乎在表达一种很深邃的情绪..也许是个小秘密呢?",
|
||||
"喵星人的这段‘加密通话’等级太高了!翻译官正在努力学习中...你能通过TA的尾巴和眼神猜猜看吗?",
|
||||
"警报!警报!接收到喵星最高机密指令,我的权限不足,无法破译!建议提供小鱼干以获取更多线索"
|
||||
));
|
||||
put("dog",List.of(
|
||||
"听得出是狗狗在说话,但TA似乎在表达一种很深邃的情绪...也许是个小秘密呢?",
|
||||
"汪语十级考试失败!这句大概是“今天的我比昨天更爱你了'之类的复杂情感吧",
|
||||
"汪星人的这段‘加密通话’等级太高了!翻译官正在努力学习中..你能通过TA的尾巴和眼神猜猜看吗?"
|
||||
));
|
||||
put("common",List.of(
|
||||
"TA刚才可能用了某种古老的咒语,或者...只是在打一个很有思想的哈欠?",
|
||||
"这句‘话’的哲学深度超出了我的理解范围,TA可能是一位诗人~"
|
||||
));
|
||||
}};
|
||||
|
||||
private Map<String,List<String>> successMap =new HashMap<>(){{
|
||||
put("舒服",List.of(
|
||||
"TA 现在全身心都放松下来啦,正被满满的安全感包围着呢~ ",
|
||||
"听这均匀的呼吸,TA 的心正像云朵一样软绵绵、轻飘飘的哦。",
|
||||
"这是幸福的声音!此刻的TA,觉得自己是全世界最被爱的小宝贝",
|
||||
"环境很安心~主人很贴心~TA 正在小声说:好舒服呀~…"
|
||||
));
|
||||
put("等待喂食",List.of(
|
||||
"小肚肚发出‘咕咕’警报啦!美食雷达正在全面启动,搜寻好吃的!",
|
||||
"来自TA的紧急通讯:‘报告!能量储备严重不足,请求立刻补充!",
|
||||
"你听到了吗?那是小饭碗在思念食物的声音!TA的眼神正在发出渴望的光波~",
|
||||
"“开饭铃”已经摇响!再不开饭,小委屈就要溢出来啦!"
|
||||
));
|
||||
put("生气",List.of(
|
||||
"TA 现在有点小紧张哦,周围可能有让TA不安的东西,快给TA一点安慰吧",
|
||||
"检测到‘心跳加速’模式!TA需要一点空间和一个温柔的声音来平静下来",
|
||||
"TA 现在有点小紧张哦,周围可能有让TA不安的东西,快给TA一点安慰吧"
|
||||
));
|
||||
}};
|
||||
|
||||
private Map<String, String> petAvatars = new HashMap<>() {{
|
||||
put("cat", "https://petshy.tashowz.com/admin-api/infra/file/29/get/默认的猫.png");
|
||||
put("dog", "https://petshy.tashowz.com/admin-api/infra/file/29/get/默认的狗.png");
|
||||
}};
|
||||
|
||||
private Map<String, String> petName = new HashMap<>() {{
|
||||
put("cat", "猫猫・三胖");
|
||||
put("dog", "狗狗・旺财");
|
||||
}};
|
||||
|
||||
|
||||
@Override
|
||||
public DialogResp getDialog(Long userId) {
|
||||
public DialogResp getDialog(Long userId, PageParam pageParam) {
|
||||
AiDialogDO aiDialogDO = this.getOne(new LambdaQueryWrapper<AiDialogDO>().eq(AiDialogDO::getUserId, userId));
|
||||
if (aiDialogDO == null) {
|
||||
aiDialogDO = new AiDialogDO();
|
||||
@@ -65,7 +122,12 @@ public class AiDialogServiceImpl extends ServiceImpl<AiDialogMapper, AiDialogDO>
|
||||
aiDialogDO.setUserId(userId);
|
||||
this.save(aiDialogDO);
|
||||
}
|
||||
List<AiDialogMessageDO> messageDOS = aiDialogMessageMapper.selectList(new LambdaQueryWrapper<AiDialogMessageDO>().eq(AiDialogMessageDO::getDialogId, aiDialogDO.getId()));
|
||||
|
||||
PageResult<AiDialogMessageDO> messageDOS = aiDialogMessageMapper.selectPage(pageParam,
|
||||
new LambdaQueryWrapper<AiDialogMessageDO>().eq(AiDialogMessageDO::getDialogId, aiDialogDO.getId())
|
||||
.orderByAsc(AiDialogMessageDO::getCreateTime)
|
||||
);
|
||||
|
||||
DialogResp resp = new DialogResp();
|
||||
resp.setDialogId(aiDialogDO.getId());
|
||||
resp.setTitle(aiDialogDO.getTitle());
|
||||
@@ -77,46 +139,23 @@ public class AiDialogServiceImpl extends ServiceImpl<AiDialogMapper, AiDialogDO>
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public TranslateRespVo translate(TranslateReqVo fileReqVo) {
|
||||
AiDialogMessageDO messageDO = aiDialogMessageMapper.selectById(fileReqVo.getMsgId());
|
||||
if (messageDO == null) {
|
||||
messageDO = new AiDialogMessageDO();
|
||||
}
|
||||
String fileName = StrUtil.isBlank(messageDO.getFileName()) ? fileReqVo.getFile().getOriginalFilename() : messageDO.getFileName();
|
||||
AiDialogMessageDO messageDO = new AiDialogMessageDO();
|
||||
String fileName = fileReqVo.getFile().getOriginalFilename();
|
||||
//上传文件获取文件地址
|
||||
String fileUrl = StrUtil.isBlank(messageDO.getContentText()) ? fileServer + fileApi.createFile(fileName, "", fileReqVo.getFile().getBytes()) : messageDO.getContentText();
|
||||
String fileUrl = fileServer + fileApi.createFile(fileName, "", fileReqVo.getFile().getBytes());
|
||||
//翻译结果
|
||||
translate(messageDO, fileUrl, fileName);
|
||||
|
||||
//创建消息 持久化消息
|
||||
if (messageDO.getId() == null) {
|
||||
messageDO.setFileName(fileName);
|
||||
messageDO.setFileType(fileReqVo.getFile().getContentType());
|
||||
messageDO.setDialogId(fileReqVo.getDialogId());
|
||||
//前端无法转换时 后端进行转
|
||||
messageDO.setContentDuration(
|
||||
StrUtil.isBlank(fileReqVo.getContentDuration()) || "Infinity".equals(fileReqVo.getContentDuration())
|
||||
? 0 : Long.parseLong(fileReqVo.getContentDuration())
|
||||
);
|
||||
|
||||
messageDO.setContentText(fileUrl);
|
||||
messageDO.setContentType(2);
|
||||
//宠物档案 todo
|
||||
messageDO.setPetId(1l);
|
||||
messageDO.setPetName("猫猫翻译");
|
||||
messageDO.setPetAvatar("https://img1.baidu.com/it/u=1224902049,3440357835&fm=253&app=138&f=JPEG?w=801&h=800");
|
||||
//获取当前最后的排序
|
||||
AiDialogMessageDO aiDialogMessageDO = aiDialogMessageMapper.selectOne(new LambdaQueryWrapper<AiDialogMessageDO>()
|
||||
.eq(AiDialogMessageDO::getDialogId, fileReqVo.getDialogId())
|
||||
.orderByDesc(AiDialogMessageDO::getMessageOrder)
|
||||
.last("limit 1")
|
||||
);
|
||||
messageDO.setMessageOrder(aiDialogMessageDO == null ? 1 : aiDialogMessageDO.getMessageOrder() + 1);
|
||||
messageDO.setCreateTime(LocalDateTime.now());
|
||||
}
|
||||
int i = messageDO.getId() == null ? aiDialogMessageMapper.insert(messageDO) : aiDialogMessageMapper.updateById(messageDO);
|
||||
TranslateRespVo bean = BeanUtils.toBean(messageDO, TranslateRespVo.class);
|
||||
bean.setId(messageDO.getId());
|
||||
return bean;
|
||||
//创建消息
|
||||
messageDO.setFileName(fileName);
|
||||
messageDO.setFileType(fileReqVo.getFile().getContentType());
|
||||
messageDO.setDialogId(fileReqVo.getDialogId());
|
||||
//前端无法转换时 后端进行转
|
||||
messageDO.setContentDuration(fileReqVo.getContentDuration());
|
||||
messageDO.setContentText(fileUrl);
|
||||
messageDO.setContentType(2);
|
||||
messageDO.setCreateTime(LocalDateTimeUtil.now());
|
||||
return BeanUtils.toBean(messageDO, TranslateRespVo.class);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@@ -139,35 +178,54 @@ public class AiDialogServiceImpl extends ServiceImpl<AiDialogMapper, AiDialogDO>
|
||||
//数据解析
|
||||
JSONObject translateResult = JSON.parseObject(result);
|
||||
|
||||
if (translateResult.isEmpty() || !translateResult.containsKey("intent_result") || !translateResult.getBoolean("is_species_sound")) {
|
||||
//翻译失败
|
||||
if (translateResult.isEmpty()
|
||||
|| !translateResult.containsKey("intent_result")
|
||||
|| !translateResult.getBoolean("is_species_sound")
|
||||
|| translateResult.getDouble("confidence") < 0.7
|
||||
) {
|
||||
messageDO.setTransStatus(0);
|
||||
messageDO.setTransResult("");
|
||||
messageDO.setTransResult(failedStr.get(RandomUtil.randomInt(failedStr.size())));
|
||||
return messageDO;
|
||||
}
|
||||
|
||||
//标签 如 cat dog
|
||||
String speciesLabels = translateResult.getString("species_labels");
|
||||
//解析翻译结果
|
||||
JSONObject probabilities = translateResult.getJSONObject("intent_result")
|
||||
.getJSONObject("probabilities");
|
||||
JSONObject intentResult = translateResult.getJSONObject("intent_result");
|
||||
|
||||
//宠物档案 todo
|
||||
messageDO.setPetId(1l);
|
||||
messageDO.setPetName(petName.get(speciesLabels));
|
||||
messageDO.setPetAvatar(petAvatars.get(speciesLabels));
|
||||
messageDO.setPetType(speciesLabels);
|
||||
//识别物种,无法翻译音频
|
||||
if (intentResult.getDouble("confidence")<0.7){
|
||||
messageDO.setTransStatus(0);
|
||||
List<String> petFailResult = failedMap.get(speciesLabels);
|
||||
if (petFailResult == null) {
|
||||
petFailResult = failedMap.get("common");
|
||||
}
|
||||
messageDO.setTransResult(petFailResult.get(RandomUtil.randomInt(petFailResult.size())));
|
||||
return messageDO;
|
||||
}
|
||||
//都识别成功后 也有不同的翻译结果
|
||||
JSONObject probabilities = intentResult.getJSONObject("probabilities");
|
||||
String resultKey = probabilities.entrySet().stream()
|
||||
.filter(entry -> entry.getValue() instanceof Number)
|
||||
.max(Comparator.comparingDouble(entry -> ((Number) entry.getValue()).doubleValue()))
|
||||
.map(Map.Entry::getKey)
|
||||
.orElse(null);
|
||||
|
||||
//返回结果
|
||||
messageDO.setPetType(speciesLabels);
|
||||
//根据key解析结果
|
||||
String emo = StrUtil.isBlank(resultKey) ? "" : resultKey.split(cn.hutool.core.util.StrUtil.UNDERLINE)[1];
|
||||
List<String> emoList = successMap.get(emo);
|
||||
messageDO.setTransStatus(1);
|
||||
messageDO.setTransResult(StrUtil.isBlank(resultKey) ? "" : resultKey.split(StrUtil.UNDERLINE)[1]);
|
||||
messageDO.setTransResult(emoList.get(RandomUtil.randomInt(emoList.size())));
|
||||
|
||||
return messageDO;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
InputStream inputStream = getInputStreamFromUrl("https://petshy.tashowz.com/admin-api/infra/file/29/get/857def513547ec33a105f71108c8ece329cb64dacc3a4779c94b0fcc3398cc32.webm");
|
||||
AudioInputStream audioStream = AudioSystem.getAudioInputStream(inputStream);
|
||||
System.out.println((long) (audioStream.getFrameLength() / audioStream.getFormat().getFrameRate()));
|
||||
// byte[] bytes = HttpUtil.downloadBytes("http://192.168.1.231:48080/admin-api/infra/file/29/get/c7351abf780f18600c104ec5662d843783ed8c309c01fb427046565217f51102.wav");
|
||||
//
|
||||
//// File file = new File("http://192.168.1.231:48080/admin-api/infra/file/29/get/c7351abf780f18600c104ec5662d843783ed8c309c01fb427046565217f51102.wav");
|
||||
@@ -177,19 +235,4 @@ public class AiDialogServiceImpl extends ServiceImpl<AiDialogMapper, AiDialogDO>
|
||||
}
|
||||
|
||||
|
||||
public static InputStream getInputStreamFromUrl(String urlString) throws Exception {
|
||||
URL url = new URL(urlString);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET"); // 可以是GET, POST等
|
||||
connection.setConnectTimeout(5000); // 设置连接超时时间
|
||||
connection.setReadTimeout(5000); // 设置读取超时时间
|
||||
int responseCode = connection.getResponseCode(); // 获取响应码
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) { // 状态码200表示成功
|
||||
return connection.getInputStream();
|
||||
} else {
|
||||
// 处理错误情况,例如抛出异常或返回null等
|
||||
throw new RuntimeException("Failed : HTTP error code : " + responseCode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,14 @@
|
||||
<artifactId>tashow-framework-env</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.jaudiotagger/jaudiotagger -->
|
||||
<dependency>
|
||||
<groupId>org.jaudiotagger</groupId>
|
||||
<artifactId>jaudiotagger</artifactId>
|
||||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- 依赖服务 -->
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
|
||||
@@ -29,14 +29,13 @@ import static com.tashow.cloud.infra.framework.file.core.utils.FileTypeUtils.wri
|
||||
@RequestMapping("/infra/file")
|
||||
@Validated
|
||||
@Slf4j
|
||||
@PermitAll
|
||||
public class FileController {
|
||||
|
||||
@Resource private FileService fileService;
|
||||
|
||||
/** 上传文件", description = "模式一:后端上传文件 */
|
||||
@PostMapping("/upload")
|
||||
public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
|
||||
public CommonResult<String> uploadFile(@Valid FileUploadReqVO uploadReqVO) throws Exception {
|
||||
MultipartFile file = uploadReqVO.getFile();
|
||||
String path = uploadReqVO.getPath();
|
||||
return success(
|
||||
@@ -88,7 +87,6 @@ public class FileController {
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
return;
|
||||
}
|
||||
response.setContentLength(content.length);
|
||||
writeAttachment(response, path, content);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,20 @@ import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.tika.Tika;
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||
import org.jaudiotagger.audio.exceptions.CannotWriteException;
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||
import org.jaudiotagger.tag.Tag;
|
||||
import org.jaudiotagger.tag.TagException;
|
||||
import org.jaudiotagger.tag.id3.AbstractID3v2Tag;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
/**
|
||||
@@ -64,7 +76,7 @@ public class FileTypeUtils {
|
||||
String contentType = getMineType(content, filename);
|
||||
response.setContentType(contentType);
|
||||
// 针对 video 的特殊处理,解决视频地址在移动端播放的兼容性问题
|
||||
if (StrUtil.containsIgnoreCase(contentType, "video")) {
|
||||
if (StrUtil.containsIgnoreCase(contentType, "video")||StrUtil.containsIgnoreCase(contentType, "audio")) {
|
||||
response.setHeader("Content-Length", String.valueOf(content.length - 1));
|
||||
response.setHeader("Content-Range", String.valueOf(content.length - 1));
|
||||
response.setHeader("Accept-Ranges", "bytes");
|
||||
@@ -73,4 +85,21 @@ public class FileTypeUtils {
|
||||
IoUtil.write(response.getOutputStream(), false, content);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws CannotReadException, TagException, InvalidAudioFrameException, ReadOnlyFileException, IOException, CannotWriteException, URISyntaxException {
|
||||
URL url = new URL("https://petshy.tashowz.com/admin-api/infra/file/29/get/jna2-雪球-难过焦虑.wav");
|
||||
File file = new File(url.getFile());
|
||||
System.out.println(file.exists());
|
||||
AudioFile audioFile = AudioFileIO.read(file);
|
||||
Tag tag = audioFile.getTag();
|
||||
if (tag instanceof AbstractID3v2Tag) {
|
||||
AbstractID3v2Tag id3v2Tag = (AbstractID3v2Tag) tag;
|
||||
// id3v2Tag.delete(); // 删除所有ID3标签
|
||||
} else {
|
||||
System.out.println("The file does not contain ID3v2 tags.");
|
||||
}
|
||||
AudioFileIO.write(audioFile); // 保存更改
|
||||
System.out.println("ID3 tags removed successfully.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName};
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#end
|
||||
#if (${column.javaType} == "LocalDateTime")
|
||||
import java.time.LocalDateTime;
|
||||
#end
|
||||
#end
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import ${BaseDOClassName};
|
||||
|
||||
/**
|
||||
* ${table.classComment} DO
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@TableName("${table.tableName.toLowerCase()}")
|
||||
@KeySequence("${table.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ${table.className}DO extends BaseDO {
|
||||
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
public static final Long ${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT = 0L;
|
||||
|
||||
#end
|
||||
#foreach ($column in $columns)
|
||||
#if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段
|
||||
/**
|
||||
* ${column.columnComment}
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
*
|
||||
* 枚举 {@link TODO ${column.dictType} 对应的类}
|
||||
#end
|
||||
*/
|
||||
#if (${column.primaryKey})##处理主键
|
||||
@TableId#if (${column.javaType} == 'String')(type = IdType.INPUT)#end
|
||||
#end
|
||||
private ${column.javaType} ${column.javaField};
|
||||
#end
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
package ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName};
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
#foreach ($column in $subColumns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#end
|
||||
#if (${column.javaType} == "LocalDateTime")
|
||||
import java.time.LocalDateTime;
|
||||
#end
|
||||
#end
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import ${BaseDOClassName};
|
||||
|
||||
/**
|
||||
* ${subTable.classComment} DO
|
||||
*
|
||||
* @author ${subTable.author}
|
||||
*/
|
||||
@TableName("${subTable.tableName.toLowerCase()}")
|
||||
@KeySequence("${subTable.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ${subTable.className}DO extends BaseDO {
|
||||
|
||||
#foreach ($column in $subColumns)
|
||||
#if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段
|
||||
/**
|
||||
* ${column.columnComment}
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
*
|
||||
* 枚举 {@link TODO ${column.dictType} 对应的类}
|
||||
#end
|
||||
*/
|
||||
#if (${column.primaryKey})##处理主键
|
||||
@TableId#if (${column.javaType} == 'String')(type = IdType.INPUT)#end
|
||||
#end
|
||||
private ${column.javaType} ${column.javaField};
|
||||
#end
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName};
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ${PageResultClassName};
|
||||
import ${QueryWrapperClassName};
|
||||
import ${BaseMapperClassName};
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
|
||||
## 字段模板
|
||||
#macro(listCondition)
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})
|
||||
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
|
||||
#if (${column.listOperationCondition} == "=")##情况一,= 的时候
|
||||
.eqIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "!=")##情况二,!= 的时候
|
||||
.neIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == ">")##情况三,> 的时候
|
||||
.gtIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == ">=")##情况四,>= 的时候
|
||||
.geIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "<")##情况五,< 的时候
|
||||
.ltIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "<=")##情况五,<= 的时候
|
||||
.leIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "LIKE")##情况七,Like 的时候
|
||||
.likeIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "BETWEEN")##情况八,Between 的时候
|
||||
.betweenIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
/**
|
||||
* ${table.classComment} Mapper
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@Mapper
|
||||
public interface ${table.className}Mapper extends BaseMapperX<${table.className}DO> {
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
default PageResult<${table.className}DO> selectPage(${sceneEnum.prefixClass}${table.className}PageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<${table.className}DO>()
|
||||
#listCondition()
|
||||
.orderByDesc(${table.className}DO::getId));## 大多数情况下,id 倒序
|
||||
|
||||
}
|
||||
#else
|
||||
default List<${table.className}DO> selectList(${sceneEnum.prefixClass}${table.className}ListReqVO reqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<${table.className}DO>()
|
||||
#listCondition()
|
||||
.orderByDesc(${table.className}DO::getId));## 大多数情况下,id 倒序
|
||||
|
||||
}
|
||||
#end
|
||||
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
|
||||
default ${table.className}DO selectBy${TreeParentJavaField}And${TreeNameJavaField}(Long ${treeParentColumn.javaField}, String ${treeNameColumn.javaField}) {
|
||||
return selectOne(${table.className}DO::get${TreeParentJavaField}, ${treeParentColumn.javaField}, ${table.className}DO::get${TreeNameJavaField}, ${treeNameColumn.javaField});
|
||||
}
|
||||
|
||||
default Long selectCountBy${TreeParentJavaField}(${treeParentColumn.javaType} ${treeParentColumn.javaField}) {
|
||||
return selectCount(${table.className}DO::get${TreeParentJavaField}, ${treeParentColumn.javaField});
|
||||
}
|
||||
|
||||
#end
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,57 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subJoinColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
package ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName};
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ${PageResultClassName};
|
||||
import ${PageParamClassName};
|
||||
import ${QueryWrapperClassName};
|
||||
import ${BaseMapperClassName};
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* ${subTable.classComment} Mapper
|
||||
*
|
||||
* @author ${subTable.author}
|
||||
*/
|
||||
@Mapper
|
||||
public interface ${subTable.className}Mapper extends BaseMapperX<${subTable.className}DO> {
|
||||
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
default PageResult<${subTable.className}DO> selectPage(PageParam reqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<${subTable.className}DO>()
|
||||
.eq(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField})
|
||||
.orderByDesc(${subTable.className}DO::getId));## 大多数情况下,id 倒序
|
||||
|
||||
}
|
||||
## 主表与子表是一对一时
|
||||
#if (!$subTable.subJoinMany)
|
||||
default ${subTable.className}DO selectBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return selectOne(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
|
||||
}
|
||||
#end
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany)
|
||||
default List<${subTable.className}DO> selectListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return selectList(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#else
|
||||
default ${subTable.className}DO selectBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return selectOne(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
default int deleteBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return delete(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// TODO 待办:请将下面的错误码复制到 yudao-module-${table.moduleName}-api 模块的 ErrorCodeConstants 类中。注意,请给“TODO 补充编号”设置一个错误码编号!!!
|
||||
// ========== ${table.classComment} TODO 补充编号 ==========
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS = new ErrorCode(TODO 补充编号, "${table.classComment}不存在");
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_EXITS_CHILDREN = new ErrorCode(TODO 补充编号, "存在存在子${table.classComment},无法删除");
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_PARENT_NOT_EXITS = new ErrorCode(TODO 补充编号,"父级${table.classComment}不存在");
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_PARENT_ERROR = new ErrorCode(TODO 补充编号, "不能设置自己为父${table.classComment}");
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE = new ErrorCode(TODO 补充编号, "已经存在该${treeNameColumn.columnComment}的${table.classComment}");
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_PARENT_IS_CHILD = new ErrorCode(TODO 补充编号, "不能设置自己的子${table.className}为父${table.className}");
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 )## 特殊:ERP 情况
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($simpleClassNameUnderlineCase = $simpleClassNameUnderlineCases.get($index))
|
||||
ErrorCode ${simpleClassNameUnderlineCase.toUpperCase()}_NOT_EXISTS = new ErrorCode(TODO 补充编号, "${subTable.classComment}不存在");
|
||||
#if ( !$subTable.subJoinMany )
|
||||
ErrorCode ${simpleClassNameUnderlineCase.toUpperCase()}_EXISTS = new ErrorCode(TODO 补充编号, "${subTable.classComment}已存在");
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
@@ -0,0 +1,147 @@
|
||||
package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
|
||||
|
||||
import java.util.*;
|
||||
import ${jakartaPackage}.validation.*;
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
#end
|
||||
import ${PageResultClassName};
|
||||
import ${PageParamClassName};
|
||||
|
||||
/**
|
||||
* ${table.classComment} Service 接口
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
public interface ${table.className}Service {
|
||||
|
||||
/**
|
||||
* 创建${table.classComment}
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
${primaryColumn.javaType} create${simpleClassName}(@Valid ${sceneEnum.prefixClass}${table.className}SaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新${table.classComment}
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void update${simpleClassName}(@Valid ${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除${table.classComment}
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void delete${simpleClassName}(${primaryColumn.javaType} id);
|
||||
|
||||
/**
|
||||
* 获得${table.classComment}
|
||||
*
|
||||
* @param id 编号
|
||||
* @return ${table.classComment}
|
||||
*/
|
||||
${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id);
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
/**
|
||||
* 获得${table.classComment}分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return ${table.classComment}分页
|
||||
*/
|
||||
PageResult<${table.className}DO> get${simpleClassName}Page(${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO);
|
||||
#else
|
||||
/**
|
||||
* 获得${table.classComment}列表
|
||||
*
|
||||
* @param listReqVO 查询条件
|
||||
* @return ${table.classComment}列表
|
||||
*/
|
||||
List<${table.className}DO> get${simpleClassName}List(${sceneEnum.prefixClass}${table.className}ListReqVO listReqVO);
|
||||
#end
|
||||
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
/**
|
||||
* 获得${subTable.classComment}分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
|
||||
* @return ${subTable.classComment}分页
|
||||
*/
|
||||
PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField});
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
/**
|
||||
* 获得${subTable.classComment}列表
|
||||
*
|
||||
* @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
|
||||
* @return ${subTable.classComment}列表
|
||||
*/
|
||||
List<${subTable.className}DO> get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField});
|
||||
|
||||
#else
|
||||
/**
|
||||
* 获得${subTable.classComment}
|
||||
*
|
||||
* @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
|
||||
* @return ${subTable.classComment}
|
||||
*/
|
||||
${subTable.className}DO get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField});
|
||||
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
/**
|
||||
* 创建${subTable.classComment}
|
||||
*
|
||||
* @param ${subClassNameVar} 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
${subPrimaryColumn.javaType} create${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar});
|
||||
|
||||
/**
|
||||
* 更新${subTable.classComment}
|
||||
*
|
||||
* @param ${subClassNameVar} 更新信息
|
||||
*/
|
||||
void update${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar});
|
||||
|
||||
/**
|
||||
* 删除${subTable.classComment}
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void delete${subSimpleClassName}(${subPrimaryColumn.javaType} id);
|
||||
|
||||
/**
|
||||
* 获得${subTable.classComment}
|
||||
*
|
||||
* @param id 编号
|
||||
* @return ${subTable.classComment}
|
||||
*/
|
||||
${subTable.className}DO get${subSimpleClassName}(${subPrimaryColumn.javaType} id);
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ${jakartaPackage}.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
#end
|
||||
import ${PageResultClassName};
|
||||
import ${PageParamClassName};
|
||||
import ${BeanUtils};
|
||||
|
||||
import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName}.${subTable.className}Mapper;
|
||||
#end
|
||||
|
||||
import static ${ServiceExceptionUtilClassName}.exception;
|
||||
import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* ${table.classComment} Service 实现类
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ${table.className}ServiceImpl implements ${table.className}Service {
|
||||
|
||||
@Resource
|
||||
private ${table.className}Mapper ${classNameVar}Mapper;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
@Resource
|
||||
private ${subTable.className}Mapper ${subClassNameVars.get($index)}Mapper;
|
||||
#end
|
||||
|
||||
@Override
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
#end
|
||||
public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}SaveReqVO createReqVO) {
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
|
||||
// 校验${treeParentColumn.columnComment}的有效性
|
||||
validateParent${simpleClassName}(null, createReqVO.get${TreeParentJavaField}());
|
||||
// 校验${treeNameColumn.columnComment}的唯一性
|
||||
validate${simpleClassName}${TreeNameJavaField}Unique(null, createReqVO.get${TreeParentJavaField}(), createReqVO.get${TreeNameJavaField}());
|
||||
|
||||
#end
|
||||
// 插入
|
||||
${table.className}DO ${classNameVar} = BeanUtils.toBean(createReqVO, ${table.className}DO.class);
|
||||
${classNameVar}Mapper.insert(${classNameVar});
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
|
||||
// 插入子表
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#if ( $subTable.subJoinMany)
|
||||
create${subSimpleClassName}List(${classNameVar}.getId(), createReqVO.get${subSimpleClassNames.get($index)}s());
|
||||
#else
|
||||
create${subSimpleClassName}(${classNameVar}.getId(), createReqVO.get${subSimpleClassNames.get($index)}());
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
// 返回
|
||||
return ${classNameVar}.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
#end
|
||||
public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validate${simpleClassName}Exists(updateReqVO.getId());
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
|
||||
// 校验${treeParentColumn.columnComment}的有效性
|
||||
validateParent${simpleClassName}(updateReqVO.getId(), updateReqVO.get${TreeParentJavaField}());
|
||||
// 校验${treeNameColumn.columnComment}的唯一性
|
||||
validate${simpleClassName}${TreeNameJavaField}Unique(updateReqVO.getId(), updateReqVO.get${TreeParentJavaField}(), updateReqVO.get${TreeNameJavaField}());
|
||||
|
||||
#end
|
||||
// 更新
|
||||
${table.className}DO updateObj = BeanUtils.toBean(updateReqVO, ${table.className}DO.class);
|
||||
${classNameVar}Mapper.updateById(updateObj);
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11)
|
||||
|
||||
// 更新子表
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#if ( $subTable.subJoinMany)
|
||||
update${subSimpleClassName}List(updateReqVO.getId(), updateReqVO.get${subSimpleClassNames.get($index)}s());
|
||||
#else
|
||||
update${subSimpleClassName}(updateReqVO.getId(), updateReqVO.get${subSimpleClassNames.get($index)}());
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
@Override
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $subTables && $subTables.size() > 0)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
#end
|
||||
public void delete${simpleClassName}(${primaryColumn.javaType} id) {
|
||||
// 校验存在
|
||||
validate${simpleClassName}Exists(id);
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($ParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
// 校验是否有子${table.classComment}
|
||||
if (${classNameVar}Mapper.selectCountBy${ParentJavaField}(id) > 0) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_EXITS_CHILDREN);
|
||||
}
|
||||
#end
|
||||
// 删除
|
||||
${classNameVar}Mapper.deleteById(id);
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $subTables && $subTables.size() > 0)
|
||||
|
||||
// 删除子表
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
delete${subSimpleClassName}By${SubJoinColumnName}(id);
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
private void validate${simpleClassName}Exists(${primaryColumn.javaType} id) {
|
||||
if (${classNameVar}Mapper.selectById(id) == null) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
|
||||
private void validateParent${simpleClassName}(Long id, Long ${treeParentColumn.javaField}) {
|
||||
if (${treeParentColumn.javaField} == null || ${simpleClassName}DO.${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT.equals(${treeParentColumn.javaField})) {
|
||||
return;
|
||||
}
|
||||
// 1. 不能设置自己为父${table.classComment}
|
||||
if (Objects.equals(id, ${treeParentColumn.javaField})) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_ERROR);
|
||||
}
|
||||
// 2. 父${table.classComment}不存在
|
||||
${simpleClassName}DO parent${simpleClassName} = ${classNameVar}Mapper.selectById(${treeParentColumn.javaField});
|
||||
if (parent${simpleClassName} == null) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_NOT_EXITS);
|
||||
}
|
||||
// 3. 递归校验父${table.classComment},如果父${table.classComment}是自己的子${table.classComment},则报错,避免形成环路
|
||||
if (id == null) { // id 为空,说明新增,不需要考虑环路
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < Short.MAX_VALUE; i++) {
|
||||
// 3.1 校验环路
|
||||
${treeParentColumn.javaField} = parent${simpleClassName}.get${TreeParentJavaField}();
|
||||
if (Objects.equals(id, ${treeParentColumn.javaField})) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_IS_CHILD);
|
||||
}
|
||||
// 3.2 继续递归下一级父${table.classComment}
|
||||
if (${treeParentColumn.javaField} == null || ${simpleClassName}DO.${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT.equals(${treeParentColumn.javaField})) {
|
||||
break;
|
||||
}
|
||||
parent${simpleClassName} = ${classNameVar}Mapper.selectById(${treeParentColumn.javaField});
|
||||
if (parent${simpleClassName} == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validate${simpleClassName}${TreeNameJavaField}Unique(Long id, Long ${treeParentColumn.javaField}, String ${treeNameColumn.javaField}) {
|
||||
${simpleClassName}DO ${classNameVar} = ${classNameVar}Mapper.selectBy${TreeParentJavaField}And${TreeNameJavaField}(${treeParentColumn.javaField}, ${treeNameColumn.javaField});
|
||||
if (${classNameVar} == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的${table.classComment}
|
||||
if (id == null) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE);
|
||||
}
|
||||
if (!Objects.equals(${classNameVar}.getId(), id)) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
#end
|
||||
@Override
|
||||
public ${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id) {
|
||||
return ${classNameVar}Mapper.selectById(id);
|
||||
}
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
@Override
|
||||
public PageResult<${table.className}DO> get${simpleClassName}Page(${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO) {
|
||||
return ${classNameVar}Mapper.selectPage(pageReqVO);
|
||||
}
|
||||
#else
|
||||
@Override
|
||||
public List<${table.className}DO> get${simpleClassName}List(${sceneEnum.prefixClass}${table.className}ListReqVO listReqVO) {
|
||||
return ${classNameVar}Mapper.selectList(listReqVO);
|
||||
}
|
||||
#end
|
||||
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($simpleClassNameUnderlineCase = $simpleClassNameUnderlineCases.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
@Override
|
||||
public PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return ${subClassNameVars.get($index)}Mapper.selectPage(pageReqVO, ${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
@Override
|
||||
public List<${subTable.className}DO> get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return ${subClassNameVars.get($index)}Mapper.selectListBy${SubJoinColumnName}(${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#else
|
||||
@Override
|
||||
public ${subTable.className}DO get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return ${subClassNameVars.get($index)}Mapper.selectBy${SubJoinColumnName}(${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
## 情况一:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
@Override
|
||||
public ${subPrimaryColumn.javaType} create${subSimpleClassName}(${subTable.className}DO ${subClassNameVar}) {
|
||||
## 特殊:一对一时,需要保证只有一条,不能重复插入
|
||||
#if ( !$subTable.subJoinMany)
|
||||
// 校验是否已经存在
|
||||
if (${subClassNameVars.get($index)}Mapper.selectBy${SubJoinColumnName}(${subClassNameVar}.get${SubJoinColumnName}()) != null) {
|
||||
throw exception(${simpleClassNameUnderlineCase.toUpperCase()}_EXISTS);
|
||||
}
|
||||
// 插入
|
||||
#end
|
||||
${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
|
||||
return ${subClassNameVar}.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update${subSimpleClassName}(${subTable.className}DO ${subClassNameVar}) {
|
||||
// 校验存在
|
||||
validate${subSimpleClassName}Exists(${subClassNameVar}.getId());
|
||||
// 更新
|
||||
${subClassNameVar}.setUpdater(null).setUpdateTime(null); // 解决更新情况下:updateTime 不更新
|
||||
${subClassNameVars.get($index)}Mapper.updateById(${subClassNameVar});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete${subSimpleClassName}(${subPrimaryColumn.javaType} id) {
|
||||
// 校验存在
|
||||
validate${subSimpleClassName}Exists(id);
|
||||
// 删除
|
||||
${subClassNameVars.get($index)}Mapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ${subTable.className}DO get${subSimpleClassName}(${subPrimaryColumn.javaType} id) {
|
||||
return ${subClassNameVars.get($index)}Mapper.selectById(id);
|
||||
}
|
||||
|
||||
private void validate${subSimpleClassName}Exists(${subPrimaryColumn.javaType} id) {
|
||||
if (${subClassNameVar}Mapper.selectById(id) == null) {
|
||||
throw exception(${simpleClassNameUnderlineCase.toUpperCase()}_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,支持批量的新增、修改操作
|
||||
#else
|
||||
#if ( $subTable.subJoinMany)
|
||||
private void create${subSimpleClassName}List(${primaryColumn.javaType} ${subJoinColumn.javaField}, List<${subTable.className}DO> list) {
|
||||
list.forEach(o -> o.set$SubJoinColumnName(${subJoinColumn.javaField}));
|
||||
${subClassNameVars.get($index)}Mapper.insertBatch(list);
|
||||
}
|
||||
|
||||
private void update${subSimpleClassName}List(${primaryColumn.javaType} ${subJoinColumn.javaField}, List<${subTable.className}DO> list) {
|
||||
delete${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField});
|
||||
list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新
|
||||
create${subSimpleClassName}List(${subJoinColumn.javaField}, list);
|
||||
}
|
||||
|
||||
#else
|
||||
private void create${subSimpleClassName}(${primaryColumn.javaType} ${subJoinColumn.javaField}, ${subTable.className}DO ${subClassNameVar}) {
|
||||
if (${subClassNameVar} == null) {
|
||||
return;
|
||||
}
|
||||
${subClassNameVar}.set$SubJoinColumnName(${subJoinColumn.javaField});
|
||||
${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
|
||||
}
|
||||
|
||||
private void update${subSimpleClassName}(${primaryColumn.javaType} ${subJoinColumn.javaField}, ${subTable.className}DO ${subClassNameVar}) {
|
||||
if (${subClassNameVar} == null) {
|
||||
return;
|
||||
}
|
||||
${subClassNameVar}.set$SubJoinColumnName(${subJoinColumn.javaField});
|
||||
${subClassNameVar}.setUpdater(null).setUpdateTime(null); // 解决更新情况下:updateTime 不更新
|
||||
${subClassNameVars.get($index)}Mapper.insertOrUpdate(${subClassNameVar});
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
private void delete${subSimpleClassName}By${SubJoinColumnName}(${primaryColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#end
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import ${jakartaPackage}.annotation.Resource;
|
||||
|
||||
import ${baseFrameworkPackage}.test.core.ut.BaseDbUnitTest;
|
||||
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
|
||||
import ${PageResultClassName};
|
||||
|
||||
import ${jakartaPackage}.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*;
|
||||
import static ${baseFrameworkPackage}.test.core.util.AssertUtils.*;
|
||||
import static ${baseFrameworkPackage}.test.core.util.RandomUtils.*;
|
||||
import static ${LocalDateTimeUtilsClassName}.*;
|
||||
import static ${ObjectUtilsClassName}.*;
|
||||
import static ${DateUtilsClassName}.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
## 字段模板
|
||||
#macro(getPageCondition $VO)
|
||||
// mock 数据
|
||||
${table.className}DO db${simpleClassName} = randomPojo(${table.className}DO.class, o -> { // 等会查询到
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})
|
||||
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
|
||||
o.set$JavaField(null);
|
||||
#end
|
||||
#end
|
||||
});
|
||||
${classNameVar}Mapper.insert(db${simpleClassName});
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})
|
||||
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
|
||||
// 测试 ${column.javaField} 不匹配
|
||||
${classNameVar}Mapper.insert(cloneIgnoreId(db${simpleClassName}, o -> o.set$JavaField(null)));
|
||||
#end
|
||||
#end
|
||||
// 准备参数
|
||||
${sceneEnum.prefixClass}${table.className}${VO} reqVO = new ${sceneEnum.prefixClass}${table.className}${VO}();
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})
|
||||
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
|
||||
#if (${column.listOperationCondition} == "BETWEEN")## BETWEEN 的情况
|
||||
reqVO.set${JavaField}(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
#else
|
||||
reqVO.set$JavaField(null);
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
/**
|
||||
* {@link ${table.className}ServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@Import(${table.className}ServiceImpl.class)
|
||||
public class ${table.className}ServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private ${table.className}ServiceImpl ${classNameVar}Service;
|
||||
|
||||
@Resource
|
||||
private ${table.className}Mapper ${classNameVar}Mapper;
|
||||
|
||||
@Test
|
||||
public void testCreate${simpleClassName}_success() {
|
||||
// 准备参数
|
||||
${sceneEnum.prefixClass}${table.className}SaveReqVO createReqVO = randomPojo(${sceneEnum.prefixClass}${table.className}SaveReqVO.class).setId(null);
|
||||
|
||||
// 调用
|
||||
${primaryColumn.javaType} ${classNameVar}Id = ${classNameVar}Service.create${simpleClassName}(createReqVO);
|
||||
// 断言
|
||||
assertNotNull(${classNameVar}Id);
|
||||
// 校验记录的属性是否正确
|
||||
${table.className}DO ${classNameVar} = ${classNameVar}Mapper.selectById(${classNameVar}Id);
|
||||
assertPojoEquals(createReqVO, ${classNameVar}, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate${simpleClassName}_success() {
|
||||
// mock 数据
|
||||
${table.className}DO db${simpleClassName} = randomPojo(${table.className}DO.class);
|
||||
${classNameVar}Mapper.insert(db${simpleClassName});// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO = randomPojo(${sceneEnum.prefixClass}${table.className}SaveReqVO.class, o -> {
|
||||
o.setId(db${simpleClassName}.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
${classNameVar}Service.update${simpleClassName}(updateReqVO);
|
||||
// 校验是否更新正确
|
||||
${table.className}DO ${classNameVar} = ${classNameVar}Mapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(updateReqVO, ${classNameVar});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate${simpleClassName}_notExists() {
|
||||
// 准备参数
|
||||
${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO = randomPojo(${sceneEnum.prefixClass}${table.className}SaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> ${classNameVar}Service.update${simpleClassName}(updateReqVO), ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete${simpleClassName}_success() {
|
||||
// mock 数据
|
||||
${table.className}DO db${simpleClassName} = randomPojo(${table.className}DO.class);
|
||||
${classNameVar}Mapper.insert(db${simpleClassName});// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
${primaryColumn.javaType} id = db${simpleClassName}.getId();
|
||||
|
||||
// 调用
|
||||
${classNameVar}Service.delete${simpleClassName}(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(${classNameVar}Mapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete${simpleClassName}_notExists() {
|
||||
// 准备参数
|
||||
${primaryColumn.javaType} id = random${primaryColumn.javaType}Id();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> ${classNameVar}Service.delete${simpleClassName}(id), ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS);
|
||||
}
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGet${simpleClassName}Page() {
|
||||
#getPageCondition("PageReqVO")
|
||||
|
||||
// 调用
|
||||
PageResult<${table.className}DO> pageResult = ${classNameVar}Service.get${simpleClassName}Page(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(db${simpleClassName}, pageResult.getList().get(0));
|
||||
}
|
||||
#else
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGet${simpleClassName}List() {
|
||||
#getPageCondition("ListReqVO")
|
||||
|
||||
// 调用
|
||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(db${simpleClassName}, list.get(0));
|
||||
}
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
-- 将该建表 SQL 语句,添加到 yudao-module-${table.moduleName}-biz 模块的 test/resources/sql/create_tableslogin.sql 文件里
|
||||
CREATE TABLE IF NOT EXISTS "${table.tableName.toLowerCase()}" (
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == 'Long')
|
||||
#set ($dataType='bigint')
|
||||
#elseif (${column.javaType} == 'Integer')
|
||||
#set ($dataType='int')
|
||||
#elseif (${column.javaType} == 'Boolean')
|
||||
#set ($dataType='bit')
|
||||
#elseif (${column.javaType} == 'Date')
|
||||
#set ($dataType='datetime')
|
||||
#else
|
||||
#set ($dataType='varchar')
|
||||
#end
|
||||
#if (${column.primaryKey})##处理主键
|
||||
"${column.javaField}"#if (${column.javaType} == 'String') ${dataType} NOT NULL#else ${dataType} NOT NULL GENERATED BY DEFAULT AS IDENTITY#end,
|
||||
#else
|
||||
#if (${column.columnName} == 'create_time')
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
#elseif (${column.columnName} == 'update_time')
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
#elseif (${column.columnName} == 'creator' || ${column.columnName} == 'updater')
|
||||
"${column.columnName}" ${dataType} DEFAULT '',
|
||||
#elseif (${column.columnName} == 'deleted')
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
#elseif (${column.columnName} == 'tenant_id')
|
||||
"tenant_id" bigint NOT NULL DEFAULT 0,
|
||||
#else
|
||||
"${column.columnName.toLowerCase()}" ${dataType}#if (${column.nullable} == false) NOT NULL#end,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
PRIMARY KEY ("${primaryColumn.columnName.toLowerCase()}")
|
||||
) COMMENT '${table.tableComment}';
|
||||
|
||||
-- 将该删表 SQL 语句,添加到 yudao-module-${table.moduleName}-biz 模块的 test/resources/sql/cleanlogin.sql 文件里
|
||||
DELETE FROM "${table.tableName}";
|
||||
@@ -0,0 +1,28 @@
|
||||
-- 菜单 SQL
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status, component_name
|
||||
)
|
||||
VALUES (
|
||||
'${table.classComment}管理', '', 2, 0, ${table.parentMenuId},
|
||||
'${simpleClassName_strikeCase}', '', '${table.moduleName}/${table.businessName}/index', 0, '${table.className}'
|
||||
);
|
||||
|
||||
-- 按钮父菜单ID
|
||||
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
|
||||
SELECT @parentId := LAST_INSERT_ID();
|
||||
|
||||
-- 按钮 SQL
|
||||
#set ($functionNames = ['查询', '创建', '更新', '删除', '导出'])
|
||||
#set ($functionOps = ['query', 'create', 'update', 'delete', 'export'])
|
||||
#foreach ($functionName in $functionNames)
|
||||
#set ($index = $foreach.count - 1)
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status
|
||||
)
|
||||
VALUES (
|
||||
'${table.classComment}${functionName}', '${permissionPrefix}:${functionOps.get($index)}', 3, $foreach.count, @parentId,
|
||||
'', '', '', 0
|
||||
);
|
||||
#end
|
||||
@@ -0,0 +1,141 @@
|
||||
import request from '@/utils/request'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
// 创建${table.classComment}
|
||||
export function create${simpleClassName}(data) {
|
||||
return request({
|
||||
url: '${baseURL}/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新${table.classComment}
|
||||
export function update${simpleClassName}(data) {
|
||||
return request({
|
||||
url: '${baseURL}/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除${table.classComment}
|
||||
export function delete${simpleClassName}(id) {
|
||||
return request({
|
||||
url: '${baseURL}/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得${table.classComment}
|
||||
export function get${simpleClassName}(id) {
|
||||
return request({
|
||||
url: '${baseURL}/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
#if ( $table.templateType != 2 )
|
||||
// 获得${table.classComment}分页
|
||||
export function get${simpleClassName}Page(params) {
|
||||
return request({
|
||||
url: '${baseURL}/page',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
#else
|
||||
// 获得${table.classComment}列表
|
||||
export function get${simpleClassName}List(params) {
|
||||
return request({
|
||||
url: '${baseURL}/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
#end
|
||||
// 导出${table.classComment} Excel
|
||||
export function export${simpleClassName}Excel(params) {
|
||||
return request({
|
||||
url: '${baseURL}/export-excel',
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ($table.templateType == 11)
|
||||
// 获得${subTable.classComment}分页
|
||||
export function get${subSimpleClassName}Page(params) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/page',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ($subTable.subJoinMany)
|
||||
// 获得${subTable.classComment}列表
|
||||
export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=' + ${subJoinColumn.javaField},
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
#else
|
||||
// 获得${subTable.classComment}
|
||||
export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=' + ${subJoinColumn.javaField},
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ($table.templateType == 11)
|
||||
// 新增${subTable.classComment}
|
||||
export function create${subSimpleClassName}(data) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 修改${subTable.classComment}
|
||||
export function update${subSimpleClassName}(data) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 删除${subTable.classComment}
|
||||
export function delete${subSimpleClassName}(id) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
// 获得${subTable.classComment}
|
||||
export function get${subSimpleClassName}(id) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
#end
|
||||
#end
|
||||
@@ -0,0 +1,205 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
#set ($hasImageUploadColumn = true)
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<ImageUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
#set ($hasFileUploadColumn = true)
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<FileUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
#set ($hasEditorColumn = true)
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<editor v-model="formData.${javaField}" :min-height="192"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||
#else##没数据字典
|
||||
<el-checkbox>请选择字典生成</el-checkbox>
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
#if ($hasImageUploadColumn)
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
import Editor from '@/components/Editor';
|
||||
#end
|
||||
export default {
|
||||
name: "${subSimpleClassName}Form",
|
||||
components: {
|
||||
#if ($hasImageUploadColumn)
|
||||
ImageUpload,
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
FileUpload,
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
Editor,
|
||||
#end
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 弹出层标题
|
||||
dialogTitle: "",
|
||||
// 是否显示弹出层
|
||||
dialogVisible: false,
|
||||
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
formLoading: false,
|
||||
// 表单参数
|
||||
formData: {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
},
|
||||
// 表单校验
|
||||
formRules: {
|
||||
#foreach ($column in $subColumns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
|
||||
#end
|
||||
#end
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/** 打开弹窗 */
|
||||
async open(id, ${subJoinColumn.javaField}) {
|
||||
this.dialogVisible = true;
|
||||
this.reset();
|
||||
this.formData.${subJoinColumn.javaField} = ${subJoinColumn.javaField};
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
this.formLoading = true;
|
||||
try {
|
||||
const res = await ${simpleClassName}Api.get${subSimpleClassName}(id);
|
||||
this.formData = res.data;
|
||||
this.dialogTitle = "修改${subTable.classComment}";
|
||||
} finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
}
|
||||
this.dialogTitle = "新增${subTable.classComment}";
|
||||
},
|
||||
/** 提交按钮 */
|
||||
async submitForm() {
|
||||
await this.#[[$]]#refs["formRef"].validate();
|
||||
this.formLoading = true;
|
||||
try {
|
||||
const data = this.formData;
|
||||
// 修改的提交
|
||||
if (data.${primaryColumn.javaField}) {
|
||||
await ${simpleClassName}Api.update${subSimpleClassName}(data);
|
||||
this.#[[$modal]]#.msgSuccess("修改成功");
|
||||
this.dialogVisible = false;
|
||||
this.#[[$]]#emit('success');
|
||||
return;
|
||||
}
|
||||
// 添加的提交
|
||||
await ${simpleClassName}Api.create${subSimpleClassName}(data);
|
||||
this.#[[$modal]]#.msgSuccess("新增成功");
|
||||
this.dialogVisible = false;
|
||||
this.#[[$]]#emit('success');
|
||||
}finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
},
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.formData = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
};
|
||||
this.resetForm("formRef");
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,2 @@
|
||||
## 主表的 normal 和 inner 使用相同的 form 表单
|
||||
#parse("codegen/vue/views/components/form_sub_normal.vue.vm")
|
||||
@@ -0,0 +1,347 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
<template>
|
||||
<div class="app-container">
|
||||
#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
v-loading="formLoading"
|
||||
label-width="0px"
|
||||
:inline-message="true"
|
||||
>
|
||||
<el-table :data="formData" class="-mt-10px">
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-input v-model="row.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
#set ($hasImageUploadColumn = true)
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<ImageUpload v-model="row.${javaField}"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
#set ($hasFileUploadColumn = true)
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<FileUpload v-model="row.${javaField}"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
#set ($hasEditorColumn = true)
|
||||
<el-table-column label="${comment}" min-width="400">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<Editor v-model="row.${javaField}" :min-height="192"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-select v-model="row.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-checkbox-group v-model="row.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||
#else##没数据字典
|
||||
<el-checkbox>请选择字典生成</el-checkbox>
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-radio-group v-model="row.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-date-picker clearable v-model="row.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||
<template v-slot="{ $index }">
|
||||
<el-link @click="handleDelete($index)">—</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
<el-row justify="center" class="mt-3">
|
||||
<el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>
|
||||
</el-row>
|
||||
#else## 情况二:一对一,form
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
#set ($hasImageUploadColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<ImageUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
#set ($hasFileUploadColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<FileUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
#set ($hasEditorColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<Editor v-model="formData.${javaField}" :min-height="192"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||
#else##没数据字典
|
||||
<el-checkbox>请选择字典生成</el-checkbox>
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
#end
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
#if ($hasImageUploadColumn)
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
import Editor from '@/components/Editor';
|
||||
#end
|
||||
export default {
|
||||
name: "${subSimpleClassName}Form",
|
||||
components: {
|
||||
#if ($hasImageUploadColumn)
|
||||
ImageUpload,
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
FileUpload,
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
Editor,
|
||||
#end
|
||||
},
|
||||
props:[
|
||||
'${subJoinColumn.javaField}'
|
||||
],// ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
data() {
|
||||
return {
|
||||
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
formLoading: false,
|
||||
// 表单参数
|
||||
formData: [],
|
||||
// 表单校验
|
||||
formRules: {
|
||||
#foreach ($column in $subColumns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
|
||||
#end
|
||||
#end
|
||||
},
|
||||
};
|
||||
},
|
||||
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
${subJoinColumn.javaField}:{
|
||||
handler(val) {
|
||||
// 1. 重置表单
|
||||
#if ( $subTable.subJoinMany )
|
||||
this.formData = []
|
||||
#else
|
||||
this.formData = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
#end
|
||||
// 2. val 非空,则加载数据
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.formLoading = true;
|
||||
// 这里还是需要获取一下 this 的不然取不到 formData
|
||||
const that = this;
|
||||
#if ( $subTable.subJoinMany )
|
||||
${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val).then(function (res){
|
||||
that.formData = res.data;
|
||||
})
|
||||
#else
|
||||
${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val).then(function (res){
|
||||
const data = res.data;
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
that.formData = data;
|
||||
})
|
||||
#end
|
||||
} finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
#if ( $subTable.subJoinMany )
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
const row = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
row.${subJoinColumn.javaField} = this.${subJoinColumn.javaField};
|
||||
this.formData.push(row);
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(index) {
|
||||
this.formData.splice(index, 1);
|
||||
},
|
||||
#end
|
||||
/** 表单校验 */
|
||||
validate(){
|
||||
return this.#[[$]]#refs["formRef"].validate();
|
||||
},
|
||||
/** 表单值 */
|
||||
getData(){
|
||||
return this.formData;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,165 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
<template>
|
||||
<div class="app-container">
|
||||
#if ($table.templateType == 11)
|
||||
<!-- 操作工具栏 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||
v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
#end
|
||||
## 列表
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.javaType == "LocalDateTime")## 时间类型
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
|
||||
<template v-slot="scope">
|
||||
<span>{{ parseTime(scope.row.${javaField}) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template v-slot="scope">
|
||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template v-slot="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.${primaryColumn.javaField})"
|
||||
v-hasPermi="['${permissionPrefix}:update']">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||
v-hasPermi="['${permissionPrefix}:delete']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
#if ($table.templateType == 11)
|
||||
<!-- 分页组件 -->
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"/>
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<${subSimpleClassName}Form ref="formRef" @success="getList" />
|
||||
#end
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
#if ($table.templateType == 11)
|
||||
import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue';
|
||||
#end
|
||||
export default {
|
||||
name: "${subSimpleClassName}List",
|
||||
#if ($table.templateType == 11)
|
||||
components: {
|
||||
${subSimpleClassName}Form
|
||||
},
|
||||
#end
|
||||
props:[
|
||||
'${subJoinColumn.javaField}'
|
||||
],// ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 列表的数据
|
||||
list: [],
|
||||
#if ($table.templateType == 11)
|
||||
// 列表的总页数
|
||||
total: 0,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
${subJoinColumn.javaField}: undefined
|
||||
}
|
||||
#end
|
||||
};
|
||||
},
|
||||
#if ($table.templateType != 11)
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
#end
|
||||
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
${subJoinColumn.javaField}:{
|
||||
handler(val) {
|
||||
this.queryParams.${subJoinColumn.javaField} = val;
|
||||
if (val){
|
||||
this.handleQuery();
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 查询列表 */
|
||||
async getList() {
|
||||
try {
|
||||
this.loading = true;
|
||||
#if ($table.templateType == 11)
|
||||
const res = await ${simpleClassName}Api.get${subSimpleClassName}Page(this.queryParams);
|
||||
this.list = res.data.list;
|
||||
this.total = res.data.total;
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
const res = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(this.${subJoinColumn.javaField});
|
||||
this.list = res.data;
|
||||
#else
|
||||
const res = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(this.${subJoinColumn.javaField});
|
||||
const data = res.data;
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
this.list.push(data);
|
||||
#end
|
||||
#end
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNo = 1;
|
||||
this.getList();
|
||||
},
|
||||
#if ($table.templateType == 11)
|
||||
/** 添加/修改操作 */
|
||||
openForm(id) {
|
||||
if (!this.${subJoinColumn.javaField}) {
|
||||
this.#[[$modal]]#.msgError('请选择一个${table.classComment}');
|
||||
return;
|
||||
}
|
||||
this.#[[$]]#refs["formRef"].open(id, this.${subJoinColumn.javaField});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
async handleDelete(row) {
|
||||
const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
|
||||
await this.#[[$modal]]#.confirm('是否确认删除${table.classComment}编号为"' + ${primaryColumn.javaField} + '"的数据项?');
|
||||
try {
|
||||
await ${simpleClassName}Api.delete${subSimpleClassName}(${primaryColumn.javaField});
|
||||
await this.getList();
|
||||
this.#[[$modal]]#.msgSuccess("删除成功");
|
||||
} catch {}
|
||||
},
|
||||
#end
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,4 @@
|
||||
## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
|
||||
## 1)inner 使用 list 不分页,erp 使用 page 分页
|
||||
## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
|
||||
#parse("codegen/vue/views/components/list_sub_erp.vue.vm")
|
||||
@@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||
#foreach($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<TreeSelect
|
||||
v-model="formData.${javaField}"
|
||||
:options="${classNameVar}Tree"
|
||||
:normalizer="normalizer"
|
||||
placeholder="请选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
#set ($hasImageUploadColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<ImageUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
#set ($hasFileUploadColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<FileUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
#set ($hasEditorColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<Editor v-model="formData.${javaField}" :min-height="192"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||
#else##没数据字典
|
||||
<el-checkbox>请选择字典生成</el-checkbox>
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
<!-- 子表的表单 -->
|
||||
<el-tabs v-model="subTabsName">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
#end
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
#if ($hasImageUploadColumn)
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
import Editor from '@/components/Editor';
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
import TreeSelect from "@riophae/vue-treeselect";
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
|
||||
#end
|
||||
#end
|
||||
export default {
|
||||
name: "${simpleClassName}Form",
|
||||
components: {
|
||||
#if ($hasImageUploadColumn)
|
||||
ImageUpload,
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
FileUpload,
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
Editor,
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
TreeSelect,
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
${subSimpleClassName}Form,
|
||||
#end
|
||||
#end
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 弹出层标题
|
||||
dialogTitle: "",
|
||||
// 是否显示弹出层
|
||||
dialogVisible: false,
|
||||
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
formLoading: false,
|
||||
// 表单参数
|
||||
formData: {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
},
|
||||
// 表单校验
|
||||
formRules: {
|
||||
#foreach ($column in $columns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||
#end
|
||||
#end
|
||||
},
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
${classNameVar}Tree: [], // 树形结构
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
/** 子表的表单 */
|
||||
subTabsName: '$subClassNameVars.get(0)'
|
||||
#end
|
||||
#end
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/** 打开弹窗 */
|
||||
async open(id) {
|
||||
this.dialogVisible = true;
|
||||
this.reset();
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
this.formLoading = true;
|
||||
try {
|
||||
const res = await ${simpleClassName}Api.get${simpleClassName}(id);
|
||||
this.formData = res.data;
|
||||
this.title = "修改${table.classComment}";
|
||||
} finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
}
|
||||
this.title = "新增${table.classComment}";
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
await this.get${simpleClassName}Tree();
|
||||
#end
|
||||
},
|
||||
/** 提交按钮 */
|
||||
async submitForm() {
|
||||
// 校验主表
|
||||
await this.$refs["formRef"].validate();
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
// 校验子表
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
try {
|
||||
## 代码生成后会替换为正确的 refs
|
||||
await this.refs['${subClassNameVar}FormRef'].validate();
|
||||
} catch (e) {
|
||||
this.subTabsName = '${subClassNameVar}';
|
||||
return;
|
||||
}
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
this.formLoading = true;
|
||||
try {
|
||||
const data = this.formData;
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
// 拼接子表的数据
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = this.refs['${subClassNameVar}FormRef'].getData();
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
// 修改的提交
|
||||
if (data.${primaryColumn.javaField}) {
|
||||
await ${simpleClassName}Api.update${simpleClassName}(data);
|
||||
this.#[[$modal]]#.msgSuccess("修改成功");
|
||||
this.dialogVisible = false;
|
||||
this.#[[$]]#emit('success');
|
||||
return;
|
||||
}
|
||||
// 添加的提交
|
||||
await ${simpleClassName}Api.create${simpleClassName}(data);
|
||||
this.#[[$modal]]#.msgSuccess("新增成功");
|
||||
this.dialogVisible = false;
|
||||
this.#[[$]]#emit('success');
|
||||
} finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
},
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
/** 获得${table.classComment}树 */
|
||||
async get${simpleClassName}Tree() {
|
||||
this.${classNameVar}Tree = [];
|
||||
const res = await ${simpleClassName}Api.get${simpleClassName}List();
|
||||
const root = { id: 0, name: '顶级${table.classComment}', children: [] };
|
||||
root.children = this.handleTree(res.data, 'id', '${treeParentColumn.javaField}')
|
||||
this.${classNameVar}Tree.push(root)
|
||||
},
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
/** 转换${table.classComment}数据结构 */
|
||||
normalizer(node) {
|
||||
if (node.children && !node.children.length) {
|
||||
delete node.children;
|
||||
}
|
||||
#if ($treeNameColumn.javaField == "name")
|
||||
return {
|
||||
id: node.id,
|
||||
label: node.name,
|
||||
children: node.children
|
||||
};
|
||||
#else
|
||||
return {
|
||||
id: node.id,
|
||||
label: node['$treeNameColumn.javaField'],
|
||||
children: node.children
|
||||
};
|
||||
#end
|
||||
},
|
||||
#end
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.formData = {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
};
|
||||
this.resetForm("formRef");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,340 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($column.htmlType == "input")
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="queryParams.${javaField}" placeholder="请输入${comment}" clearable @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="queryParams.${javaField}" placeholder="请选择${comment}" clearable size="small">
|
||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
#else## 未设置 dictType 数据字典的情况
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")
|
||||
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker clearable v-model="queryParams.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
#else## 范围
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker v-model="queryParams.${javaField}" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
||||
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 操作工具栏 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||
v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
||||
v-hasPermi="['${permissionPrefix}:export']">导出</el-button>
|
||||
</el-col>
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">
|
||||
展开/折叠
|
||||
</el-button>
|
||||
</el-col>
|
||||
#end
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:highlight-current-row="true"
|
||||
:show-overflow-tooltip="true"
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
## 特殊:树表专属逻辑
|
||||
#elseif ( $table.templateType == 2 )
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
v-if="refreshTable"
|
||||
row-key="id"
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||
>
|
||||
#else
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
|
||||
<!-- 子表的列表 -->
|
||||
<el-table-column type="expand">
|
||||
<template #default="scope">
|
||||
<el-tabs value="$subClassNameVars.get(0)">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
|
||||
<template v-slot="scope">
|
||||
<span>{{ parseTime(scope.row.${javaField}) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif("" != $column.dictType)## 数据字典
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template v-slot="scope">
|
||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template v-slot="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.${primaryColumn.javaField})"
|
||||
v-hasPermi="['${permissionPrefix}:update']">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||
v-hasPermi="['${permissionPrefix}:delete']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
## 特殊:树表专属逻辑(树不需要分页)
|
||||
#if ( $table.templateType != 2 )
|
||||
<!-- 分页组件 -->
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"/>
|
||||
#end
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<${simpleClassName}Form ref="formRef" @success="getList" />
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||
<!-- 子表的列表 -->
|
||||
<el-tabs v-model="subTabsName">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}List v-if="currentRow.id" :${subJoinColumn_strikeCase}="currentRow.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
#end
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
import ${simpleClassName}Form from './${simpleClassName}Form.vue';
|
||||
#if ($hasImageUploadColumn)
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
import Editor from '@/components/Editor';
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType != 10 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue';
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
export default {
|
||||
name: "${simpleClassName}",
|
||||
components: {
|
||||
${simpleClassName}Form,
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType != 10 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
${subSimpleClassName}List,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#if ($hasImageUploadColumn)
|
||||
ImageUpload,
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
FileUpload,
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
Editor,
|
||||
#end
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 导出遮罩层
|
||||
exportLoading: false,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
// 总条数
|
||||
total: 0,
|
||||
#end
|
||||
// ${table.classComment}列表
|
||||
list: [],
|
||||
// 是否展开,默认全部展开
|
||||
isExpandAll: true,
|
||||
// 重新渲染表格状态
|
||||
refreshTable: true,
|
||||
// 选中行
|
||||
currentRow: {},
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
#end
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#if ($column.listOperationCondition != 'BETWEEN')
|
||||
$column.javaField: null,
|
||||
#end
|
||||
#if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||
$column.javaField: [],
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
},
|
||||
## 特殊:主子表专属逻辑-erp
|
||||
#if ( $table.templateType == 11)
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
/** 子表的列表 */
|
||||
subTabsName: '$subClassNameVars.get(0)'
|
||||
#end
|
||||
#end
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询列表 */
|
||||
async getList() {
|
||||
try {
|
||||
this.loading = true;
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType == 2 )
|
||||
const res = await ${simpleClassName}Api.get${simpleClassName}List(this.queryParams);
|
||||
this.list = this.handleTree(res.data, 'id', '${treeParentColumn.javaField}');
|
||||
#else
|
||||
const res = await ${simpleClassName}Api.get${simpleClassName}Page(this.queryParams);
|
||||
this.list = res.data.list;
|
||||
this.total = res.data.total;
|
||||
#end
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNo = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 添加/修改操作 */
|
||||
openForm(id) {
|
||||
this.#[[$]]#refs["formRef"].open(id);
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
async handleDelete(row) {
|
||||
const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
|
||||
await this.#[[$modal]]#.confirm('是否确认删除${table.classComment}编号为"' + ${primaryColumn.javaField} + '"的数据项?')
|
||||
try {
|
||||
await ${simpleClassName}Api.delete${simpleClassName}(${primaryColumn.javaField});
|
||||
await this.getList();
|
||||
this.#[[$modal]]#.msgSuccess("删除成功");
|
||||
} catch {}
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
async handleExport() {
|
||||
await this.#[[$modal]]#.confirm('是否确认导出所有${table.classComment}数据项?');
|
||||
try {
|
||||
this.exportLoading = true;
|
||||
const data = await ${simpleClassName}Api.export${simpleClassName}Excel(this.queryParams);
|
||||
this.#[[$]]#download.excel(data, '${table.classComment}.xls');
|
||||
} catch {
|
||||
} finally {
|
||||
this.exportLoading = false;
|
||||
}
|
||||
},
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 )
|
||||
/** 选中行操作 */
|
||||
handleCurrentChange(row) {
|
||||
this.currentRow = row;
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
/** 子表的列表 */
|
||||
this.subTabsName = '$subClassNameVars.get(0)';
|
||||
#end
|
||||
},
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
/** 展开/折叠操作 */
|
||||
toggleExpandAll() {
|
||||
this.refreshTable = false
|
||||
this.isExpandAll = !this.isExpandAll
|
||||
this.$nextTick(function () {
|
||||
this.refreshTable = true
|
||||
})
|
||||
}
|
||||
#end
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,115 @@
|
||||
import request from '@/config/axios'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
// ${table.classComment} VO
|
||||
export interface ${simpleClassName}VO {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||
${column.javaField}: number // ${column.columnComment}
|
||||
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
|
||||
${column.javaField}: Date // ${column.columnComment}
|
||||
#else
|
||||
${column.javaField}: ${column.javaType.toLowerCase()} // ${column.columnComment}
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
// ${table.classComment} API
|
||||
export const ${simpleClassName}Api = {
|
||||
#if ( $table.templateType != 2 )
|
||||
// 查询${table.classComment}分页
|
||||
get${simpleClassName}Page: async (params: any) => {
|
||||
return await request.get({ url: `${baseURL}/page`, params })
|
||||
},
|
||||
#else
|
||||
// 查询${table.classComment}列表
|
||||
get${simpleClassName}List: async (params) => {
|
||||
return await request.get({ url: `${baseURL}/list`, params })
|
||||
},
|
||||
#end
|
||||
|
||||
// 查询${table.classComment}详情
|
||||
get${simpleClassName}: async (id: number) => {
|
||||
return await request.get({ url: `${baseURL}/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增${table.classComment}
|
||||
create${simpleClassName}: async (data: ${simpleClassName}VO) => {
|
||||
return await request.post({ url: `${baseURL}/create`, data })
|
||||
},
|
||||
|
||||
// 修改${table.classComment}
|
||||
update${simpleClassName}: async (data: ${simpleClassName}VO) => {
|
||||
return await request.put({ url: `${baseURL}/update`, data })
|
||||
},
|
||||
|
||||
// 删除${table.classComment}
|
||||
delete${simpleClassName}: async (id: number) => {
|
||||
return await request.delete({ url: `${baseURL}/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出${table.classComment} Excel
|
||||
export${simpleClassName}: async (params) => {
|
||||
return await request.download({ url: `${baseURL}/export-excel`, params })
|
||||
},
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
|
||||
// 获得${subTable.classComment}分页
|
||||
get${subSimpleClassName}Page: async (params) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/page`, params })
|
||||
},
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
|
||||
// 获得${subTable.classComment}列表
|
||||
get${subSimpleClassName}ListBy${SubJoinColumnName}: async (${subJoinColumn.javaField}) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
|
||||
},
|
||||
#else
|
||||
|
||||
// 获得${subTable.classComment}
|
||||
get${subSimpleClassName}By${SubJoinColumnName}: async (${subJoinColumn.javaField}) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
|
||||
},
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
// 新增${subTable.classComment}
|
||||
create${subSimpleClassName}: async (data) => {
|
||||
return await request.post({ url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, data })
|
||||
},
|
||||
|
||||
// 修改${subTable.classComment}
|
||||
update${subSimpleClassName}: async (data) => {
|
||||
return await request.put({ url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, data })
|
||||
},
|
||||
|
||||
// 删除${subTable.classComment}
|
||||
delete${subSimpleClassName}: async (id: number) => {
|
||||
return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 获得${subTable.classComment}
|
||||
get${subSimpleClassName}: async (id: number) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id })
|
||||
},
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadImg v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadFile v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<Editor v-model="formData.${javaField}" height="150px" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-checkbox label="请选择字典生成" />
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="formData.${javaField}"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRules = reactive({
|
||||
#foreach ($column in $subColumns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number, ${subJoinColumn.javaField}: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
formData.value.${subJoinColumn.javaField} = ${subJoinColumn.javaField}
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await ${simpleClassName}Api.get${subSimpleClassName}(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value
|
||||
if (formType.value === 'create') {
|
||||
await ${simpleClassName}Api.create${subSimpleClassName}(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await ${simpleClassName}Api.update${subSimpleClassName}(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,2 @@
|
||||
## 主表的 normal 和 inner 使用相同的 form 表单
|
||||
#parse("codegen/vue3/views/components/form_sub_normal.vue.vm")
|
||||
@@ -0,0 +1,360 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
<template>
|
||||
#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
v-loading="formLoading"
|
||||
label-width="0px"
|
||||
:inline-message="true"
|
||||
>
|
||||
<el-table :data="formData" class="-mt-10px">
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-input v-model="row.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<UploadImg v-model="row.${javaField}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<UploadFile v-model="row.${javaField}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
<el-table-column label="${comment}" min-width="400">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<Editor v-model="row.${javaField}" height="150px" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-select v-model="row.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-checkbox-group v-model="row.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-checkbox label="请选择字典生成" />
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-radio-group v-model="row.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-date-picker
|
||||
v-model="row.${javaField}"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||
<template #default="{ $index }">
|
||||
<el-button @click="handleDelete($index)" link>—</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
<el-row justify="center" class="mt-3">
|
||||
<el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>
|
||||
</el-row>
|
||||
#else## 情况二:一对一,form
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadImg v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadFile v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<Editor v-model="formData.${javaField}" height="150px" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-checkbox label="请选择字典生成" />
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="formData.${javaField}"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
#end
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
|
||||
const props = defineProps<{
|
||||
${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
}>()
|
||||
const formLoading = ref(false) // 表单的加载中
|
||||
const formData = ref([])
|
||||
const formRules = reactive({
|
||||
#foreach ($column in $subColumns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
() => props.${subJoinColumn.javaField},
|
||||
async (val) => {
|
||||
// 1. 重置表单
|
||||
#if ( $subTable.subJoinMany )
|
||||
formData.value = []
|
||||
#else
|
||||
formData.value = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
#end
|
||||
// 2. val 非空,则加载数据
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
formLoading.value = true
|
||||
#if ( $subTable.subJoinMany )
|
||||
formData.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val)
|
||||
#else
|
||||
const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val)
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
formData.value = data
|
||||
#end
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
#if ( $subTable.subJoinMany )
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
const row = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
row.${subJoinColumn.javaField} = props.${subJoinColumn.javaField}
|
||||
formData.value.push(row)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (index) => {
|
||||
formData.value.splice(index, 1)
|
||||
}
|
||||
#end
|
||||
|
||||
/** 表单校验 */
|
||||
const validate = () => {
|
||||
return formRef.value.validate()
|
||||
}
|
||||
|
||||
/** 表单值 */
|
||||
const getData = () => {
|
||||
return formData.value
|
||||
}
|
||||
|
||||
defineExpose({ validate, getData })
|
||||
</script>
|
||||
@@ -0,0 +1,184 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
<template>
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
#if ($table.templateType == 11)
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['${permissionPrefix}:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
#end
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.javaType == "LocalDateTime")## 时间类型
|
||||
<el-table-column
|
||||
label="${comment}"
|
||||
align="center"
|
||||
prop="${javaField}"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#if ($table.templateType == 11)
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['${permissionPrefix}:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['${permissionPrefix}:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
</el-table>
|
||||
#if ($table.templateType == 11)
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
#end
|
||||
</ContentWrap>
|
||||
#if ($table.templateType == 11)
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<${subSimpleClassName}Form ref="formRef" @success="getList" />
|
||||
#end
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
#if ($table.templateType == 11)
|
||||
import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
|
||||
#end
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const props = defineProps<{
|
||||
${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
}>()
|
||||
const loading = ref(false) // 列表的加载中
|
||||
const list = ref([]) // 列表的数据
|
||||
#if ($table.templateType == 11)
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
${subJoinColumn.javaField}: undefined as unknown
|
||||
})
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
() => props.${subJoinColumn.javaField},
|
||||
(val: number) => {
|
||||
if (!val) {
|
||||
return
|
||||
}
|
||||
queryParams.${subJoinColumn.javaField} = val
|
||||
handleQuery()
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
#end
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
#if ($table.templateType == 11)
|
||||
const data = await ${simpleClassName}Api.get${subSimpleClassName}Page(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField})
|
||||
#else
|
||||
const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField})
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
list.value.push(data)
|
||||
#end
|
||||
#end
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
#if ($table.templateType == 11)
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
if (!props.${subJoinColumn.javaField}) {
|
||||
message.error('请选择一个${table.classComment}')
|
||||
return
|
||||
}
|
||||
formRef.value.open(type, id, props.${subJoinColumn.javaField})
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await ${simpleClassName}Api.delete${subSimpleClassName}(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
#end
|
||||
#if ($table.templateType != 11)
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
#end
|
||||
</script>
|
||||
@@ -0,0 +1,4 @@
|
||||
## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
|
||||
## 1)inner 使用 list 不分页,erp 使用 page 分页
|
||||
## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
|
||||
#parse("codegen/vue3/views/components/list_sub_erp.vue.vm")
|
||||
@@ -0,0 +1,300 @@
|
||||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
#foreach($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-tree-select
|
||||
v-model="formData.${javaField}"
|
||||
:data="${classNameVar}Tree"
|
||||
#if ($treeNameColumn.javaField == "name")
|
||||
:props="defaultProps"
|
||||
#else
|
||||
:props="{...defaultProps, label: '$treeNameColumn.javaField'}"
|
||||
#end
|
||||
check-strictly
|
||||
default-expand-all
|
||||
placeholder="请选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadImg v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadFile v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<Editor v-model="formData.${javaField}" height="150px" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-checkbox label="请选择字典生成" />
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="formData.${javaField}"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
<!-- 子表的表单 -->
|
||||
<el-tabs v-model="subTabsName">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
#end
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
|
||||
#end
|
||||
#end
|
||||
|
||||
/** ${table.classComment} 表单 */
|
||||
defineOptions({ name: '${simpleClassName}Form' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRules = reactive({
|
||||
#foreach ($column in $columns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
const ${classNameVar}Tree = ref() // 树形结构
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
|
||||
/** 子表的表单 */
|
||||
const subTabsName = ref('$subClassNameVars.get(0)')
|
||||
#foreach ($subClassNameVar in $subClassNameVars)
|
||||
const ${subClassNameVar}FormRef = ref()
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await ${simpleClassName}Api.get${simpleClassName}(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
await get${simpleClassName}Tree()
|
||||
#end
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
// 校验子表单
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
try {
|
||||
await ${subClassNameVar}FormRef.value.validate()
|
||||
} catch (e) {
|
||||
subTabsName.value = '${subClassNameVar}'
|
||||
return
|
||||
}
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as ${simpleClassName}VO
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
// 拼接子表的数据
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = ${subClassNameVar}FormRef.value.getData()
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
if (formType.value === 'create') {
|
||||
await ${simpleClassName}Api.create${simpleClassName}(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await ${simpleClassName}Api.update${simpleClassName}(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
|
||||
/** 获得${table.classComment}树 */
|
||||
const get${simpleClassName}Tree = async () => {
|
||||
${classNameVar}Tree.value = []
|
||||
const data = await ${simpleClassName}Api.get${simpleClassName}List()
|
||||
const root: Tree = { id: 0, name: '顶级${table.classComment}', children: [] }
|
||||
root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')
|
||||
${classNameVar}Tree.value.push(root)
|
||||
}
|
||||
#end
|
||||
</script>
|
||||
@@ -0,0 +1,374 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ($column.htmlType == "input")
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input
|
||||
v-model="queryParams.${javaField}"
|
||||
placeholder="请输入${comment}"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select
|
||||
v-model="queryParams.${javaField}"
|
||||
placeholder="请选择${comment}"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else## 未设置 dictType 数据字典的情况
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")
|
||||
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="queryParams.${javaField}"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="date"
|
||||
placeholder="选择${comment}"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
#else## 范围
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="queryParams.${javaField}"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['${permissionPrefix}:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['${permissionPrefix}:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
<el-button type="danger" plain @click="toggleExpandAll">
|
||||
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
|
||||
</el-button>
|
||||
#end
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
## 特殊:树表专属逻辑
|
||||
#elseif ( $table.templateType == 2 )
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
row-key="id"
|
||||
:default-expand-all="isExpandAll"
|
||||
v-if="refreshTable"
|
||||
>
|
||||
#else
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
|
||||
<!-- 子表的列表 -->
|
||||
<el-table-column type="expand">
|
||||
<template #default="scope">
|
||||
<el-tabs model-value="$subClassNameVars.get(0)">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||
<el-table-column
|
||||
label="${comment}"
|
||||
align="center"
|
||||
prop="${javaField}"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['${permissionPrefix}:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['${permissionPrefix}:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<${simpleClassName}Form ref="formRef" @success="getList" />
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||
<!-- 子表的列表 -->
|
||||
<ContentWrap>
|
||||
<el-tabs model-value="$subClassNameVars.get(0)">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="currentRow.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
</ContentWrap>
|
||||
#end
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
import { handleTree } from '@/utils/tree'
|
||||
#end
|
||||
import download from '@/utils/download'
|
||||
import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
import ${simpleClassName}Form from './${simpleClassName}Form.vue'
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType != 10 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue'
|
||||
#end
|
||||
#end
|
||||
|
||||
/** ${table.classComment} 列表 */
|
||||
defineOptions({ name: '${table.className}' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
const total = ref(0) // 列表的总页数
|
||||
#end
|
||||
const queryParams = reactive({
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
#end
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#if ($column.listOperationCondition != 'BETWEEN')
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||
$column.javaField: [],
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType == 2 )
|
||||
const data = await ${simpleClassName}Api.get${simpleClassName}List(queryParams)
|
||||
list.value = handleTree(data, 'id', '${treeParentColumn.javaField}')
|
||||
#else
|
||||
const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
#end
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await ${simpleClassName}Api.delete${simpleClassName}(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)
|
||||
download.excel(data, '${table.classComment}.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 )
|
||||
|
||||
/** 选中行操作 */
|
||||
const currentRow = ref({}) // 选中行
|
||||
const handleCurrentChange = (row) => {
|
||||
currentRow.value = row
|
||||
}
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
|
||||
/** 展开/折叠操作 */
|
||||
const isExpandAll = ref(true) // 是否展开,默认全部展开
|
||||
const refreshTable = ref(true) // 重新渲染表格状态
|
||||
const toggleExpandAll = async () => {
|
||||
refreshTable.value = false
|
||||
isExpandAll.value = !isExpandAll.value
|
||||
await nextTick()
|
||||
refreshTable.value = true
|
||||
}
|
||||
#end
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,32 @@
|
||||
import { defHttp } from '@/utils/http/axios'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
// 查询${table.classComment}列表
|
||||
export function get${simpleClassName}Page(params) {
|
||||
return defHttp.get({ url: '${baseURL}/page', params })
|
||||
}
|
||||
|
||||
// 查询${table.classComment}详情
|
||||
export function get${simpleClassName}(id: number) {
|
||||
return defHttp.get({ url: `${baseURL}/get?id=${id}` })
|
||||
}
|
||||
|
||||
// 新增${table.classComment}
|
||||
export function create${simpleClassName}(data) {
|
||||
return defHttp.post({ url: '${baseURL}/create', data })
|
||||
}
|
||||
|
||||
// 修改${table.classComment}
|
||||
export function update${simpleClassName}(data) {
|
||||
return defHttp.put({ url: '${baseURL}/update', data })
|
||||
}
|
||||
|
||||
// 删除${table.classComment}
|
||||
export function delete${simpleClassName}(id: number) {
|
||||
return defHttp.delete({ url: `${baseURL}/delete?id=${id}` })
|
||||
}
|
||||
|
||||
// 导出${table.classComment} Excel
|
||||
export function export${simpleClassName}(params) {
|
||||
return defHttp.download({ url: '${baseURL}/export-excel', params }, '${table.classComment}.xls')
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
import type {BasicColumn, FormSchema} from '@/components/Table'
|
||||
import {useRender} from '@/components/Table'
|
||||
import {DICT_TYPE, getDictOptions} from '@/utils/dict'
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||
{
|
||||
title: '${comment}',
|
||||
dataIndex: '${javaField}',
|
||||
width: 180,
|
||||
customRender: ({ text }) => {
|
||||
return useRender.renderDate(text)
|
||||
},
|
||||
},
|
||||
#elseif("" != $column.dictType)## 数据字典
|
||||
{
|
||||
title: '${comment}',
|
||||
dataIndex: '${javaField}',
|
||||
width: 180,
|
||||
customRender: ({ text }) => {
|
||||
return useRender.renderDict(text, DICT_TYPE.$dictType.toUpperCase())
|
||||
},
|
||||
},
|
||||
#else
|
||||
{
|
||||
title: '${comment}',
|
||||
dataIndex: '${javaField}',
|
||||
width: 160,
|
||||
},
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
]
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "number")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "string")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "boolean")
|
||||
#end
|
||||
{
|
||||
label: '${comment}',
|
||||
field: '${javaField}',
|
||||
#if ($column.htmlType == "input")
|
||||
component: 'Input',
|
||||
#elseif ($column.htmlType == "select")
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else## 未设置 dictType 数据字典的情况
|
||||
options: [],
|
||||
#end
|
||||
},
|
||||
#elseif ($column.htmlType == "radio")
|
||||
component: 'RadioButtonGroup',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else## 未设置 dictType 数据字典的情况
|
||||
options: [],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "datetime")
|
||||
component: 'RangePicker',
|
||||
#end
|
||||
colProps: { span: 8 },
|
||||
},
|
||||
#end
|
||||
#end
|
||||
]
|
||||
|
||||
export const createFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '编号',
|
||||
field: 'id',
|
||||
show: false,
|
||||
component: 'Input',
|
||||
},
|
||||
#foreach($column in $columns)
|
||||
#if ($column.createOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "number")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "string")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "boolean")
|
||||
#end
|
||||
#if (!$column.primaryKey)## 忽略主键,不用在表单里
|
||||
{
|
||||
label: '${comment}',
|
||||
field: '${javaField}',
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
required: true,
|
||||
#end
|
||||
#if ($column.htmlType == "input")
|
||||
component: 'Input',
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
component: 'FileUpload',
|
||||
componentProps: {
|
||||
fileType: 'image',
|
||||
maxCount: 1,
|
||||
},
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
component: 'FileUpload',
|
||||
componentProps: {
|
||||
fileType: 'file',
|
||||
maxCount: 1,
|
||||
},
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
component: 'Editor',
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
component: 'Checkbox',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
component: 'RadioButtonGroup',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
format: 'YYYY-MM-DD HH:mm:ss',
|
||||
valueFormat: 'x',
|
||||
},
|
||||
#elseif($column.htmlType == "textarea")## 文本域
|
||||
component: 'InputTextArea',
|
||||
#end
|
||||
},
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
]
|
||||
|
||||
export const updateFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '编号',
|
||||
field: 'id',
|
||||
show: false,
|
||||
component: 'Input',
|
||||
},
|
||||
#foreach($column in $columns)
|
||||
#if ($column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "number")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "string")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "boolean")
|
||||
#end
|
||||
#if (!$column.primaryKey)## 忽略主键,不用在表单里
|
||||
{
|
||||
label: '${comment}',
|
||||
field: '${javaField}',
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
required: true,
|
||||
#end
|
||||
#if ($column.htmlType == "input")
|
||||
component: 'Input',
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
component: 'FileUpload',
|
||||
componentProps: {
|
||||
fileType: 'image',
|
||||
maxCount: 1,
|
||||
},
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
component: 'FileUpload',
|
||||
componentProps: {
|
||||
fileType: 'file',
|
||||
maxCount: 1,
|
||||
},
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
component: 'Editor',
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
component: 'Checkbox',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
component: 'RadioButtonGroup',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
format: 'YYYY-MM-DD HH:mm:ss',
|
||||
valueFormat: 'x',
|
||||
},
|
||||
#elseif($column.htmlType == "textarea")## 文本域
|
||||
component: 'InputTextArea',
|
||||
#end
|
||||
},
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
]
|
||||
@@ -0,0 +1,58 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue'
|
||||
import { createFormSchema, updateFormSchema } from './${classNameVar}.data'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useMessage } from '@/hooks/web/useMessage'
|
||||
import { BasicForm, useForm } from '@/components/Form'
|
||||
import { BasicModal, useModalInner } from '@/components/Modal'
|
||||
import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
|
||||
defineOptions({ name: '${table.className}Modal' })
|
||||
|
||||
const emit = defineEmits(['success', 'register'])
|
||||
|
||||
const { t } = useI18n()
|
||||
const { createMessage } = useMessage()
|
||||
const isUpdate = ref(true)
|
||||
|
||||
const [registerForm, { setFieldsValue, resetFields, resetSchema, validate }] = useForm({
|
||||
labelWidth: 120,
|
||||
baseColProps: { span: 24 },
|
||||
schemas: createFormSchema,
|
||||
showActionButtonGroup: false,
|
||||
actionColOptions: { span: 23 },
|
||||
})
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
resetFields()
|
||||
setModalProps({ confirmLoading: false })
|
||||
isUpdate.value = !!data?.isUpdate
|
||||
if (unref(isUpdate)) {
|
||||
resetSchema(updateFormSchema)
|
||||
const res = await get${simpleClassName}(data.record.id)
|
||||
setFieldsValue({ ...res })
|
||||
}
|
||||
})
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate()
|
||||
setModalProps({ confirmLoading: true })
|
||||
if (unref(isUpdate))
|
||||
await update${simpleClassName}(values)
|
||||
else
|
||||
await create${simpleClassName}(values)
|
||||
|
||||
closeModal()
|
||||
emit('success')
|
||||
createMessage.success(t('common.saveSuccessText'))
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
@@ -0,0 +1,92 @@
|
||||
<script lang="ts" setup>
|
||||
import ${simpleClassName}Modal from './${simpleClassName}Modal.vue'
|
||||
import { columns, searchFormSchema } from './${classNameVar}.data'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useMessage } from '@/hooks/web/useMessage'
|
||||
import { useModal } from '@/components/Modal'
|
||||
import { IconEnum } from '@/enums/appEnum'
|
||||
import { BasicTable, TableAction, useTable } from '@/components/Table'
|
||||
import { delete${simpleClassName}, export${simpleClassName}, get${simpleClassName}Page } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
|
||||
defineOptions({ name: '${table.className}' })
|
||||
|
||||
const { t } = useI18n()
|
||||
const { createConfirm, createMessage } = useMessage()
|
||||
const [registerModal, { openModal }] = useModal()
|
||||
|
||||
const [registerTable, { getForm, reload }] = useTable({
|
||||
title: '${table.classComment}列表',
|
||||
api: get${simpleClassName}Page,
|
||||
columns,
|
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema },
|
||||
useSearchForm: true,
|
||||
showTableSetting: true,
|
||||
actionColumn: {
|
||||
width: 140,
|
||||
title: t('common.action'),
|
||||
dataIndex: 'action',
|
||||
fixed: 'right',
|
||||
},
|
||||
})
|
||||
|
||||
function handleCreate() {
|
||||
openModal(true, { isUpdate: false })
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, { record, isUpdate: true })
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
createConfirm({
|
||||
title: t('common.exportTitle'),
|
||||
iconType: 'warning',
|
||||
content: t('common.exportMessage'),
|
||||
async onOk() {
|
||||
await export${simpleClassName}(getForm().getFieldsValue())
|
||||
createMessage.success(t('common.exportSuccessText'))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
await delete${simpleClassName}(record.id)
|
||||
createMessage.success(t('common.delSuccessText'))
|
||||
reload()
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #toolbar>
|
||||
<a-button type="primary" v-auth="['${permissionPrefix}:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
|
||||
{{ t('action.create') }}
|
||||
</a-button>
|
||||
<a-button v-auth="['${permissionPrefix}:export']" :preIcon="IconEnum.EXPORT" @click="handleExport">
|
||||
{{ t('action.export') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: '${permissionPrefix}:update', onClick: handleEdit.bind(null, record) },
|
||||
{
|
||||
icon: IconEnum.DELETE,
|
||||
danger: true,
|
||||
label: t('action.delete'),
|
||||
auth: '${permissionPrefix}:delete',
|
||||
popConfirm: {
|
||||
title: t('common.delMessage'),
|
||||
placement: 'left',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<${simpleClassName}Modal @register="registerModal" @success="reload()" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -2,7 +2,7 @@
|
||||
<!-- 引用 Spring Boot 的 logback 基础配置 -->
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||
<!-- 变量 yudao.info.base-package,基础业务包 -->
|
||||
<springProperty scope="context" name="yudao.info.base-package" source="yudao.info.base-package"/>
|
||||
<springProperty scope="context" name="tashow.info.base-package" source="tashow.info.base-package"/>
|
||||
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度,%msg:日志消息,%n是换行符 -->
|
||||
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.tashow.cloud.member.address;
|
||||
|
||||
import com.tashow.cloud.common.pojo.CommonResult;
|
||||
import com.tashow.cloud.memberapi.api.address.MemberAddressApi;
|
||||
import com.tashow.cloud.memberapi.api.address.dto.MemberAddressRespDTO;
|
||||
import com.tashow.cloud.member.convert.address.AddressConvert;
|
||||
import com.tashow.cloud.member.service.address.AddressService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static com.tashow.cloud.common.pojo.CommonResult.success;
|
||||
|
||||
|
||||
/**
|
||||
* 用户收件地址 API 实现类
|
||||
*/
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class MemberAddressApiImpl implements MemberAddressApi {
|
||||
|
||||
@Resource
|
||||
private AddressService addressService;
|
||||
|
||||
@Override
|
||||
public CommonResult<MemberAddressRespDTO> getAddress(Long id, Long userId) {
|
||||
return success(AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<MemberAddressRespDTO> getDefaultAddress(Long userId) {
|
||||
return success(AddressConvert.INSTANCE.convert02(addressService.getDefaultUserAddress(userId)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.admin.address;
|
||||
|
||||
import com.tashow.cloud.common.pojo.CommonResult;
|
||||
import com.tashow.cloud.member.controller.admin.address.vo.AddressRespVO;
|
||||
import com.tashow.cloud.member.convert.address.AddressConvert;
|
||||
import com.tashow.cloud.member.dal.dataobject.address.MemberAddressDO;
|
||||
import com.tashow.cloud.member.service.address.AddressService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.tashow.cloud.common.pojo.CommonResult.success;
|
||||
|
||||
|
||||
// 管理后台 - 用户收件地址
|
||||
@RestController
|
||||
@RequestMapping("/member/address")
|
||||
@Validated
|
||||
public class AddressController {
|
||||
|
||||
@Resource
|
||||
private AddressService addressService;
|
||||
|
||||
@GetMapping("/list")
|
||||
// 获得用户收件地址列表
|
||||
// userId: 用户编号,必填
|
||||
@PreAuthorize("@ss.hasPermission('member:user:query')")
|
||||
public CommonResult<List<AddressRespVO>> getAddressList(@RequestParam("userId") Long userId) {
|
||||
List<MemberAddressDO> list = addressService.getAddressList(userId);
|
||||
return success(AddressConvert.INSTANCE.convertList2(list));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.admin.address;
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.admin.address.vo;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class AddressBaseVO {
|
||||
|
||||
// 收件人名称,必填,示例:张三
|
||||
@NotNull(message = "收件人名称不能为空")
|
||||
private String name;
|
||||
|
||||
// 手机号,必填
|
||||
@NotNull(message = "手机号不能为空")
|
||||
private String mobile;
|
||||
|
||||
// 地区编码,必填,示例:15716
|
||||
@NotNull(message = "地区编码不能为空")
|
||||
private Long areaId;
|
||||
|
||||
// 收件详细地址,必填
|
||||
@NotNull(message = "收件详细地址不能为空")
|
||||
private String detailAddress;
|
||||
|
||||
// 是否默认,必填,示例:2
|
||||
@NotNull(message = "是否默认不能为空")
|
||||
private Boolean defaultStatus;
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.admin.address.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// 管理后台 - 用户收件地址 Response VO
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AddressRespVO extends AddressBaseVO {
|
||||
|
||||
// 收件地址编号,必填,示例:7380
|
||||
private Long id;
|
||||
|
||||
// 创建时间,必填
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.admin.user.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static com.tashow.cloud.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
|
||||
|
||||
|
||||
/**
|
||||
* 会员用户 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class MemberUserBaseVO {
|
||||
|
||||
// 手机号,必填,示例:15601691300
|
||||
@NotNull(message = "手机号不能为空")
|
||||
private String mobile;
|
||||
|
||||
// 状态,必填,示例:2
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Byte status;
|
||||
|
||||
// 用户昵称,必填,示例:李四
|
||||
@NotNull(message = "用户昵称不能为空")
|
||||
private String nickname;
|
||||
|
||||
// 头像,必填,示例:https://www.iocoder.cn/x.png
|
||||
@URL(message = "头像必须是 URL 格式")
|
||||
private String avatar;
|
||||
|
||||
// 用户昵称,示例:李四
|
||||
private String name;
|
||||
|
||||
// 用户性别,示例:1
|
||||
private Integer sex;
|
||||
|
||||
// 所在地编号,示例:4371
|
||||
private Long areaId;
|
||||
|
||||
// 所在地全程,示例:上海上海市普陀区
|
||||
private String areaName;
|
||||
|
||||
// 出生日期,示例:2023-03-12
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
|
||||
private LocalDateTime birthday;
|
||||
|
||||
// 会员备注,示例:我是小备注
|
||||
private String mark;
|
||||
|
||||
// 会员标签,示例:[1, 2]
|
||||
private List<Long> tagIds;
|
||||
|
||||
// 会员等级编号,示例:1
|
||||
private Long levelId;
|
||||
|
||||
// 用户分组编号,示例:1
|
||||
private Long groupId;
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.admin.user.vo;
|
||||
|
||||
import com.tashow.cloud.common.pojo.PageParam;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static com.tashow.cloud.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
|
||||
// 管理后台 - 会员用户分页 Request VO
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class MemberUserPageReqVO extends PageParam {
|
||||
|
||||
// 手机号,示例:15601691300
|
||||
private String mobile;
|
||||
|
||||
// 用户昵称,示例:李四
|
||||
private String nickname;
|
||||
|
||||
// 最后登录时间
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] loginDate;
|
||||
|
||||
// 创建时间
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
// 会员标签编号列表,示例:[1, 2]
|
||||
private List<Long> tagIds;
|
||||
|
||||
// 会员等级编号,示例:1
|
||||
private Long levelId;
|
||||
|
||||
// 用户分组编号,示例:1
|
||||
private Long groupId;
|
||||
|
||||
// TODO 芋艿:注册用户类型;
|
||||
|
||||
// TODO 芋艿:登录用户类型;
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.admin.user.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
// 管理后台 - 会员用户 Response VO
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class MemberUserRespVO extends MemberUserBaseVO {
|
||||
|
||||
// 编号,必填,示例:23788
|
||||
private Long id;
|
||||
|
||||
// 注册 IP,必填,示例:127.0.0.1
|
||||
private String registerIp;
|
||||
|
||||
// 最后登录IP,必填,示例:127.0.0.1
|
||||
private String loginIp;
|
||||
|
||||
// 最后登录时间,必填
|
||||
private LocalDateTime loginDate;
|
||||
|
||||
// 创建时间,必填
|
||||
private LocalDateTime createTime;
|
||||
|
||||
// ========== 其它信息 ==========
|
||||
|
||||
// 积分,必填,示例:100
|
||||
private Integer point;
|
||||
|
||||
// 总积分,必填,示例:2000
|
||||
private Integer totalPoint;
|
||||
|
||||
// 会员标签,示例:[红色, 快乐]
|
||||
private List<String> tagNames;
|
||||
|
||||
// 会员等级,示例:黄金会员
|
||||
private String levelName;
|
||||
|
||||
// 用户分组,示例:购物达人
|
||||
private String groupName;
|
||||
|
||||
// 用户经验值,必填,示例:200
|
||||
private Integer experience;
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
### 请求 /create 接口 => 成功
|
||||
POST {{appApi}}//member/address/create
|
||||
Content-Type: application/json
|
||||
tenant-id: {{appTenantId}}
|
||||
Authorization: Bearer {{appToken}}
|
||||
|
||||
{
|
||||
"name": "yunai",
|
||||
"mobile": "15601691300",
|
||||
"areaId": "610632",
|
||||
"postCode": "200000",
|
||||
"detailAddress": "芋道源码 233 号 666 室",
|
||||
"defaulted": true
|
||||
}
|
||||
|
||||
### 请求 /update 接口 => 成功
|
||||
PUT {{appApi}}//member/address/update
|
||||
Content-Type: application/json
|
||||
tenant-id: {{appTenantId}}
|
||||
Authorization: Bearer {{appToken}}
|
||||
|
||||
{
|
||||
"id": "1",
|
||||
"name": "yunai888",
|
||||
"mobile": "15601691300",
|
||||
"areaId": "610632",
|
||||
"postCode": "200000",
|
||||
"detailAddress": "芋道源码 233 号 666 室",
|
||||
"defaulted": false
|
||||
}
|
||||
|
||||
### 请求 /delete 接口 => 成功
|
||||
DELETE {{appApi}}//member/address/delete?id=2
|
||||
Content-Type: application/json
|
||||
tenant-id: {{appTenantId}}
|
||||
Authorization: Bearer {{appToken}}
|
||||
|
||||
### 请求 /get 接口 => 成功
|
||||
GET {{appApi}}//member/address/get?id=1
|
||||
Content-Type: application/json
|
||||
tenant-id: {{appTenantId}}
|
||||
Authorization: Bearer {{appToken}}
|
||||
|
||||
### 请求 /get-default 接口 => 成功
|
||||
GET {{appApi}}//member/address/get-default
|
||||
Content-Type: application/json
|
||||
tenant-id: {{appTenantId}}
|
||||
Authorization: Bearer {{appToken}}
|
||||
|
||||
### 请求 /list 接口 => 成功
|
||||
GET {{appApi}}//member/address/list
|
||||
Content-Type: application/json
|
||||
tenant-id: {{appTenantId}}
|
||||
Authorization: Bearer {{appToken}}
|
||||
@@ -1,95 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.app.address;
|
||||
|
||||
import com.tashow.cloud.common.pojo.CommonResult;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressCreateReqVO;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressRespVO;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressUpdateReqVO;
|
||||
import com.tashow.cloud.member.convert.address.AddressConvert;
|
||||
import com.tashow.cloud.member.dal.dataobject.address.MemberAddressDO;
|
||||
import com.tashow.cloud.member.service.address.AddressService;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.tashow.cloud.common.pojo.CommonResult.success;
|
||||
import static com.tashow.cloud.security.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
|
||||
/**
|
||||
* 用户 APP - 用户收件地址
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/member/address")
|
||||
@Validated
|
||||
public class AppAddressController {
|
||||
|
||||
@Resource
|
||||
private AddressService addressService;
|
||||
|
||||
/**
|
||||
* 创建用户收件地址
|
||||
* @param createReqVO
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
public CommonResult<Long> createAddress(@Valid @RequestBody AppAddressCreateReqVO createReqVO) {
|
||||
return success(addressService.createAddress(getLoginUserId(), createReqVO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户收件地址
|
||||
* @param updateReqVO
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/update")
|
||||
public CommonResult<Boolean> updateAddress(@Valid @RequestBody AppAddressUpdateReqVO updateReqVO) {
|
||||
addressService.updateAddress(getLoginUserId(), updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户收件地址
|
||||
* @param id 编号
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("/delete")
|
||||
public CommonResult<Boolean> deleteAddress(@RequestParam("id") Long id) {
|
||||
addressService.deleteAddress(getLoginUserId(), id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户收件地址
|
||||
* @param id 编号
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/get")
|
||||
public CommonResult<AppAddressRespVO> getAddress(@RequestParam("id") Long id) {
|
||||
MemberAddressDO address = addressService.getAddress(getLoginUserId(), id);
|
||||
return success(AddressConvert.INSTANCE.convert(address));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得默认的用户收件地址
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/get-default")
|
||||
public CommonResult<AppAddressRespVO> getDefaultUserAddress() {
|
||||
MemberAddressDO address = addressService.getDefaultUserAddress(getLoginUserId());
|
||||
return success(AddressConvert.INSTANCE.convert(address));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户收件地址列表
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public CommonResult<List<AppAddressRespVO>> getAddressList() {
|
||||
List<MemberAddressDO> list = addressService.getAddressList(getLoginUserId());
|
||||
return success(AddressConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.app.address.vo;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
*/
|
||||
@Data
|
||||
public class AppAddressBaseVO {
|
||||
|
||||
//收件人名称
|
||||
@NotNull(message = "收件人名称不能为空")
|
||||
private String name;
|
||||
|
||||
//手机号
|
||||
@NotNull(message = "手机号不能为空")
|
||||
private String mobile;
|
||||
|
||||
//地区编号
|
||||
@NotNull(message = "地区编号不能为空")
|
||||
private Long areaId;
|
||||
|
||||
//收件详细地址
|
||||
@NotNull(message = "收件详细地址不能为空")
|
||||
private String detailAddress;
|
||||
|
||||
//是否默认地址
|
||||
@NotNull(message = "是否默认地址不能为空")
|
||||
private Boolean defaultStatus;
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.app.address.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 用户 APP - 用户收件地址创建 Request VO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AppAddressCreateReqVO extends AppAddressBaseVO {
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.app.address.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 用户 APP - 用户收件地址 Response VO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AppAddressRespVO extends AppAddressBaseVO {
|
||||
|
||||
//编号
|
||||
private Long id;
|
||||
|
||||
//地区名字
|
||||
private String areaName;
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.tashow.cloud.member.controller.app.address.vo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 用户 APP - 用户收件地址更新 Request VO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AppAddressUpdateReqVO extends AppAddressBaseVO {
|
||||
|
||||
//编号
|
||||
@NotNull(message = "编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.tashow.cloud.member.convert.address;
|
||||
|
||||
import com.tashow.cloud.common.util.ip.AreaUtils;
|
||||
import com.tashow.cloud.memberapi.api.address.dto.MemberAddressRespDTO;
|
||||
import com.tashow.cloud.member.controller.admin.address.vo.AddressRespVO;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressCreateReqVO;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressRespVO;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressUpdateReqVO;
|
||||
import com.tashow.cloud.member.dal.dataobject.address.MemberAddressDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface AddressConvert {
|
||||
|
||||
AddressConvert INSTANCE = Mappers.getMapper(AddressConvert.class);
|
||||
|
||||
MemberAddressDO convert(AppAddressCreateReqVO bean);
|
||||
|
||||
MemberAddressDO convert(AppAddressUpdateReqVO bean);
|
||||
|
||||
@Mapping(source = "areaId", target = "areaName", qualifiedByName = "convertAreaIdToAreaName")
|
||||
AppAddressRespVO convert(MemberAddressDO bean);
|
||||
|
||||
List<AppAddressRespVO> convertList(List<MemberAddressDO> list);
|
||||
|
||||
MemberAddressRespDTO convert02(MemberAddressDO bean);
|
||||
|
||||
@Named("convertAreaIdToAreaName")
|
||||
default String convertAreaIdToAreaName(Integer areaId) {
|
||||
return AreaUtils.format(areaId);
|
||||
}
|
||||
|
||||
List<AddressRespVO> convertList2(List<MemberAddressDO> list);
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.tashow.cloud.member.convert.user;
|
||||
|
||||
import com.tashow.cloud.common.pojo.PageResult;
|
||||
import com.tashow.cloud.memberapi.api.user.dto.MemberUserRespDTO;
|
||||
import com.tashow.cloud.member.controller.admin.user.vo.MemberUserRespVO;
|
||||
import com.tashow.cloud.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
||||
import com.tashow.cloud.member.controller.app.user.vo.AppMemberUserInfoRespVO;
|
||||
import com.tashow.cloud.member.convert.address.AddressConvert;
|
||||
import com.tashow.cloud.member.dal.dataobject.user.MemberUserDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper(uses = {AddressConvert.class})
|
||||
public interface MemberUserConvert {
|
||||
|
||||
MemberUserConvert INSTANCE = Mappers.getMapper(MemberUserConvert.class);
|
||||
|
||||
AppMemberUserInfoRespVO convert(MemberUserDO bean);
|
||||
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "bean.id", target = "id"),
|
||||
})
|
||||
|
||||
MemberUserRespDTO convert2(MemberUserDO bean);
|
||||
|
||||
List<MemberUserRespDTO> convertList2(List<MemberUserDO> list);
|
||||
|
||||
MemberUserDO convert(MemberUserUpdateReqVO bean);
|
||||
|
||||
PageResult<MemberUserRespVO> convertPage(PageResult<MemberUserDO> page);
|
||||
|
||||
@Mapping(source = "areaId", target = "areaName", qualifiedByName = "convertAreaIdToAreaName")
|
||||
MemberUserRespVO convert03(MemberUserDO bean);
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao>
|
||||
@@ -1,139 +0,0 @@
|
||||
package com.tashow.cloud.member.dal.dataobject.user;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.tashow.cloud.common.enums.CommonStatusEnum;
|
||||
import com.tashow.cloud.common.enums.TerminalEnum;
|
||||
import com.tashow.cloud.mybatis.mybatis.core.type.LongListTypeHandler;
|
||||
import com.tashow.cloud.systemapi.enums.common.SexEnum;
|
||||
import com.tashow.cloud.tenant.core.db.TenantBaseDO;
|
||||
import lombok.*;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会员用户 DO
|
||||
*
|
||||
* uk_mobile 索引:基于 {@link #mobile} 字段
|
||||
*
|
||||
*/
|
||||
@TableName(value = "member_user", autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MemberUserDO extends TenantBaseDO {
|
||||
|
||||
// ========== 账号信息 ==========
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 手机
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 加密后的密码
|
||||
*
|
||||
* 因为目前使用 {@link BCryptPasswordEncoder} 加密器,所以无需自己处理 salt 盐
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 帐号状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 注册 IP
|
||||
*/
|
||||
private String registerIp;
|
||||
/**
|
||||
* 注册终端
|
||||
* 枚举 {@link TerminalEnum}
|
||||
*/
|
||||
private Integer registerTerminal;
|
||||
/**
|
||||
* 最后登录IP
|
||||
*/
|
||||
private String loginIp;
|
||||
/**
|
||||
* 最后登录时间
|
||||
*/
|
||||
private LocalDateTime loginDate;
|
||||
|
||||
// ========== 基础信息 ==========
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 真实名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link SexEnum}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 所在地
|
||||
*
|
||||
* 关联 {@link Area#getId()} 字段
|
||||
*/
|
||||
private Integer areaId;
|
||||
/**
|
||||
* 用户备注
|
||||
*/
|
||||
private String mark;
|
||||
|
||||
// ========== 其它信息 ==========
|
||||
|
||||
/**
|
||||
* 积分
|
||||
*/
|
||||
private Integer point;
|
||||
// TODO 疯狂:增加一个 totalPoint;个人信息接口要返回
|
||||
|
||||
/**
|
||||
* 会员标签列表,以逗号分隔
|
||||
*/
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> tagIds;
|
||||
|
||||
/**
|
||||
* 会员级别编号
|
||||
*
|
||||
* 关联 {@link MemberLevelDO#getId()} 字段
|
||||
*/
|
||||
private Long levelId;
|
||||
/**
|
||||
* 会员经验
|
||||
*/
|
||||
private Integer experience;
|
||||
/**
|
||||
* 用户分组编号
|
||||
*
|
||||
* 关联 {@link MemberGroupDO#getId()} 字段
|
||||
*/
|
||||
private Long groupId;
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.tashow.cloud.member.dal.mysql.address;
|
||||
|
||||
import com.tashow.cloud.member.dal.dataobject.address.MemberAddressDO;
|
||||
import com.tashow.cloud.mybatis.mybatis.core.mapper.BaseMapperX;
|
||||
import com.tashow.cloud.mybatis.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface MemberAddressMapper extends BaseMapperX<MemberAddressDO> {
|
||||
|
||||
default MemberAddressDO selectByIdAndUserId(Long id, Long userId) {
|
||||
return selectOne(MemberAddressDO::getId, id, MemberAddressDO::getUserId, userId);
|
||||
}
|
||||
|
||||
default List<MemberAddressDO> selectListByUserIdAndDefaulted(Long userId, Boolean defaulted) {
|
||||
return selectList(new LambdaQueryWrapperX<MemberAddressDO>().eq(MemberAddressDO::getUserId, userId)
|
||||
.eqIfPresent(MemberAddressDO::getDefaultStatus, defaulted));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.tashow.cloud.member.dal.mysql.user;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.tashow.cloud.common.pojo.PageResult;
|
||||
import com.tashow.cloud.member.controller.admin.user.vo.MemberUserPageReqVO;
|
||||
import com.tashow.cloud.member.dal.dataobject.user.MemberUserDO;
|
||||
import com.tashow.cloud.mybatis.mybatis.core.mapper.BaseMapperX;
|
||||
import com.tashow.cloud.mybatis.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 会员 User Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
|
||||
|
||||
default MemberUserDO selectByMobile(String mobile) {
|
||||
return selectOne(MemberUserDO::getMobile, mobile);
|
||||
}
|
||||
|
||||
default List<MemberUserDO> selectListByNicknameLike(String nickname) {
|
||||
return selectList(new LambdaQueryWrapperX<MemberUserDO>()
|
||||
.likeIfPresent(MemberUserDO::getNickname, nickname));
|
||||
}
|
||||
|
||||
default PageResult<MemberUserDO> selectPage(MemberUserPageReqVO reqVO) {
|
||||
// 处理 tagIds 过滤条件
|
||||
String tagIdSql = "";
|
||||
if (CollUtil.isNotEmpty(reqVO.getTagIds())) {
|
||||
tagIdSql = reqVO.getTagIds().stream()
|
||||
.map(tagId -> "FIND_IN_SET(" + tagId + ", tag_ids)")
|
||||
.collect(Collectors.joining(" OR "));
|
||||
}
|
||||
// 分页查询
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<MemberUserDO>()
|
||||
.likeIfPresent(MemberUserDO::getMobile, reqVO.getMobile())
|
||||
.betweenIfPresent(MemberUserDO::getLoginDate, reqVO.getLoginDate())
|
||||
.likeIfPresent(MemberUserDO::getNickname, reqVO.getNickname())
|
||||
.betweenIfPresent(MemberUserDO::getCreateTime, reqVO.getCreateTime())
|
||||
.eqIfPresent(MemberUserDO::getLevelId, reqVO.getLevelId())
|
||||
.eqIfPresent(MemberUserDO::getGroupId, reqVO.getGroupId())
|
||||
.apply(StrUtil.isNotEmpty(tagIdSql), tagIdSql)
|
||||
.orderByDesc(MemberUserDO::getId));
|
||||
}
|
||||
|
||||
default Long selectCountByGroupId(Long groupId) {
|
||||
return selectCount(MemberUserDO::getGroupId, groupId);
|
||||
}
|
||||
|
||||
default Long selectCountByLevelId(Long levelId) {
|
||||
return selectCount(MemberUserDO::getLevelId, levelId);
|
||||
}
|
||||
|
||||
default Long selectCountByTagId(Long tagId) {
|
||||
return selectCount(new LambdaQueryWrapperX<MemberUserDO>()
|
||||
.apply("FIND_IN_SET({0}, tag_ids)", tagId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户积分(增加)
|
||||
*
|
||||
* @param id 用户编号
|
||||
* @param incrCount 增加积分(正数)
|
||||
*/
|
||||
default void updatePointIncr(Long id, Integer incrCount) {
|
||||
Assert.isTrue(incrCount > 0);
|
||||
LambdaUpdateWrapper<MemberUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<MemberUserDO>()
|
||||
.setSql(" point = point + " + incrCount)
|
||||
.eq(MemberUserDO::getId, id);
|
||||
update(null, lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户积分(减少)
|
||||
*
|
||||
* @param id 用户编号
|
||||
* @param incrCount 增加积分(负数)
|
||||
* @return 更新行数
|
||||
*/
|
||||
default int updatePointDecr(Long id, Integer incrCount) {
|
||||
Assert.isTrue(incrCount < 0);
|
||||
LambdaUpdateWrapper<MemberUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<MemberUserDO>()
|
||||
.setSql(" point = point + " + incrCount) // 负数,所以使用 + 号
|
||||
.eq(MemberUserDO::getId, id);
|
||||
return update(null, lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* 占位
|
||||
*/
|
||||
package com.tashow.cloud.member.framework.rpc;
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* 占位
|
||||
*/
|
||||
package com.tashow.cloud.member.framework.security.core;
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* 消息队列的消费者
|
||||
*/
|
||||
package com.tashow.cloud.member.mq.consumer;
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* 消息队列的消息
|
||||
*/
|
||||
package com.tashow.cloud.member.mq.message;
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* 消息队列的生产者
|
||||
*/
|
||||
package com.tashow.cloud.member.mq.producer;
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.tashow.cloud.member.mq.producer.user;
|
||||
|
||||
import com.tashow.cloud.memberapi.message.user.MemberUserCreateMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 会员用户 Producer
|
||||
*
|
||||
* @author owen
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MemberUserProducer {
|
||||
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* 发送 {@link MemberUserCreateMessage} 消息
|
||||
*
|
||||
* @param userId 用户编号
|
||||
*/
|
||||
public void sendUserCreateMessage(Long userId) {
|
||||
applicationContext.publishEvent(new MemberUserCreateMessage().setUserId(userId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* member 模块,我们放会员业务。
|
||||
* 例如说:会员中心等等
|
||||
*
|
||||
* 1. Controller URL:以 /member/ 开头,避免和其它 Module 冲突
|
||||
* 2. DataObject 表名:以 member_ 开头,方便在数据库中区分
|
||||
*/
|
||||
package com.tashow.cloud.member;
|
||||
@@ -1,67 +0,0 @@
|
||||
package com.tashow.cloud.member.service.address;
|
||||
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressCreateReqVO;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressUpdateReqVO;
|
||||
import com.tashow.cloud.member.dal.dataobject.address.MemberAddressDO;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface AddressService {
|
||||
|
||||
/**
|
||||
* 创建用户收件地址
|
||||
*
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createAddress(Long userId, @Valid AppAddressCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新用户收件地址
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateAddress(Long userId, @Valid AppAddressUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除用户收件地址
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteAddress(Long userId, Long id);
|
||||
|
||||
/**
|
||||
* 获得用户收件地址
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
MemberAddressDO getAddress(Long userId, Long id);
|
||||
|
||||
/**
|
||||
* 获得用户收件地址列表
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 用户收件地址列表
|
||||
*/
|
||||
List<MemberAddressDO> getAddressList(Long userId);
|
||||
|
||||
/**
|
||||
* 获得用户默认的收件地址
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
MemberAddressDO getDefaultUserAddress(Long userId);
|
||||
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package com.tashow.cloud.member.service.address;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressCreateReqVO;
|
||||
import com.tashow.cloud.member.controller.app.address.vo.AppAddressUpdateReqVO;
|
||||
import com.tashow.cloud.member.convert.address.AddressConvert;
|
||||
import com.tashow.cloud.member.dal.dataobject.address.MemberAddressDO;
|
||||
import com.tashow.cloud.member.dal.mysql.address.MemberAddressMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static com.tashow.cloud.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.tashow.cloud.memberapi.enums.ErrorCodeConstants.ADDRESS_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class AddressServiceImpl implements AddressService {
|
||||
|
||||
@Resource
|
||||
private MemberAddressMapper memberAddressMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createAddress(Long userId, AppAddressCreateReqVO createReqVO) {
|
||||
// 如果添加的是默认收件地址,则将原默认地址修改为非默认
|
||||
if (Boolean.TRUE.equals(createReqVO.getDefaultStatus())) {
|
||||
List<MemberAddressDO> addresses = memberAddressMapper.selectListByUserIdAndDefaulted(userId, true);
|
||||
addresses.forEach(address -> memberAddressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaultStatus(false)));
|
||||
}
|
||||
|
||||
// 插入
|
||||
MemberAddressDO address = AddressConvert.INSTANCE.convert(createReqVO);
|
||||
address.setUserId(userId);
|
||||
memberAddressMapper.insert(address);
|
||||
// 返回
|
||||
return address.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateAddress(Long userId, AppAddressUpdateReqVO updateReqVO) {
|
||||
// 校验存在,校验是否能够操作
|
||||
validAddressExists(userId, updateReqVO.getId());
|
||||
|
||||
// 如果修改的是默认收件地址,则将原默认地址修改为非默认
|
||||
if (Boolean.TRUE.equals(updateReqVO.getDefaultStatus())) {
|
||||
List<MemberAddressDO> addresses = memberAddressMapper.selectListByUserIdAndDefaulted(userId, true);
|
||||
addresses.stream().filter(u -> !u.getId().equals(updateReqVO.getId())) // 排除自己
|
||||
.forEach(address -> memberAddressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaultStatus(false)));
|
||||
}
|
||||
|
||||
// 更新
|
||||
MemberAddressDO updateObj = AddressConvert.INSTANCE.convert(updateReqVO);
|
||||
memberAddressMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAddress(Long userId, Long id) {
|
||||
// 校验存在,校验是否能够操作
|
||||
validAddressExists(userId, id);
|
||||
// 删除
|
||||
memberAddressMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validAddressExists(Long userId, Long id) {
|
||||
MemberAddressDO addressDO = getAddress(userId, id);
|
||||
if (addressDO == null) {
|
||||
throw exception(ADDRESS_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberAddressDO getAddress(Long userId, Long id) {
|
||||
return memberAddressMapper.selectByIdAndUserId(id, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MemberAddressDO> getAddressList(Long userId) {
|
||||
return memberAddressMapper.selectListByUserIdAndDefaulted(userId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberAddressDO getDefaultUserAddress(Long userId) {
|
||||
List<MemberAddressDO> addresses = memberAddressMapper.selectListByUserIdAndDefaulted(userId, true);
|
||||
return CollUtil.getFirst(addresses);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
spring:
|
||||
main:
|
||||
lazy-initialization: true # 开启懒加载,加快速度
|
||||
banner-mode: off # 单元测试,禁用 Banner
|
||||
|
||||
--- #################### 数据库相关配置 ####################
|
||||
|
||||
spring:
|
||||
# 数据源配置项
|
||||
datasource:
|
||||
name: ruoyi-vue-pro
|
||||
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
|
||||
driver-class-name: org.h2.Driver
|
||||
username: sa
|
||||
password:
|
||||
druid:
|
||||
async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
|
||||
initial-size: 1 # 单元测试,配置为 1,提升启动速度
|
||||
sql:
|
||||
init:
|
||||
schema-locations: classpath:/sql/create_tables.sql
|
||||
|
||||
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||
data:
|
||||
redis:
|
||||
host: 127.0.0.1 # 地址
|
||||
port: 16379 # 端口(单元测试,使用 16379 端口)
|
||||
database: 0 # 数据库索引
|
||||
|
||||
mybatis:
|
||||
lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
|
||||
|
||||
--- #################### 定时任务相关配置 ####################
|
||||
|
||||
--- #################### 配置中心相关配置 ####################
|
||||
|
||||
--- #################### 服务保障相关配置 ####################
|
||||
|
||||
# Lock4j 配置项(单元测试,禁用 Lock4j)
|
||||
|
||||
--- #################### 监控相关配置 ####################
|
||||
|
||||
--- #################### 芋道相关配置 ####################
|
||||
|
||||
# 芋道配置项,设置当前项目所有自定义的配置
|
||||
yudao:
|
||||
info:
|
||||
base-package: cn.iocoder.yudao.module
|
||||
@@ -1,4 +0,0 @@
|
||||
<configuration>
|
||||
<!-- 引用 Spring Boot 的 logback 基础配置 -->
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||
</configuration>
|
||||
@@ -1,5 +0,0 @@
|
||||
DELETE FROM "member_user";
|
||||
DELETE FROM "member_address";
|
||||
DELETE FROM "member_tag";
|
||||
DELETE FROM "member_level";
|
||||
DELETE FROM "member_group";
|
||||
@@ -1,113 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS "member_user"
|
||||
(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号',
|
||||
"nickname" varchar(30) NOT NULL DEFAULT '' COMMENT '用户昵称',
|
||||
"name" varchar(30) NULL COMMENT '真实名字',
|
||||
sex tinyint null comment '性别',
|
||||
birthday datetime null comment '出生日期',
|
||||
area_id int null comment '所在地',
|
||||
mark varchar(255) null comment '用户备注',
|
||||
point int default 0 null comment '积分',
|
||||
"avatar" varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
|
||||
"status" tinyint NOT NULL COMMENT '状态',
|
||||
"mobile" varchar(11) NOT NULL COMMENT '手机号',
|
||||
"password" varchar(100) NOT NULL DEFAULT '' COMMENT '密码',
|
||||
"register_ip" varchar(32) NOT NULL COMMENT '注册 IP',
|
||||
"login_ip" varchar(50) NULL DEFAULT '' COMMENT '最后登录IP',
|
||||
"login_date" datetime NULL DEFAULT NULL COMMENT '最后登录时间',
|
||||
"tag_ids" varchar(255) NULL DEFAULT NULL COMMENT '用户标签编号列表,以逗号分隔',
|
||||
"level_id" bigint NULL DEFAULT NULL COMMENT '等级编号',
|
||||
"experience" bigint NULL DEFAULT NULL COMMENT '经验',
|
||||
"group_id" bigint NULL DEFAULT NULL COMMENT '用户分组编号',
|
||||
"creator" varchar(64) NULL DEFAULT '' COMMENT '创建者',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
"updater" varchar(64) NULL DEFAULT '' COMMENT '更新者',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
"deleted" bit(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '会员表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "member_address" (
|
||||
"id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint(20) NOT NULL,
|
||||
"name" varchar(10) NOT NULL,
|
||||
"mobile" varchar(20) NOT NULL,
|
||||
"area_id" bigint(20) NOT NULL,
|
||||
"detail_address" varchar(250) NOT NULL,
|
||||
"default_status" bit NOT NULL,
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '用户收件地址';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "member_tag"
|
||||
(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint NOT NULL default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '会员标签';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "member_level"
|
||||
(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar NOT NULL,
|
||||
"experience" int NOT NULL,
|
||||
"level" int NOT NULL,
|
||||
"discount_percent" int NOT NULL,
|
||||
"icon" varchar NOT NULL,
|
||||
"background_url" varchar NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint not null default '0',
|
||||
"status" tinyint NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '会员等级';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "member_group"
|
||||
(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar NOT NULL,
|
||||
"remark" varchar NOT NULL,
|
||||
"status" tinyint NOT NULL DEFAULT '0',
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '用户分组';
|
||||
CREATE TABLE IF NOT EXISTS "member_brokerage_record"
|
||||
(
|
||||
"id" int NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"biz_id" varchar NOT NULL,
|
||||
"biz_type" varchar NOT NULL,
|
||||
"title" varchar NOT NULL,
|
||||
"price" int NOT NULL,
|
||||
"total_price" int NOT NULL,
|
||||
"description" varchar NOT NULL,
|
||||
"status" varchar NOT NULL,
|
||||
"frozen_days" int NOT NULL,
|
||||
"unfreeze_time" varchar,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '佣金记录';
|
||||
@@ -4,7 +4,7 @@ package com.tashow.cloud.pay.controller.admin.transfer.vo;
|
||||
|
||||
import com.tashow.cloud.common.util.validation.ValidationUtils;
|
||||
import com.tashow.cloud.common.validation.InEnum;
|
||||
import com.tashow.cloud.sdk.payment.enums.channel.PayChannelEnum;
|
||||
import com.tashow.cloud.sdk.payment.enums.channel.PayTypeEnum;
|
||||
import com.tashow.cloud.sdk.payment.enums.transfer.PayTransferTypeEnum;
|
||||
import jakarta.validation.Validator;
|
||||
import jakarta.validation.constraints.*;
|
||||
@@ -83,7 +83,7 @@ public class PayTransferCreateReqVO {
|
||||
PayTransferTypeEnum transferType = typeOf(type);
|
||||
switch (transferType) {
|
||||
case ALIPAY_BALANCE: {
|
||||
return PayChannelEnum.isAlipay(channelCode);
|
||||
return PayTypeEnum.isAlipay(channelCode);
|
||||
}
|
||||
case WX_BALANCE:
|
||||
case BANK_CARD:
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.tashow.cloud.common.enums.CommonStatusEnum;
|
||||
import com.tashow.cloud.pay.dal.dataobject.app.PayAppDO;
|
||||
import com.tashow.cloud.sdk.payment.client.PayClientConfig;
|
||||
import com.tashow.cloud.sdk.payment.enums.channel.PayChannelEnum;
|
||||
import com.tashow.cloud.sdk.payment.enums.channel.PayTypeEnum;
|
||||
import com.tashow.cloud.tenant.core.db.TenantBaseDO;
|
||||
import lombok.*;
|
||||
|
||||
@@ -33,7 +33,7 @@ public class PayChannelDO extends TenantBaseDO {
|
||||
/**
|
||||
* 渠道编码
|
||||
*
|
||||
* 枚举 {@link PayChannelEnum}
|
||||
* 枚举 {@link PayTypeEnum}
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user