yanderong
2 天以前 686790777f722b0621bcc20e550d15965cda7b67
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
-- =============================================================================
-- 刷卡充电(SD)流程测试数据(实扣冻结锁定 + 授权停充 + 优惠结算)
-- 创建日期: 2026-09-29
-- 目标环境: 测试库 Mycat(192.168.110.111:8066),逻辑库 other/account/order/service
-- 配套脚本: doc/charging-link-test/run-sd-flow.ps1
-- 幂等: 可重复执行(先按 99xx 段清理再重建),与 VIN 流程数据(公司9901~9911/卡无)互不影响
--
-- 执行:
--   mysql --host=192.168.110.111 --port=8066 --user=root --password=123456 \
--         --default-character-set=utf8mb4 --batch --force -e "source <本文件>"
--
-- 场景矩阵(固定ID段 99xx;公司 9921~9933,卡 99201~99213,授权 9921~9933):
--  S1  公司9921 共享(50)     卡99201(余额0)   授权 全天 site19 auto0 下发30  优惠 1=不优惠
--  S2  公司9922 分配         卡99202(余额20)  授权 全天 site19 auto0 下发30  优惠 1=不优惠
--  S3  公司9923 共享(50)     卡99203          授权 指定时段(now-2h~now+3min) auto1 下发30
--  S4  公司9924 共享(50)     卡99204          授权 全天 site_ids=25(枪在site19)
--  S5  公司9925 共享(50)     卡99205          授权 指定时段 00:00~00:00(恒不命中)
--  S5b 公司9931 共享(50)     卡99211          授权 指定时段 time_ranges=NULL(放行分支)
--  S6a 公司9926 共享(0)      卡99206          授权 全天 下发30
--  S6b 公司9927 分配         卡99207(余额0)   授权 全天 下发30
--  S7  公司9928 共享(50/停用) 卡99208         授权 全天 下发30
--  S8a 公司9929 共享(50)     卡99209          授权 全天 site19 auto0 下发30  优惠 2=服务费折扣50%
--  S8b 公司9930 共享(50)     卡99210          授权 全天 site19 auto0 下发30  优惠 3=计费模板9902
--  S9  公司9932 共享(50)     卡99212(禁用)    授权 全天 下发30            -> 卡鉴权失败
--  S10 公司9933 共享(50)     卡99213(充电中)  授权 全天 下发30            -> 同卡并发锁卡失败
--
-- 结算断言依赖(计费策略254,6段,按 start_time 排序;第N段读 {type}_chargeN):
--  段1 00:00-08:00 type4谷 0.3300/0.4000  段2 08:00-10:00 type3平 0.6813/0.4000
--  段3 10:00-12:00 type2峰 1.0327/0.4000  段4/5/6 依次 平/峰/谷 同价
--  上报 valley_charge1=1.0 + flat_charge2=1.0 + peak_charge3=1.0 ->
--    S1/S2 电费 0.33+0.68+1.03=2.04 服务费 1.20 -> order_amount=3.24
--    S8a   服务费单价 0.40x50%=0.20x3=0.60 电费 2.04    -> order_amount=2.64
--    S8b   模板 谷0.20/0.30 平0.50/0.30 峰0.90/0.30      -> order_amount=2.50
--  锁定口径(实扣冻结):共享模式锁企业账户 available_balance-额度 并记 locked_amount;
--                       分配模式锁卡账户 balance-额度 并记 locked_amount。
-- =============================================================================
 
-- ============ 第0节 清理 ============
USE `charging_pile_order`;
-- 注:Mycat 不支持带子查询的删除,订单快照/明细表(t_card_charging_order_accounting_strategy 等)
--     由 run-sd-flow.ps1 先按 card_id 查出订单ID、再用 IN (...) 显式删除。
DELETE FROM `t_card_charging_order` WHERE card_id BETWEEN 99201 AND 99213;
 
USE `charging_pile_account`;
DELETE FROM `t_company_allocate_record` WHERE company_id BETWEEN 9921 AND 9933;
-- 卡余额流水(结算扣款 change_type=3 的唯一索引 uk_order_code 为幂等键):按卡ID段清理,保证重复执行后
-- 「扣款流水恰好1条」断言不受上一轮残留影响
DELETE FROM `t_charging_card_balance_record` WHERE card_id BETWEEN 99201 AND 99213;
-- 测试卡:先清后建,保证重复执行幂等(卡余额/锁定标志/绑定订单号重置为新值)
DELETE FROM `t_charging_card` WHERE id BETWEEN 99201 AND 99213;
 
USE `charging_pile_other`;
DELETE FROM `t_charge_authorization` WHERE company_id BETWEEN 9921 AND 9933;
DELETE FROM `t_company_preferential` WHERE company_id BETWEEN 9921 AND 9933;
DELETE FROM `t_group_company` WHERE id BETWEEN 9921 AND 9933;
 
USE `charging_pile_service`;
DELETE FROM `t_billing_template_detail` WHERE template_id = 9902;
DELETE FROM `t_billing_template` WHERE id = 9902;
 
-- ============ 第1节 测试公司(account_mode 1=共享 2=分配; status 1=启用 0=停用) ============
USE `charging_pile_other`;
INSERT INTO `t_group_company`
  (`id`,`name`,`account_mode`,`available_balance`,`locked_amount`,`status`,`remark`,`del_flag`) VALUES
  (9921,'SD测试-共享无优惠',   1, 50.00, 0.00, 1,'S1', 0),
  (9922,'SD测试-分配无优惠',   2,  0.00, 0.00, 1,'S2', 0),
  (9923,'SD测试-授权到期停充', 1, 50.00, 0.00, 1,'S3', 0),
  (9924,'SD测试-站点超范围',   1, 50.00, 0.00, 1,'S4', 0),
  (9925,'SD测试-时段外',       1, 50.00, 0.00, 1,'S5', 0),
  (9926,'SD测试-共享余额0',    1,  0.00, 0.00, 1,'S6a',0),
  (9927,'SD测试-分配余额0',    2,  0.00, 0.00, 1,'S6b',0),
  (9928,'SD测试-公司停用',     1, 50.00, 0.00, 0,'S7', 0),
  (9929,'SD测试-比例优惠',     1, 50.00, 0.00, 1,'S8a',0),
  (9930,'SD测试-模板优惠',     1, 50.00, 0.00, 1,'S8b',0),
  (9931,'SD测试-空时段放行',   1, 50.00, 0.00, 1,'S5b',0),
  (9932,'SD测试-卡禁用',       1, 50.00, 0.00, 1,'S9', 0),
  (9933,'SD测试-同卡并发',     1, 50.00, 0.00, 1,'S10',0);
 
-- ============ 第2节 测试卡(card_no 即设备上报 account 原文,区分大小写与前后空格) ============
--  status 1=启用 2=禁用;charging_flag 1=充电中锁定;balance 分配模式卡余额;locked_amount 锁定额度
USE `charging_pile_account`;
INSERT INTO `t_charging_card`
  (`id`,`card_no`,`password`,`balance`,`locked_amount`,`company_id`,`fleet_id`,`status`,`charging_flag`,`charging_order_code`,`del_flag`) VALUES
  (99201,'99201',NULL, 0.00,0.00,9921,NULL,1,0,NULL,0),
  (99202,'99202',NULL,20.00,0.00,9922,NULL,1,0,NULL,0),
  (99203,'99203',NULL, 0.00,0.00,9923,NULL,1,0,NULL,0),
  (99204,'99204',NULL, 0.00,0.00,9924,NULL,1,0,NULL,0),
  (99205,'99205',NULL, 0.00,0.00,9925,NULL,1,0,NULL,0),
  (99206,'99206',NULL, 0.00,0.00,9926,NULL,1,0,NULL,0),
  (99207,'99207',NULL, 0.00,0.00,9927,NULL,1,0,NULL,0),
  (99208,'99208',NULL, 0.00,0.00,9928,NULL,1,0,NULL,0),
  (99209,'99209',NULL, 0.00,0.00,9929,NULL,1,0,NULL,0),
  (99210,'99210',NULL, 0.00,0.00,9930,NULL,1,0,NULL,0),
  (99211,'99211',NULL, 0.00,0.00,9931,NULL,1,0,NULL,0),
  (99212,'99212',NULL, 0.00,0.00,9932,NULL,2,0,NULL,0),
  -- S10: 预置充电中锁定,另一个订单号占用,用于验证同卡并发锁卡失败(fail=4)
  (99213,'99213',NULL, 0.00,0.00,9933,NULL,1,1,'SD-OTHER-LOCK',0);
 
-- ============ 第3节 充电授权(time_mode 1=全天 2=指定时段 3=指定电价时段; auto_charge 1=到期自动停充) ============
USE `charging_pile_other`;
INSERT INTO `t_charge_authorization`
  (`id`,`company_id`,`time_mode`,`time_ranges`,`price_types`,`auto_charge`,`site_ids`,`dispatch_amount`,`del_flag`) VALUES
  (9921,9921,1,NULL,          NULL,    0,'19',30.00,0),
  (9922,9922,1,NULL,          NULL,    0,'19',30.00,0),
  -- S3: 当前时间-2h ~ 当前时间+3min(跨零点窗口退化为 00:00~23:59,由脚本推进 max_end_time 验证停充)
  (9923,9923,2,
     CASE WHEN HOUR(NOW()) < 3 OR HOUR(NOW()) >= 23
          THEN '[{"startTime":"00:00","endTime":"23:59"}]'
          ELSE CONCAT('[{"startTime":"', DATE_FORMAT(NOW() - INTERVAL 2 HOUR, '%H:%i'),
                      '","endTime":"',   DATE_FORMAT(NOW() + INTERVAL 3 MINUTE, '%H:%i'), '"}]')
     END,
     NULL,1,'19',30.00,0),
  (9924,9924,1,NULL,          NULL,    0,'25',30.00,0),
  (9925,9925,2,'[{"startTime":"00:00","endTime":"00:00"}]', NULL,0,'19',30.00,0),
  (9926,9926,1,NULL,          NULL,    0,'19',30.00,0),
  (9927,9927,1,NULL,          NULL,    0,'19',30.00,0),
  (9928,9928,1,NULL,          NULL,    0,'19',30.00,0),
  (9929,9929,1,NULL,          NULL,    0,'19',30.00,0),
  (9930,9930,1,NULL,          NULL,    0,'19',30.00,0),
  -- S5b: 指定时段但未配置时间段 -> 服务端按放行处理
  (9931,9931,2,NULL,          NULL,    0,'19',30.00,0),
  (9932,9932,1,NULL,          NULL,    0,'19',30.00,0),
  (9933,9933,1,NULL,          NULL,    0,'19',30.00,0);
 
-- ============ 第4节 公司优惠设置与计费模板 ============
-- preferential_type: 1=不优惠 2=服务费按比例折扣(service_discount_rate 百分比) 3=按计费模板优惠单价
USE `charging_pile_other`;
INSERT INTO `t_company_preferential`
  (`id`,`company_id`,`preferential_type`,`service_discount_rate`,`billing_template_id`,`del_flag`) VALUES
  (9921,9929,2,50.00,NULL,0),
  -- S8b 优惠方式3 必须落在本脚本第4节创建的计费模板 9902 上(曾误配其它模板导致查不到、按原价结算)
  (9922,9930,3,NULL,9902,0);
 
USE `charging_pile_service`;
INSERT INTO `t_billing_template` (`id`,`name`,`description`,`discount`,`del_flag`) VALUES
  (9902,'SD测试-模板优惠','刷卡充电流程测试 S8b',NULL,0);
INSERT INTO `t_billing_template_detail`
  (`id`,`template_id`,`type`,`start_time`,`end_time`,`electrovalence`,`service_charge`,`cost_service_charge`,`del_flag`) VALUES
  (9904,9902,4,'00:00','08:00',0.2000,0.3000,0.3000,0),
  (9905,9902,3,'08:00','10:00',0.5000,0.3000,0.3000,0),
  (9906,9902,2,'10:00','12:00',0.9000,0.3000,0.3000,0);
 
-- ============ 第5节 回查(执行后应输出 13 家公司 / 13 张卡 / 13 条授权 / 2 条优惠 / 模板3明细) ============
SELECT 'COMPANY' AS tag, id, name, account_mode, available_balance, locked_amount, status
  FROM charging_pile_other.t_group_company WHERE id BETWEEN 9921 AND 9933 ORDER BY id;
SELECT 'CARD' AS tag, id, card_no, company_id, balance, locked_amount, status, charging_flag, charging_order_code
  FROM charging_pile_account.t_charging_card WHERE id BETWEEN 99201 AND 99213 ORDER BY id;
SELECT 'AUTH' AS tag, id, company_id, time_mode, time_ranges, auto_charge, site_ids, dispatch_amount
  FROM charging_pile_other.t_charge_authorization WHERE id BETWEEN 9921 AND 9933 ORDER BY id;
SELECT 'PREF' AS tag, id, company_id, preferential_type, service_discount_rate, billing_template_id
  FROM charging_pile_other.t_company_preferential WHERE id BETWEEN 9921 AND 9922 ORDER BY id;
SELECT 'TPL' AS tag, id, template_id, type, start_time, end_time, electrovalence, service_charge
  FROM charging_pile_service.t_billing_template_detail WHERE template_id = 9902 ORDER BY id;
SELECT 'GUN' AS tag, g.id, g.code, g.status, g.site_id, p.code AS pile_code
  FROM charging_pile_service.t_charging_gun g
  JOIN charging_pile_service.t_charging_pile p ON p.id = g.charging_pile_id
 WHERE g.del_flag = 0 AND p.del_flag = 0 AND g.site_id = 19 ORDER BY g.id;