Commit 4dba84b7595ef3fb606ec60a5d5fe61e4287b038

Authored by YunaiV
1 parent a38811c9

fix: 修正 SQL Server 类型与短信布尔映射,完善工资条租户实体

sql/sqlserver/ruoyi-vue-pro.sql
... ... @@ -43,7 +43,7 @@ CREATE TABLE infra_api_access_log (
43 43 id bigint NOT NULL PRIMARY KEY IDENTITY,
44 44 trace_id nvarchar(64) DEFAULT '' NOT NULL,
45 45 user_id bigint DEFAULT 0 NOT NULL,
46   - user_type tinyint DEFAULT 0 NOT NULL,
  46 + user_type smallint DEFAULT 0 NOT NULL,
47 47 application_name nvarchar(50) NOT NULL,
48 48 request_method nvarchar(16) DEFAULT '' NOT NULL,
49 49 request_url nvarchar(255) DEFAULT '' NOT NULL,
... ... @@ -53,7 +53,7 @@ CREATE TABLE infra_api_access_log (
53 53 user_agent nvarchar(512) NOT NULL,
54 54 operate_module nvarchar(50) DEFAULT NULL NULL,
55 55 operate_name nvarchar(50) DEFAULT NULL NULL,
56   - operate_type tinyint DEFAULT 0 NULL,
  56 + operate_type smallint DEFAULT 0 NULL,
57 57 begin_time datetime2 NOT NULL,
58 58 end_time datetime2 NOT NULL,
59 59 duration int NOT NULL,
... ... @@ -260,7 +260,7 @@ CREATE TABLE infra_api_error_log (
260 260 id bigint NOT NULL PRIMARY KEY IDENTITY,
261 261 trace_id nvarchar(64) NOT NULL,
262 262 user_id bigint DEFAULT 0 NOT NULL,
263   - user_type tinyint DEFAULT 0 NOT NULL,
  263 + user_type smallint DEFAULT 0 NOT NULL,
264 264 application_name nvarchar(50) NOT NULL,
265 265 request_method nvarchar(16) NOT NULL,
266 266 request_url nvarchar(255) NOT NULL,
... ... @@ -276,7 +276,7 @@ CREATE TABLE infra_api_error_log (
276 276 exception_file_name nvarchar(512) NOT NULL,
277 277 exception_method_name nvarchar(512) NOT NULL,
278 278 exception_line_number int NOT NULL,
279   - process_status tinyint NOT NULL,
  279 + process_status smallint NOT NULL,
280 280 process_time datetime2 DEFAULT NULL NULL,
281 281 process_user_id int DEFAULT 0 NULL,
282 282 creator nvarchar(64) DEFAULT '' NULL,
... ... @@ -503,18 +503,18 @@ CREATE TABLE infra_codegen_column (
503 503 column_name nvarchar(200) NOT NULL,
504 504 data_type nvarchar(100) NOT NULL,
505 505 column_comment nvarchar(500) NOT NULL,
506   - nullable varchar(1) NOT NULL,
507   - primary_key varchar(1) NOT NULL,
  506 + nullable bit NOT NULL,
  507 + primary_key bit NOT NULL,
508 508 ordinal_position int NOT NULL,
509 509 java_type nvarchar(32) NOT NULL,
510 510 java_field nvarchar(64) NOT NULL,
511 511 dict_type nvarchar(200) DEFAULT '' NULL,
512 512 example nvarchar(64) DEFAULT NULL NULL,
513   - create_operation varchar(1) NOT NULL,
514   - update_operation varchar(1) NOT NULL,
515   - list_operation varchar(1) NOT NULL,
  513 + create_operation bit NOT NULL,
  514 + update_operation bit NOT NULL,
  515 + list_operation bit NOT NULL,
516 516 list_operation_condition nvarchar(32) DEFAULT '=' NOT NULL,
517   - list_operation_result varchar(1) NOT NULL,
  517 + list_operation_result bit NOT NULL,
518 518 html_type nvarchar(32) NOT NULL,
519 519 creator nvarchar(64) DEFAULT '' NULL,
520 520 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -701,7 +701,7 @@ GO
701 701 CREATE TABLE infra_codegen_table (
702 702 id bigint NOT NULL PRIMARY KEY IDENTITY,
703 703 data_source_config_id bigint NOT NULL,
704   - scene tinyint DEFAULT 1 NOT NULL,
  704 + scene smallint DEFAULT 1 NOT NULL,
705 705 table_name nvarchar(200) DEFAULT '' NOT NULL,
706 706 table_comment nvarchar(500) DEFAULT '' NOT NULL,
707 707 remark nvarchar(500) DEFAULT NULL NULL,
... ... @@ -710,12 +710,12 @@ CREATE TABLE infra_codegen_table (
710 710 class_name nvarchar(100) DEFAULT '' NOT NULL,
711 711 class_comment nvarchar(50) NOT NULL,
712 712 author nvarchar(50) NOT NULL,
713   - template_type tinyint DEFAULT 1 NOT NULL,
714   - front_type tinyint NOT NULL,
  713 + template_type smallint DEFAULT 1 NOT NULL,
  714 + front_type smallint NOT NULL,
715 715 parent_menu_id bigint DEFAULT NULL NULL,
716 716 master_table_id bigint DEFAULT NULL NULL,
717 717 sub_join_column_id bigint DEFAULT NULL NULL,
718   - sub_join_many varchar(1) DEFAULT NULL NULL,
  718 + sub_join_many bit DEFAULT NULL NULL,
719 719 tree_parent_column_id bigint DEFAULT NULL NULL,
720 720 tree_name_column_id bigint DEFAULT NULL NULL,
721 721 creator nvarchar(64) DEFAULT '' NULL,
... ... @@ -907,11 +907,11 @@ GO
907 907 CREATE TABLE infra_config (
908 908 id bigint NOT NULL PRIMARY KEY IDENTITY,
909 909 category nvarchar(50) NOT NULL,
910   - type tinyint NOT NULL,
  910 + type smallint NOT NULL,
911 911 name nvarchar(100) DEFAULT '' NOT NULL,
912 912 config_key nvarchar(100) DEFAULT '' NOT NULL,
913 913 value nvarchar(500) DEFAULT '' NOT NULL,
914   - visible varchar(1) NOT NULL,
  914 + visible bit NOT NULL,
915 915 remark nvarchar(500) DEFAULT NULL NULL,
916 916 creator nvarchar(64) DEFAULT '' NULL,
917 917 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -1260,9 +1260,9 @@ GO
1260 1260 CREATE TABLE infra_file_config (
1261 1261 id bigint NOT NULL PRIMARY KEY IDENTITY,
1262 1262 name nvarchar(63) NOT NULL,
1263   - storage tinyint NOT NULL,
  1263 + storage smallint NOT NULL,
1264 1264 remark nvarchar(255) DEFAULT NULL NULL,
1265   - master varchar(1) NOT NULL,
  1265 + master bit NOT NULL,
1266 1266 config nvarchar(4000) NOT NULL,
1267 1267 creator nvarchar(64) DEFAULT '' NULL,
1268 1268 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -1487,7 +1487,7 @@ GO
1487 1487 CREATE TABLE infra_job (
1488 1488 id bigint NOT NULL PRIMARY KEY IDENTITY,
1489 1489 name nvarchar(32) NOT NULL,
1490   - status tinyint NOT NULL,
  1490 + status smallint NOT NULL,
1491 1491 handler_name nvarchar(64) NOT NULL,
1492 1492 handler_param nvarchar(255) DEFAULT NULL NULL,
1493 1493 cron_expression nvarchar(32) NOT NULL,
... ... @@ -1687,11 +1687,11 @@ CREATE TABLE infra_job_log (
1687 1687 job_id bigint NOT NULL,
1688 1688 handler_name nvarchar(64) NOT NULL,
1689 1689 handler_param nvarchar(255) DEFAULT NULL NULL,
1690   - execute_index tinyint DEFAULT 1 NOT NULL,
  1690 + execute_index smallint DEFAULT 1 NOT NULL,
1691 1691 begin_time datetime2 NOT NULL,
1692 1692 end_time datetime2 DEFAULT NULL NULL,
1693 1693 duration int DEFAULT NULL NULL,
1694   - status tinyint NOT NULL,
  1694 + status smallint NOT NULL,
1695 1695 result nvarchar(4000) DEFAULT '' NULL,
1696 1696 creator nvarchar(64) DEFAULT '' NULL,
1697 1697 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -1829,7 +1829,7 @@ CREATE TABLE system_dept (
1829 1829 leader_user_id bigint DEFAULT NULL NULL,
1830 1830 phone nvarchar(11) DEFAULT NULL NULL,
1831 1831 email nvarchar(50) DEFAULT NULL NULL,
1832   - status tinyint NOT NULL,
  1832 + status smallint NOT NULL,
1833 1833 creator nvarchar(64) DEFAULT '' NULL,
1834 1834 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
1835 1835 updater nvarchar(64) DEFAULT '' NULL,
... ... @@ -1999,7 +1999,7 @@ CREATE TABLE system_dict_data (
1999 1999 label nvarchar(100) DEFAULT '' NOT NULL,
2000 2000 value nvarchar(100) DEFAULT '' NOT NULL,
2001 2001 dict_type nvarchar(100) DEFAULT '' NOT NULL,
2002   - status tinyint DEFAULT 0 NOT NULL,
  2002 + status smallint DEFAULT 0 NOT NULL,
2003 2003 color_type nvarchar(100) DEFAULT '' NULL,
2004 2004 css_class nvarchar(100) DEFAULT '' NULL,
2005 2005 remark nvarchar(500) DEFAULT NULL NULL,
... ... @@ -5251,7 +5251,7 @@ CREATE TABLE system_dict_type (
5251 5251 id bigint NOT NULL PRIMARY KEY IDENTITY,
5252 5252 name nvarchar(100) DEFAULT '' NOT NULL,
5253 5253 type nvarchar(100) DEFAULT '' NOT NULL,
5254   - status tinyint DEFAULT 0 NOT NULL,
  5254 + status smallint DEFAULT 0 NOT NULL,
5255 5255 remark nvarchar(500) DEFAULT NULL NULL,
5256 5256 creator nvarchar(64) DEFAULT '' NULL,
5257 5257 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -6056,9 +6056,9 @@ CREATE TABLE system_login_log (
6056 6056 log_type bigint NOT NULL,
6057 6057 trace_id nvarchar(64) DEFAULT '' NOT NULL,
6058 6058 user_id bigint DEFAULT 0 NOT NULL,
6059   - user_type tinyint DEFAULT 0 NOT NULL,
  6059 + user_type smallint DEFAULT 0 NOT NULL,
6060 6060 username nvarchar(50) DEFAULT '' NOT NULL,
6061   - result tinyint NOT NULL,
  6061 + result smallint NOT NULL,
6062 6062 user_ip nvarchar(50) NOT NULL,
6063 6063 user_agent nvarchar(512) NOT NULL,
6064 6064 creator nvarchar(64) DEFAULT '' NULL,
... ... @@ -6197,8 +6197,8 @@ CREATE TABLE system_mail_account (
6197 6197 password nvarchar(255) NOT NULL,
6198 6198 host nvarchar(255) NOT NULL,
6199 6199 port int NOT NULL,
6200   - ssl_enable varchar(1) DEFAULT '0' NOT NULL,
6201   - starttls_enable varchar(1) DEFAULT '0' NOT NULL,
  6200 + ssl_enable bit DEFAULT 0 NOT NULL,
  6201 + starttls_enable bit DEFAULT 0 NOT NULL,
6202 6202 creator nvarchar(64) DEFAULT '' NULL,
6203 6203 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
6204 6204 updater nvarchar(64) DEFAULT '' NULL,
... ... @@ -6333,7 +6333,7 @@ GO
6333 6333 CREATE TABLE system_mail_log (
6334 6334 id bigint NOT NULL PRIMARY KEY IDENTITY,
6335 6335 user_id bigint DEFAULT NULL NULL,
6336   - user_type tinyint DEFAULT NULL NULL,
  6336 + user_type smallint DEFAULT NULL NULL,
6337 6337 to_mails nvarchar(1024) NOT NULL,
6338 6338 cc_mails nvarchar(1024) DEFAULT NULL NULL,
6339 6339 bcc_mails nvarchar(1024) DEFAULT NULL NULL,
... ... @@ -6345,7 +6345,7 @@ CREATE TABLE system_mail_log (
6345 6345 template_title nvarchar(255) NOT NULL,
6346 6346 template_content nvarchar(max) NOT NULL,
6347 6347 template_params nvarchar(255) NOT NULL,
6348   - send_status tinyint DEFAULT 0 NOT NULL,
  6348 + send_status smallint DEFAULT 0 NOT NULL,
6349 6349 send_time datetime2 DEFAULT NULL NULL,
6350 6350 send_message_id nvarchar(255) DEFAULT NULL NULL,
6351 6351 send_exception nvarchar(4000) DEFAULT NULL NULL,
... ... @@ -6537,7 +6537,7 @@ CREATE TABLE system_mail_template (
6537 6537 title nvarchar(255) NOT NULL,
6538 6538 content nvarchar(4000) NOT NULL,
6539 6539 params nvarchar(255) NOT NULL,
6540   - status tinyint NOT NULL,
  6540 + status smallint NOT NULL,
6541 6541 remark nvarchar(255) DEFAULT NULL NULL,
6542 6542 creator nvarchar(64) DEFAULT '' NULL,
6543 6543 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -6686,17 +6686,17 @@ CREATE TABLE system_menu (
6686 6686 id bigint NOT NULL PRIMARY KEY IDENTITY,
6687 6687 name nvarchar(50) NOT NULL,
6688 6688 permission nvarchar(100) DEFAULT '' NOT NULL,
6689   - type tinyint NOT NULL,
  6689 + type smallint NOT NULL,
6690 6690 sort int DEFAULT 0 NOT NULL,
6691 6691 parent_id bigint DEFAULT 0 NOT NULL,
6692 6692 path nvarchar(200) DEFAULT '' NULL,
6693 6693 icon nvarchar(100) DEFAULT '#' NULL,
6694 6694 component nvarchar(255) DEFAULT NULL NULL,
6695 6695 component_name nvarchar(255) DEFAULT NULL NULL,
6696   - status tinyint DEFAULT 0 NOT NULL,
6697   - visible varchar(1) DEFAULT '1' NOT NULL,
6698   - keep_alive varchar(1) DEFAULT '1' NOT NULL,
6699   - always_show varchar(1) DEFAULT '1' NOT NULL,
  6696 + status smallint DEFAULT 0 NOT NULL,
  6697 + visible bit DEFAULT 1 NOT NULL,
  6698 + keep_alive bit DEFAULT 1 NOT NULL,
  6699 + always_show bit DEFAULT 1 NOT NULL,
6700 6700 creator nvarchar(64) DEFAULT '' NULL,
6701 6701 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
6702 6702 updater nvarchar(64) DEFAULT '' NULL,
... ... @@ -11190,8 +11190,8 @@ CREATE TABLE system_notice (
11190 11190 id bigint NOT NULL PRIMARY KEY IDENTITY,
11191 11191 title nvarchar(50) NOT NULL,
11192 11192 content nvarchar(max) NOT NULL,
11193   - type tinyint NOT NULL,
11194   - status tinyint DEFAULT 0 NOT NULL,
  11193 + type smallint NOT NULL,
  11194 + status smallint DEFAULT 0 NOT NULL,
11195 11195 creator nvarchar(64) DEFAULT '' NULL,
11196 11196 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
11197 11197 updater nvarchar(64) DEFAULT '' NULL,
... ... @@ -11311,14 +11311,14 @@ GO
11311 11311 CREATE TABLE system_notify_message (
11312 11312 id bigint NOT NULL PRIMARY KEY IDENTITY,
11313 11313 user_id bigint NOT NULL,
11314   - user_type tinyint NOT NULL,
  11314 + user_type smallint NOT NULL,
11315 11315 template_id bigint NOT NULL,
11316 11316 template_code nvarchar(64) NOT NULL,
11317 11317 template_nickname nvarchar(63) NOT NULL,
11318 11318 template_content nvarchar(1024) NOT NULL,
11319 11319 template_type int NOT NULL,
11320 11320 template_params nvarchar(255) NOT NULL,
11321   - read_status varchar(1) NOT NULL,
  11321 + read_status bit NOT NULL,
11322 11322 read_time datetime2 DEFAULT NULL NULL,
11323 11323 creator nvarchar(64) DEFAULT '' NULL,
11324 11324 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -11671,9 +11671,9 @@ CREATE TABLE system_notify_template (
11671 11671 code nvarchar(64) NOT NULL,
11672 11672 nickname nvarchar(255) NOT NULL,
11673 11673 content nvarchar(1024) NOT NULL,
11674   - type tinyint NOT NULL,
  11674 + type smallint NOT NULL,
11675 11675 params nvarchar(255) DEFAULT NULL NULL,
11676   - status tinyint NOT NULL,
  11676 + status smallint NOT NULL,
11677 11677 remark nvarchar(255) DEFAULT NULL NULL,
11678 11678 creator nvarchar(64) DEFAULT '' NULL,
11679 11679 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -11794,7 +11794,7 @@ GO
11794 11794 CREATE TABLE system_oauth2_access_token (
11795 11795 id bigint NOT NULL PRIMARY KEY IDENTITY,
11796 11796 user_id bigint NOT NULL,
11797   - user_type tinyint NOT NULL,
  11797 + user_type smallint NOT NULL,
11798 11798 user_info nvarchar(512) NOT NULL,
11799 11799 access_token nvarchar(255) NOT NULL,
11800 11800 refresh_token nvarchar(32) NOT NULL,
... ... @@ -11933,10 +11933,10 @@ GO
11933 11933 CREATE TABLE system_oauth2_approve (
11934 11934 id bigint NOT NULL PRIMARY KEY IDENTITY,
11935 11935 user_id bigint NOT NULL,
11936   - user_type tinyint NOT NULL,
  11936 + user_type smallint NOT NULL,
11937 11937 client_id nvarchar(255) NOT NULL,
11938 11938 scope nvarchar(255) DEFAULT '' NOT NULL,
11939   - approved varchar(1) DEFAULT '0' NOT NULL,
  11939 + approved bit DEFAULT 0 NOT NULL,
11940 11940 expires_time datetime2 NOT NULL,
11941 11941 creator nvarchar(64) DEFAULT '' NULL,
11942 11942 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -12058,7 +12058,7 @@ CREATE TABLE system_oauth2_client (
12058 12058 name nvarchar(255) NOT NULL,
12059 12059 logo nvarchar(255) NOT NULL,
12060 12060 description nvarchar(255) DEFAULT NULL NULL,
12061   - status tinyint NOT NULL,
  12061 + status smallint NOT NULL,
12062 12062 access_token_validity_seconds int NOT NULL,
12063 12063 refresh_token_validity_seconds int NOT NULL,
12064 12064 redirect_uris nvarchar(255) NOT NULL,
... ... @@ -12261,7 +12261,7 @@ GO
12261 12261 CREATE TABLE system_oauth2_code (
12262 12262 id bigint NOT NULL PRIMARY KEY IDENTITY,
12263 12263 user_id bigint NOT NULL,
12264   - user_type tinyint NOT NULL,
  12264 + user_type smallint NOT NULL,
12265 12265 code nvarchar(32) NOT NULL,
12266 12266 client_id nvarchar(255) NOT NULL,
12267 12267 scopes nvarchar(255) DEFAULT '' NULL,
... ... @@ -12399,7 +12399,7 @@ CREATE TABLE system_oauth2_refresh_token (
12399 12399 id bigint NOT NULL PRIMARY KEY IDENTITY,
12400 12400 user_id bigint NOT NULL,
12401 12401 refresh_token nvarchar(32) NOT NULL,
12402   - user_type tinyint NOT NULL,
  12402 + user_type smallint NOT NULL,
12403 12403 client_id nvarchar(255) NOT NULL,
12404 12404 scopes nvarchar(255) DEFAULT NULL NULL,
12405 12405 expires_time datetime2 NOT NULL,
... ... @@ -12520,12 +12520,12 @@ CREATE TABLE system_operate_log (
12520 12520 id bigint NOT NULL PRIMARY KEY IDENTITY,
12521 12521 trace_id nvarchar(64) DEFAULT '' NOT NULL,
12522 12522 user_id bigint NOT NULL,
12523   - user_type tinyint DEFAULT 0 NOT NULL,
  12523 + user_type smallint DEFAULT 0 NOT NULL,
12524 12524 type nvarchar(50) NOT NULL,
12525 12525 sub_type nvarchar(50) NOT NULL,
12526 12526 biz_id bigint NOT NULL,
12527 12527 action nvarchar(2000) DEFAULT '' NOT NULL,
12528   - success varchar(1) DEFAULT '1' NOT NULL,
  12528 + success bit DEFAULT 1 NOT NULL,
12529 12529 extra nvarchar(2000) DEFAULT '' NOT NULL,
12530 12530 request_method nvarchar(16) DEFAULT '' NULL,
12531 12531 request_url nvarchar(255) DEFAULT '' NULL,
... ... @@ -12700,7 +12700,7 @@ CREATE TABLE system_post (
12700 12700 code nvarchar(64) NOT NULL,
12701 12701 name nvarchar(50) NOT NULL,
12702 12702 sort int NOT NULL,
12703   - status tinyint NOT NULL,
  12703 + status smallint NOT NULL,
12704 12704 remark nvarchar(500) DEFAULT NULL NULL,
12705 12705 creator nvarchar(64) DEFAULT '' NULL,
12706 12706 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -12832,10 +12832,10 @@ CREATE TABLE system_role (
12832 12832 name nvarchar(30) NOT NULL,
12833 12833 code nvarchar(100) NOT NULL,
12834 12834 sort int NOT NULL,
12835   - data_scope tinyint DEFAULT 1 NOT NULL,
  12835 + data_scope smallint DEFAULT 1 NOT NULL,
12836 12836 data_scope_dept_ids nvarchar(500) DEFAULT '' NOT NULL,
12837   - status tinyint NOT NULL,
12838   - type tinyint NOT NULL,
  12837 + status smallint NOT NULL,
  12838 + type smallint NOT NULL,
12839 12839 remark nvarchar(500) DEFAULT NULL NULL,
12840 12840 creator nvarchar(64) DEFAULT '' NULL,
12841 12841 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -16200,7 +16200,7 @@ CREATE TABLE system_sms_channel (
16200 16200 id bigint NOT NULL PRIMARY KEY IDENTITY,
16201 16201 signature nvarchar(12) NOT NULL,
16202 16202 code nvarchar(63) NOT NULL,
16203   - status tinyint NOT NULL,
  16203 + status smallint NOT NULL,
16204 16204 remark nvarchar(255) DEFAULT NULL NULL,
16205 16205 api_key nvarchar(128) NOT NULL,
16206 16206 api_secret nvarchar(128) DEFAULT NULL NULL,
... ... @@ -16339,9 +16339,9 @@ CREATE TABLE system_sms_code (
16339 16339 mobile nvarchar(11) NOT NULL,
16340 16340 code nvarchar(6) NOT NULL,
16341 16341 create_ip nvarchar(15) NOT NULL,
16342   - scene tinyint NOT NULL,
16343   - today_index tinyint NOT NULL,
16344   - used tinyint NOT NULL,
  16342 + scene smallint NOT NULL,
  16343 + today_index smallint NOT NULL,
  16344 + used smallint NOT NULL,
16345 16345 used_time datetime2 DEFAULT NULL NULL,
16346 16346 used_ip nvarchar(255) DEFAULT NULL NULL,
16347 16347 creator nvarchar(64) DEFAULT '' NULL,
... ... @@ -16477,20 +16477,20 @@ CREATE TABLE system_sms_log (
16477 16477 channel_code nvarchar(63) NOT NULL,
16478 16478 template_id bigint NOT NULL,
16479 16479 template_code nvarchar(63) NOT NULL,
16480   - template_type tinyint NOT NULL,
  16480 + template_type smallint NOT NULL,
16481 16481 template_content nvarchar(255) NOT NULL,
16482 16482 template_params nvarchar(255) NOT NULL,
16483 16483 api_template_id nvarchar(63) NOT NULL,
16484 16484 mobile nvarchar(11) NOT NULL,
16485 16485 user_id bigint DEFAULT NULL NULL,
16486   - user_type tinyint DEFAULT NULL NULL,
16487   - send_status tinyint DEFAULT 0 NOT NULL,
  16486 + user_type smallint DEFAULT NULL NULL,
  16487 + send_status smallint DEFAULT 0 NOT NULL,
16488 16488 send_time datetime2 DEFAULT NULL NULL,
16489 16489 api_send_code nvarchar(63) DEFAULT NULL NULL,
16490 16490 api_send_msg nvarchar(255) DEFAULT NULL NULL,
16491 16491 api_request_id nvarchar(255) DEFAULT NULL NULL,
16492 16492 api_serial_no nvarchar(255) DEFAULT NULL NULL,
16493   - receive_status tinyint DEFAULT 0 NOT NULL,
  16493 + receive_status smallint DEFAULT 0 NOT NULL,
16494 16494 receive_time datetime2 DEFAULT NULL NULL,
16495 16495 api_receive_code nvarchar(63) DEFAULT NULL NULL,
16496 16496 api_receive_msg nvarchar(255) DEFAULT NULL NULL,
... ... @@ -16703,8 +16703,8 @@ DROP TABLE IF EXISTS system_sms_template
16703 16703 GO
16704 16704 CREATE TABLE system_sms_template (
16705 16705 id bigint NOT NULL PRIMARY KEY IDENTITY,
16706   - type tinyint NOT NULL,
16707   - status tinyint NOT NULL,
  16706 + type smallint NOT NULL,
  16707 + status smallint NOT NULL,
16708 16708 code nvarchar(63) NOT NULL,
16709 16709 name nvarchar(63) NOT NULL,
16710 16710 content nvarchar(255) NOT NULL,
... ... @@ -16890,13 +16890,13 @@ GO
16890 16890 CREATE TABLE system_social_client (
16891 16891 id bigint NOT NULL PRIMARY KEY IDENTITY,
16892 16892 name nvarchar(255) NOT NULL,
16893   - social_type tinyint NOT NULL,
16894   - user_type tinyint NOT NULL,
  16893 + social_type smallint NOT NULL,
  16894 + user_type smallint NOT NULL,
16895 16895 client_id nvarchar(255) NOT NULL,
16896 16896 client_secret nvarchar(255) NOT NULL,
16897 16897 agent_id nvarchar(255) DEFAULT NULL NULL,
16898 16898 public_key nvarchar(2048) DEFAULT NULL NULL,
16899   - status tinyint NOT NULL,
  16899 + status smallint NOT NULL,
16900 16900 creator nvarchar(64) DEFAULT '' NULL,
16901 16901 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
16902 16902 updater nvarchar(64) DEFAULT '' NULL,
... ... @@ -17053,7 +17053,7 @@ DROP TABLE IF EXISTS system_social_user
17053 17053 GO
17054 17054 CREATE TABLE system_social_user (
17055 17055 id bigint NOT NULL PRIMARY KEY IDENTITY,
17056   - type tinyint NOT NULL,
  17056 + type smallint NOT NULL,
17057 17057 openid nvarchar(32) NOT NULL,
17058 17058 token nvarchar(256) DEFAULT NULL NULL,
17059 17059 raw_token_info nvarchar(1024) NOT NULL,
... ... @@ -17201,8 +17201,8 @@ GO
17201 17201 CREATE TABLE system_social_user_bind (
17202 17202 id bigint NOT NULL PRIMARY KEY IDENTITY,
17203 17203 user_id bigint NOT NULL,
17204   - user_type tinyint NOT NULL,
17205   - social_type tinyint NOT NULL,
  17204 + user_type smallint NOT NULL,
  17205 + social_type smallint NOT NULL,
17206 17206 social_user_id bigint NOT NULL,
17207 17207 creator nvarchar(64) DEFAULT '' NULL,
17208 17208 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
... ... @@ -17309,7 +17309,7 @@ CREATE TABLE system_tenant (
17309 17309 contact_user_id bigint DEFAULT NULL NULL,
17310 17310 contact_name nvarchar(30) NOT NULL,
17311 17311 contact_mobile nvarchar(500) DEFAULT NULL NULL,
17312   - status tinyint DEFAULT 0 NOT NULL,
  17312 + status smallint DEFAULT 0 NOT NULL,
17313 17313 websites nvarchar(1024) DEFAULT '' NULL,
17314 17314 package_id bigint NOT NULL,
17315 17315 expire_time datetime2 NOT NULL,
... ... @@ -17460,7 +17460,7 @@ GO
17460 17460 CREATE TABLE system_tenant_package (
17461 17461 id bigint NOT NULL PRIMARY KEY IDENTITY,
17462 17462 name nvarchar(30) NOT NULL,
17463   - status tinyint DEFAULT 0 NOT NULL,
  17463 + status smallint DEFAULT 0 NOT NULL,
17464 17464 remark nvarchar(256) DEFAULT '' NULL,
17465 17465 menu_ids nvarchar(4000) NOT NULL,
17466 17466 creator nvarchar(64) DEFAULT '' NOT NULL,
... ... @@ -17850,9 +17850,9 @@ CREATE TABLE system_users (
17850 17850 post_ids nvarchar(255) DEFAULT NULL NULL,
17851 17851 email nvarchar(50) DEFAULT '' NULL,
17852 17852 mobile nvarchar(11) DEFAULT '' NULL,
17853   - sex tinyint DEFAULT 0 NULL,
  17853 + sex smallint DEFAULT 0 NULL,
17854 17854 avatar nvarchar(512) DEFAULT '' NULL,
17855   - status tinyint DEFAULT 0 NOT NULL,
  17855 + status smallint DEFAULT 0 NOT NULL,
17856 17856 login_ip nvarchar(50) DEFAULT '' NULL,
17857 17857 login_date datetime2 DEFAULT NULL NULL,
17858 17858 creator nvarchar(64) DEFAULT '' NULL,
... ... @@ -18082,7 +18082,7 @@ GO
18082 18082 CREATE TABLE yudao_demo01_contact (
18083 18083 id bigint NOT NULL PRIMARY KEY IDENTITY,
18084 18084 name nvarchar(100) DEFAULT '' NOT NULL,
18085   - sex tinyint NOT NULL,
  18085 + sex smallint NOT NULL,
18086 18086 birthday datetime2 NOT NULL,
18087 18087 description nvarchar(255) NOT NULL,
18088 18088 avatar nvarchar(512) DEFAULT NULL NULL,
... ... @@ -18323,7 +18323,7 @@ CREATE TABLE yudao_demo03_course (
18323 18323 id bigint NOT NULL PRIMARY KEY IDENTITY,
18324 18324 student_id bigint NOT NULL,
18325 18325 name nvarchar(100) DEFAULT '' NOT NULL,
18326   - score tinyint NOT NULL,
  18326 + score smallint NOT NULL,
18327 18327 creator nvarchar(64) DEFAULT '' NULL,
18328 18328 create_time datetime2 DEFAULT CURRENT_TIMESTAMP NOT NULL,
18329 18329 updater nvarchar(64) DEFAULT '' NULL,
... ... @@ -18578,7 +18578,7 @@ GO
18578 18578 CREATE TABLE yudao_demo03_student (
18579 18579 id bigint NOT NULL PRIMARY KEY IDENTITY,
18580 18580 name nvarchar(100) DEFAULT '' NOT NULL,
18581   - sex tinyint NOT NULL,
  18581 + sex smallint NOT NULL,
18582 18582 birthday datetime2 NOT NULL,
18583 18583 description nvarchar(255) NOT NULL,
18584 18584 creator nvarchar(64) DEFAULT '' NULL,
... ...
sql/tools/convertor.py
... ... @@ -800,9 +800,20 @@ class SQLServerConvertor(Convertor):
800 800 if type in ("datetime", "timestamp"):
801 801 return "datetime2"
802 802 if type == "bit":
803   - return "varchar(1)"
  803 + # MySQL bit(1) 与 SQL Server bit 均只有 0、1、NULL;多位的位串不是布尔值,暂不支持
  804 + if size not in (None, 1):
  805 + raise ValueError(f"SQL Server 转换暂不支持 bit({size}),仅支持 bit(1)")
  806 + return "bit"
  807 + # SQL Server 的 tinyint 为 0 ~ 255,smallint 为 -32768 ~ 32767,需要选择能容纳 MySQL 取值范围的类型
804 808 if type in ("tinyint", "smallint"):
  809 + # 有符号:MySQL tinyint 为 -128 ~ 127,smallint 为 -32768 ~ 32767
  810 + return "smallint"
  811 + if type == "tinyint unsigned":
  812 + # 无符号:0 ~ 255
805 813 return "tinyint"
  814 + if type == "smallint unsigned":
  815 + # 无符号:0 ~ 65535
  816 + return "int"
806 817 if type in ("text", "longtext"):
807 818 return "nvarchar(max)"
808 819 if type in ("blob", "mediumblob"):
... ... @@ -825,7 +836,11 @@ class SQLServerConvertor(Convertor):
825 836 type = col["type"].lower()
826 837 full_type = self.translate_type(type, col["size"])
827 838 nullable = "NULL" if col["nullable"] else "NOT NULL"
828   - default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
  839 + default_value = col["default"]
  840 + # bit 的默认值使用数字常量:b'0'、b'1' 在清理后为 '0'、'1'
  841 + if full_type == "bit" and default_value in ("'0'", "'1'"):
  842 + default_value = default_value.strip("'")
  843 + default = f"DEFAULT {default_value}" if default_value is not None else ""
829 844 return f"{name} {full_type} {default} {nullable}"
830 845  
831 846 table_name = ddl["table_name"].lower()
... ...
sql/tools/test_convertor.py
... ... @@ -286,6 +286,130 @@ INSERT INTO `demo_bom` (`id`, `name`) VALUES (1, 'a\ufeffb');
286 286 self.assertNotIn("Table structure for ghost", out)
287 287  
288 288  
  289 +class SQLServerConvertorTest(unittest.TestCase):
  290 + # MySQL 整数取值范围:https://dev.mysql.com/doc/refman/8.4/en/integer-types.html
  291 + MYSQL_INTEGER_RANGES = {
  292 + "tinyint": (-128, 127),
  293 + "tinyint unsigned": (0, 255),
  294 + "smallint": (-32768, 32767),
  295 + "smallint unsigned": (0, 65535),
  296 + }
  297 + # SQL Server 整数取值范围:https://learn.microsoft.com/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql
  298 + SQLSERVER_INTEGER_RANGES = {
  299 + "tinyint": (0, 255),
  300 + "smallint": (-32768, 32767),
  301 + "int": (-2 ** 31, 2 ** 31 - 1),
  302 + "bigint": (-2 ** 63, 2 ** 63 - 1),
  303 + }
  304 +
  305 + TYPE_TABLE = """
  306 +DROP TABLE IF EXISTS `demo_type`;
  307 +CREATE TABLE `demo_type` (
  308 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  309 + `grade` tinyint NOT NULL DEFAULT 0 COMMENT '有符号 tinyint',
  310 + `sex` tinyint(1) NOT NULL DEFAULT 0 COMMENT '性别',
  311 + `score` smallint NOT NULL DEFAULT 0 COMMENT '有符号 smallint',
  312 + `ratio` tinyint unsigned NOT NULL DEFAULT 255 COMMENT '无符号 tinyint',
  313 + `port` smallint unsigned NOT NULL DEFAULT 65535 COMMENT '无符号 smallint',
  314 + `enabled` bit(1) NOT NULL DEFAULT b'1' COMMENT '是否启用',
  315 + `visible` bit(1) NULL DEFAULT NULL COMMENT '是否可见',
  316 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  317 + PRIMARY KEY (`id`) USING BTREE
  318 +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '类型表';
  319 +
  320 +BEGIN;
  321 +INSERT INTO `demo_type` (`id`, `grade`, `sex`, `score`, `ratio`, `port`, `enabled`, `visible`, `deleted`) VALUES (1, -128, 1, -32768, 255, 65535, b'0', NULL, b'0');
  322 +INSERT INTO `demo_type` (`id`, `grade`, `sex`, `score`, `ratio`, `port`, `enabled`, `visible`, `deleted`) VALUES (2, 127, 0, 32767, 0, 0, b'1', b'1', b'0');
  323 +COMMIT;
  324 +"""
  325 +
  326 + def setUp(self):
  327 + directory = tempfile.TemporaryDirectory()
  328 + self.addCleanup(directory.cleanup)
  329 + self.directory = directory.name
  330 +
  331 + def write_sql(self, content):
  332 + path = os.path.join(self.directory, "dump.sql")
  333 + with open(path, "w", encoding="utf-8") as f:
  334 + f.write(content)
  335 + return path
  336 +
  337 + def test_translate_type_integer_range(self):
  338 + convertor = SQLServerConvertor(self.write_sql(HEADER + DEMO_TABLE))
  339 + for mysql_type, (mysql_min, mysql_max) in self.MYSQL_INTEGER_RANGES.items():
  340 + with self.subTest(mysql_type):
  341 + target_type = convertor.translate_type(mysql_type, None)
  342 + target_min, target_max = self.SQLSERVER_INTEGER_RANGES[target_type]
  343 + # 目标类型需要容纳负数、大于 255 等全部取值
  344 + self.assertLessEqual(target_min, mysql_min)
  345 + self.assertGreaterEqual(target_max, mysql_max)
  346 + # tinyint(1) 的显示宽度不影响取值范围
  347 + self.assertEqual("smallint", convertor.translate_type("tinyint", 1))
  348 + # 无符号 tinyint 保持 tinyint,不扩大类型
  349 + self.assertEqual("tinyint", convertor.translate_type("TINYINT UNSIGNED", None))
  350 +
  351 + def test_translate_type_bit(self):
  352 + convertor = SQLServerConvertor(self.write_sql(HEADER + DEMO_TABLE))
  353 + self.assertEqual("bit", convertor.translate_type("bit", 1))
  354 + self.assertEqual("bit", convertor.translate_type("bit", None))
  355 + # 多位的位串不是布尔值,不能转换为 bit
  356 + with self.assertRaises(ValueError):
  357 + convertor.translate_type("bit", 8)
  358 +
  359 + def test_integer_and_bit(self):
  360 + out, err = convert(SQLServerConvertor(self.write_sql(HEADER + self.TYPE_TABLE)))
  361 + self.assertNotIn("无法正常解析", err)
  362 + # 有符号 tinyint、smallint:smallint
  363 + self.assertIn("grade smallint DEFAULT 0 NOT NULL", out)
  364 + self.assertIn("sex smallint DEFAULT 0 NOT NULL", out)
  365 + self.assertIn("score smallint DEFAULT 0 NOT NULL", out)
  366 + # 无符号 tinyint:tinyint;无符号 smallint:int
  367 + self.assertIn("ratio tinyint DEFAULT 255 NOT NULL", out)
  368 + self.assertIn("port int DEFAULT 65535 NOT NULL", out)
  369 + # bit(1):bit,默认值为数字常量,允许 NULL
  370 + self.assertIn("enabled bit DEFAULT 1 NOT NULL", out)
  371 + self.assertIn("visible bit DEFAULT NULL NULL", out)
  372 + self.assertIn("deleted bit DEFAULT 0 NOT NULL", out)
  373 + self.assertNotIn("varchar(1)", out)
  374 + # INSERT 保留负数、大于 255 的取值;bit 的 '0'、'1' 由 SQL Server 隐式转换
  375 + self.assertIn("INSERT INTO demo_type (id, grade, sex, score, ratio, port, enabled, visible, deleted)"
  376 + " VALUES (1, -128, 1, -32768, 255, 65535, N'0', NULL, N'0')\nGO", out)
  377 + self.assertIn("INSERT INTO demo_type (id, grade, sex, score, ratio, port, enabled, visible, deleted)"
  378 + " VALUES (2, 127, 0, 32767, 0, 0, N'1', N'1', N'0')\nGO", out)
  379 +
  380 + def test_bit_multiple(self):
  381 + sql = HEADER + """
  382 +CREATE TABLE `demo_flags` (
  383 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  384 + `flags` bit(8) NOT NULL COMMENT '位串',
  385 + PRIMARY KEY (`id`) USING BTREE
  386 +) ENGINE = InnoDB COMMENT = '位串表';
  387 +"""
  388 + # 明确失败,不把多位的位串当成布尔值
  389 + with self.assertRaises(ValueError):
  390 + convert(SQLServerConvertor(self.write_sql(sql)))
  391 +
  392 + def test_ruoyi_vue_pro(self):
  393 + convertor = SQLServerConvertor(os.path.join(MYSQL_DIR, "ruoyi-vue-pro.sql"))
  394 + source_bits, source_integers = [], []
  395 + for table_sql in convertor.original_table_script_list:
  396 + source_bits += re.findall(r"^\s*`(\w+)`\s+bit\b[^\n]*", table_sql, flags=re.MULTILINE)
  397 + source_integers += re.findall(r"^\s*`\w+`\s+(?:tinyint|smallint)\b[^\n]*", table_sql, flags=re.MULTILINE)
  398 + self.assertTrue(source_bits)
  399 + self.assertTrue(source_integers)
  400 + # 官方脚本只有 bit(1)、有符号的 tinyint / smallint
  401 + for table_sql in convertor.original_table_script_list:
  402 + self.assertFalse(re.findall(r"^\s*`\w+`\s+bit\((?!1\))", table_sql, flags=re.MULTILINE))
  403 + self.assertFalse([line for line in source_integers if "unsigned" in line.lower()])
  404 +
  405 + out, err = convert(convertor)
  406 + self.assertNotIn("无法正常解析", err)
  407 + self.assertNotIn("varchar(1)", out)
  408 + self.assertEqual(len(source_bits), len(re.findall(r"^ \w+ bit\b", out, flags=re.MULTILINE)))
  409 + self.assertEqual(len(source_integers), len(re.findall(r"^ \w+ smallint\b", out, flags=re.MULTILINE)))
  410 + self.assertFalse(re.findall(r"^ \w+ tinyint\b", out, flags=re.MULTILINE))
  411 +
  412 +
289 413 class ConvertorOfficialDumpTest(unittest.TestCase):
290 414  
291 415 def test_ruoyi_vue_pro(self):
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
... ... @@ -112,6 +112,11 @@
112 112 <artifactId>spring-boot-starter-test</artifactId>
113 113 <scope>test</scope>
114 114 </dependency>
  115 + <dependency>
  116 + <groupId>org.mockito</groupId>
  117 + <artifactId>mockito-inline</artifactId>
  118 + <scope>test</scope>
  119 + </dependency>
115 120 </dependencies>
116 121  
117 122 </project>
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/IntegerBooleanTypeHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.mybatis.core.type;
  2 +
  3 +import org.apache.ibatis.type.BaseTypeHandler;
  4 +import org.apache.ibatis.type.JdbcType;
  5 +
  6 +import java.sql.CallableStatement;
  7 +import java.sql.PreparedStatement;
  8 +import java.sql.ResultSet;
  9 +import java.sql.SQLException;
  10 +import java.sql.Types;
  11 +
  12 +/**
  13 + * Boolean 的类型转换器实现类,对应数据库的整数类型(tinyint、smallint、int2、number 等)
  14 + *
  15 + * 写入时 true 存 1、false 存 0;读取时非 0 为 true、0 为 false、NULL 为 null。
  16 + * 用于数据库列是整数、而 Java 字段是 Boolean 的场景,避免 PostgreSQL 等数据库不允许 boolean 与整数隐式转换。
  17 + *
  18 + * 使用时在字段上配置 {@code @TableField(typeHandler = IntegerBooleanTypeHandler.class)},
  19 + * 并在实体上开启 {@code @TableName(autoResultMap = true)},使查询结果也使用该转换器。
  20 + * 自定义 SQL 或 Wrapper 的独立参数需显式指定此转换器。
  21 + *
  22 + * 注意:仅按字段使用,
  23 + * 不要注册为全局的 Boolean 类型转换器,否则会影响真正的 boolean / bit 列。
  24 + *
  25 + * @author 芋道源码
  26 + */
  27 +public class IntegerBooleanTypeHandler extends BaseTypeHandler<Boolean> {
  28 +
  29 + @Override
  30 + public void setParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException {
  31 + if (parameter == null) {
  32 + // 未显式指定 jdbcType 时,按整数类型写入 NULL,避免 JdbcType.OTHER 在部分驱动上无法推断类型
  33 + ps.setNull(i, jdbcType == null || jdbcType == JdbcType.OTHER ? Types.INTEGER : jdbcType.TYPE_CODE);
  34 + return;
  35 + }
  36 + setNonNullParameter(ps, i, parameter, jdbcType);
  37 + }
  38 +
  39 + @Override
  40 + public void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException {
  41 + ps.setInt(i, parameter ? 1 : 0);
  42 + }
  43 +
  44 + @Override
  45 + public Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException {
  46 + int value = rs.getInt(columnName);
  47 + return rs.wasNull() ? null : value != 0;
  48 + }
  49 +
  50 + @Override
  51 + public Boolean getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  52 + int value = rs.getInt(columnIndex);
  53 + return rs.wasNull() ? null : value != 0;
  54 + }
  55 +
  56 + @Override
  57 + public Boolean getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  58 + int value = cs.getInt(columnIndex);
  59 + return cs.wasNull() ? null : value != 0;
  60 + }
  61 +
  62 +}
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/test/java/cn/iocoder/yudao/framework/mybatis/core/type/IntegerBooleanTypeHandlerTest.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.mybatis.core.type;
  2 +
  3 +import org.apache.ibatis.type.JdbcType;
  4 +import org.junit.jupiter.api.Test;
  5 +
  6 +import java.sql.CallableStatement;
  7 +import java.sql.PreparedStatement;
  8 +import java.sql.ResultSet;
  9 +import java.sql.SQLException;
  10 +import java.sql.Types;
  11 +
  12 +import static org.junit.jupiter.api.Assertions.assertEquals;
  13 +import static org.junit.jupiter.api.Assertions.assertNull;
  14 +import static org.mockito.ArgumentMatchers.anyBoolean;
  15 +import static org.mockito.ArgumentMatchers.anyInt;
  16 +import static org.mockito.Mockito.mock;
  17 +import static org.mockito.Mockito.never;
  18 +import static org.mockito.Mockito.verify;
  19 +import static org.mockito.Mockito.when;
  20 +
  21 +/**
  22 + * {@link IntegerBooleanTypeHandler} 的单元测试
  23 + *
  24 + * @author 芋道源码
  25 + */
  26 +public class IntegerBooleanTypeHandlerTest {
  27 +
  28 + private final IntegerBooleanTypeHandler handler = new IntegerBooleanTypeHandler();
  29 +
  30 + // ========== 写入 ==========
  31 +
  32 + @Test
  33 + public void testSetParameter_true() throws SQLException {
  34 + PreparedStatement ps = mock(PreparedStatement.class);
  35 +
  36 + handler.setParameter(ps, 1, true, null);
  37 +
  38 + verify(ps).setInt(1, 1);
  39 + verify(ps, never()).setBoolean(anyInt(), anyBoolean());
  40 + }
  41 +
  42 + @Test
  43 + public void testSetParameter_false() throws SQLException {
  44 + PreparedStatement ps = mock(PreparedStatement.class);
  45 +
  46 + handler.setParameter(ps, 2, false, JdbcType.TINYINT);
  47 +
  48 + verify(ps).setInt(2, 0);
  49 + }
  50 +
  51 + @Test
  52 + public void testSetParameter_nullWithoutJdbcType() throws SQLException {
  53 + PreparedStatement ps = mock(PreparedStatement.class);
  54 +
  55 + // MyBatis 未指定 jdbcType 时,可能传入 null 或 jdbcTypeForNull 默认的 OTHER
  56 + handler.setParameter(ps, 1, null, null);
  57 + handler.setParameter(ps, 2, null, JdbcType.OTHER);
  58 +
  59 + verify(ps).setNull(1, Types.INTEGER);
  60 + verify(ps).setNull(2, Types.INTEGER);
  61 + }
  62 +
  63 + @Test
  64 + public void testSetParameter_nullWithJdbcType() throws SQLException {
  65 + PreparedStatement ps = mock(PreparedStatement.class);
  66 +
  67 + handler.setParameter(ps, 1, null, JdbcType.SMALLINT);
  68 +
  69 + verify(ps).setNull(1, Types.SMALLINT);
  70 + }
  71 +
  72 + // ========== 读取 ==========
  73 +
  74 + @Test
  75 + public void testGetResult_byColumnName() throws SQLException {
  76 + ResultSet rs = mock(ResultSet.class);
  77 + when(rs.getInt("used")).thenReturn(1, 0, 2, 0);
  78 + when(rs.wasNull()).thenReturn(false, false, false, true);
  79 +
  80 + assertEquals(Boolean.TRUE, handler.getResult(rs, "used"));
  81 + assertEquals(Boolean.FALSE, handler.getResult(rs, "used"));
  82 + assertEquals(Boolean.TRUE, handler.getResult(rs, "used")); // 非 0 均为 true
  83 + assertNull(handler.getResult(rs, "used")); // NULL
  84 + }
  85 +
  86 + @Test
  87 + public void testGetResult_byColumnIndex() throws SQLException {
  88 + ResultSet rs = mock(ResultSet.class);
  89 + when(rs.getInt(3)).thenReturn(1, 0, 0);
  90 + when(rs.wasNull()).thenReturn(false, false, true);
  91 +
  92 + assertEquals(Boolean.TRUE, handler.getResult(rs, 3));
  93 + assertEquals(Boolean.FALSE, handler.getResult(rs, 3));
  94 + assertNull(handler.getResult(rs, 3));
  95 + }
  96 +
  97 + @Test
  98 + public void testGetResult_callableStatement() throws SQLException {
  99 + CallableStatement cs = mock(CallableStatement.class);
  100 + when(cs.getInt(1)).thenReturn(1, 0, 0);
  101 + when(cs.wasNull()).thenReturn(false, false, true);
  102 +
  103 + assertEquals(Boolean.TRUE, handler.getResult(cs, 1));
  104 + assertEquals(Boolean.FALSE, handler.getResult(cs, 1));
  105 + assertNull(handler.getResult(cs, 1));
  106 + }
  107 +
  108 +}
... ...
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/salary/slip/HrmSalarySlipTemplateDO.java
1 1 package cn.iocoder.yudao.module.hrm.dal.dataobject.salary.slip;
2 2  
3 3 import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.config.HrmSalaryOptionDO;
4   -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
5 5 import cn.iocoder.yudao.module.hrm.enums.salary.slip.HrmSalarySlipTemplateOptionTypeEnum;
6 6 import com.baomidou.mybatisplus.annotation.KeySequence;
7 7 import com.baomidou.mybatisplus.annotation.TableField;
... ... @@ -20,6 +20,8 @@ import java.util.List;
20 20 /**
21 21 * HRM 工资条模板 DO
22 22 *
  23 + * 平台级默认模板保存在 {@link cn.iocoder.yudao.framework.tenant.core.util.TenantUtils#GLOBAL_TENANT_ID} 下,由所有租户只读共享
  24 + *
23 25 * @author 芋道源码
24 26 */
25 27 @TableName(value = "hrm_salary_slip_template", autoResultMap = true)
... ... @@ -30,7 +32,7 @@ import java.util.List;
30 32 @Builder
31 33 @NoArgsConstructor
32 34 @AllArgsConstructor
33   -public class HrmSalarySlipTemplateDO extends BaseDO {
  35 +public class HrmSalarySlipTemplateDO extends TenantBaseDO {
34 36  
35 37 /**
36 38 * 编号
... ...
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/salary/slip/HrmSalarySlipTemplateMapper.java
... ... @@ -26,7 +26,7 @@ public interface HrmSalarySlipTemplateMapper extends BaseMapperX&lt;HrmSalarySlipTe
26 26 */
27 27 default HrmSalarySlipTemplateDO selectGlobalDefaultTemplate() {
28 28 return selectFirstOne(new LambdaQueryWrapperX<HrmSalarySlipTemplateDO>()
29   - .apply("tenant_id = {0}", TenantUtils.GLOBAL_TENANT_ID)
  29 + .eq(HrmSalarySlipTemplateDO::getTenantId, TenantUtils.GLOBAL_TENANT_ID)
30 30 .eq(HrmSalarySlipTemplateDO::getDefaultStatus, true)
31 31 .orderByDesc(HrmSalarySlipTemplateDO::getId));
32 32 }
... ...
yudao-module-hrm/src/test/java/cn/iocoder/yudao/module/hrm/service/salary/slip/HrmSalarySlipTemplateServiceImplTest.java
... ... @@ -34,6 +34,7 @@ import java.util.Objects;
34 34 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
35 35 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
36 36 import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.SALARY_DATA_ILLEGAL;
  37 +import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.SALARY_SLIP_TEMPLATE_NOT_EXISTS;
37 38 import static org.junit.jupiter.api.Assertions.assertEquals;
38 39 import static org.junit.jupiter.api.Assertions.assertFalse;
39 40 import static org.junit.jupiter.api.Assertions.assertNotNull;
... ... @@ -51,6 +52,7 @@ import static org.mockito.Mockito.when;
51 52 public class HrmSalarySlipTemplateServiceImplTest extends BaseDbUnitTest {
52 53  
53 54 private static final Long TENANT_ID = 2L;
  55 + private static final Long OTHER_TENANT_ID = 3L;
54 56  
55 57 @TestConfiguration(proxyBeanMethods = false)
56 58 static class TenantTestConfiguration {
... ... @@ -108,6 +110,8 @@ public class HrmSalarySlipTemplateServiceImplTest extends BaseDbUnitTest {
108 110 // 断言
109 111 assertNotNull(templateId);
110 112 HrmSalarySlipTemplateDO template = salarySlipTemplateService.getSalarySlipTemplate(templateId);
  113 + // 新增时不传租户编号,由租户拦截器按当前租户填充
  114 + assertEquals(TENANT_ID, template.getTenantId());
111 115 assertEquals("研发工资条", template.getName());
112 116 assertFalse(template.getHideEmpty());
113 117 assertFalse(template.getDefaultStatus());
... ... @@ -173,6 +177,7 @@ public class HrmSalarySlipTemplateServiceImplTest extends BaseDbUnitTest {
173 177 HrmSalarySlipTemplateDO template = randomPojo(HrmSalarySlipTemplateDO.class, o -> {
174 178 o.setId(null).setName("默认工资条模板").setHideEmpty(false).setDefaultStatus(true);
175 179 o.setOptions(Collections.emptyList());
  180 + o.setTenantId(TENANT_ID);
176 181 });
177 182 salarySlipTemplateMapper.insert(template);
178 183  
... ... @@ -258,6 +263,7 @@ public class HrmSalarySlipTemplateServiceImplTest extends BaseDbUnitTest {
258 263 HrmSalarySlipTemplateDO defaultTemplate = randomPojo(HrmSalarySlipTemplateDO.class, o -> {
259 264 o.setId(null).setName("默认工资条模板").setHideEmpty(false).setDefaultStatus(true);
260 265 o.setOptions(Collections.emptyList());
  266 + o.setTenantId(TENANT_ID);
261 267 });
262 268 salarySlipTemplateMapper.insert(defaultTemplate);
263 269 when(salaryOptionService.getSalaryOptionList(false)).thenReturn(Arrays.asList(
... ... @@ -286,11 +292,13 @@ public class HrmSalarySlipTemplateServiceImplTest extends BaseDbUnitTest {
286 292 HrmSalarySlipTemplateDO globalDefaultTemplate = randomPojo(HrmSalarySlipTemplateDO.class, o -> {
287 293 o.setId(null).setName("平台默认工资条模板").setHideEmpty(false).setDefaultStatus(true);
288 294 o.setOptions(Collections.emptyList());
  295 + o.setTenantId(TenantUtils.GLOBAL_TENANT_ID);
289 296 });
290 297 TenantUtils.executeIgnore(() -> salarySlipTemplateMapper.insert(globalDefaultTemplate));
291 298 HrmSalarySlipTemplateDO tenantTemplate = randomPojo(HrmSalarySlipTemplateDO.class, o -> {
292 299 o.setId(null).setName("租户自定义工资条模板").setHideEmpty(false).setDefaultStatus(false);
293 300 o.setOptions(Collections.emptyList());
  301 + o.setTenantId(TENANT_ID);
294 302 });
295 303 salarySlipTemplateMapper.insert(tenantTemplate);
296 304 when(salaryOptionService.getSalaryOptionList(false)).thenReturn(Collections.emptyList());
... ... @@ -301,13 +309,73 @@ public class HrmSalarySlipTemplateServiceImplTest extends BaseDbUnitTest {
301 309  
302 310 // 断言:普通查询被租户隔离,但 Service 可只读回退平台默认模板
303 311 assertNull(salarySlipTemplateMapper.selectById(globalDefaultTemplate.getId()));
304   - assertEquals(globalDefaultTemplate.getId(),
305   - TenantUtils.executeIgnore(salarySlipTemplateMapper::selectGlobalDefaultTemplate).getId());
  312 + HrmSalarySlipTemplateDO dbGlobalDefaultTemplate =
  313 + TenantUtils.executeIgnore(salarySlipTemplateMapper::selectGlobalDefaultTemplate);
  314 + assertEquals(globalDefaultTemplate.getId(), dbGlobalDefaultTemplate.getId());
  315 + assertEquals(TenantUtils.GLOBAL_TENANT_ID, dbGlobalDefaultTemplate.getTenantId());
306 316 assertEquals(globalDefaultTemplate.getId(), salarySlipTemplateService
307 317 .getSalarySlipTemplate(globalDefaultTemplate.getId()).getId());
308 318 assertEquals(2, templates.size());
309 319 assertEquals(globalDefaultTemplate.getId(), templates.get(0).getId());
310 320 assertEquals(tenantTemplate.getId(), templates.get(1).getId());
  321 + assertEquals(TENANT_ID, templates.get(1).getTenantId());
  322 +
  323 + // 调用,并断言:平台默认模板只读,租户不能修改、删除
  324 + HrmSalarySlipTemplateSaveReqVO updateReqVO = randomPojo(HrmSalarySlipTemplateSaveReqVO.class, o -> {
  325 + o.setId(globalDefaultTemplate.getId());
  326 + o.setName("租户改写的默认模板");
  327 + o.setOptions(Collections.singletonList(createTemplateOption("基本工资", 10101, 1)));
  328 + });
  329 + assertServiceException(() -> salarySlipTemplateService.updateSalarySlipTemplate(updateReqVO),
  330 + SALARY_DATA_ILLEGAL);
  331 + assertServiceException(() -> salarySlipTemplateService.deleteSalarySlipTemplate(globalDefaultTemplate.getId()),
  332 + SALARY_DATA_ILLEGAL);
  333 + HrmSalarySlipTemplateDO dbTemplate = TenantUtils.executeIgnore(
  334 + () -> salarySlipTemplateMapper.selectById(globalDefaultTemplate.getId()));
  335 + assertEquals("平台默认工资条模板", dbTemplate.getName());
  336 + assertEquals(TenantUtils.GLOBAL_TENANT_ID, dbTemplate.getTenantId());
  337 + }
  338 +
  339 + @Test
  340 + public void testSalarySlipTemplate_otherTenantIsolated() {
  341 + // mock 数据:其它租户的自定义模板、默认模板,按其它租户的上下文新增
  342 + HrmSalarySlipTemplateDO otherTemplate = randomPojo(HrmSalarySlipTemplateDO.class, o -> {
  343 + o.setId(null).setName("其它租户工资条模板").setHideEmpty(false).setDefaultStatus(false);
  344 + o.setOptions(Collections.emptyList());
  345 + o.setTenantId(null);
  346 + });
  347 + HrmSalarySlipTemplateDO otherDefaultTemplate = randomPojo(HrmSalarySlipTemplateDO.class, o -> {
  348 + o.setId(null).setName("其它租户默认工资条模板").setHideEmpty(false).setDefaultStatus(true);
  349 + o.setOptions(Collections.emptyList());
  350 + o.setTenantId(null);
  351 + });
  352 + TenantUtils.execute(OTHER_TENANT_ID, () -> salarySlipTemplateMapper.insert(otherTemplate));
  353 + TenantUtils.execute(OTHER_TENANT_ID, () -> salarySlipTemplateMapper.insert(otherDefaultTemplate));
  354 + when(salaryOptionService.getSalaryOptionList(false)).thenReturn(Collections.emptyList());
  355 +
  356 + // 调用,并断言:当前租户读不到,也不会把其它租户的默认模板当作平台默认模板
  357 + assertNull(salarySlipTemplateMapper.selectById(otherTemplate.getId()));
  358 + assertNull(salarySlipTemplateService.getSalarySlipTemplate(otherTemplate.getId()));
  359 + assertNull(salarySlipTemplateService.getSalarySlipTemplate(otherDefaultTemplate.getId()));
  360 + assertNull(TenantUtils.executeIgnore(salarySlipTemplateMapper::selectGlobalDefaultTemplate));
  361 + assertTrue(salarySlipTemplateService.getSalarySlipTemplateList().isEmpty());
  362 +
  363 + // 调用,并断言:当前租户不能修改、删除
  364 + HrmSalarySlipTemplateSaveReqVO updateReqVO = randomPojo(HrmSalarySlipTemplateSaveReqVO.class, o -> {
  365 + o.setId(otherTemplate.getId());
  366 + o.setName("当前租户改写的模板");
  367 + o.setOptions(Collections.singletonList(createTemplateOption("基本工资", 10101, 1)));
  368 + });
  369 + assertServiceException(() -> salarySlipTemplateService.updateSalarySlipTemplate(updateReqVO),
  370 + SALARY_SLIP_TEMPLATE_NOT_EXISTS);
  371 + assertServiceException(() -> salarySlipTemplateService.deleteSalarySlipTemplate(otherTemplate.getId()),
  372 + SALARY_SLIP_TEMPLATE_NOT_EXISTS);
  373 +
  374 + // 断言:其它租户的数据不变
  375 + HrmSalarySlipTemplateDO dbTemplate = TenantUtils.executeIgnore(
  376 + () -> salarySlipTemplateMapper.selectById(otherTemplate.getId()));
  377 + assertEquals("其它租户工资条模板", dbTemplate.getName());
  378 + assertEquals(OTHER_TENANT_ID, dbTemplate.getTenantId());
311 379 }
312 380  
313 381 @Test
... ...
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/sms/SmsCodeDO.java
1 1 package cn.iocoder.yudao.module.system.dal.dataobject.sms;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.type.IntegerBooleanTypeHandler;
4 5 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
5 6 import com.baomidou.mybatisplus.annotation.KeySequence;
  7 +import com.baomidou.mybatisplus.annotation.TableField;
6 8 import com.baomidou.mybatisplus.annotation.TableName;
7 9 import lombok.*;
8 10  
... ... @@ -15,7 +17,7 @@ import java.time.LocalDateTime;
15 17 *
16 18 * @author 芋道源码
17 19 */
18   -@TableName("system_sms_code")
  20 +@TableName(value = "system_sms_code", autoResultMap = true)
19 21 @KeySequence("system_sms_code_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
20 22 @Data
21 23 @EqualsAndHashCode(callSuper = true)
... ... @@ -54,6 +56,7 @@ public class SmsCodeDO extends BaseDO {
54 56 /**
55 57 * 是否使用
56 58 */
  59 + @TableField(typeHandler = IntegerBooleanTypeHandler.class)
57 60 private Boolean used;
58 61 /**
59 62 * 使用时间
... ...
yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImplTest.java
... ... @@ -77,7 +77,7 @@ public class SmsCodeServiceImplTest extends BaseDbUnitTest {
77 77 public void sendSmsCode_tooFast() {
78 78 // mock 数据
79 79 SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
80   - o -> o.setMobile("15601691300").setTodayIndex(1));
  80 + o -> o.setMobile("15601691300").setTodayIndex(1).setUsed(false));
81 81 smsCodeMapper.insert(smsCodeDO);
82 82 // 准备参数
83 83 SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
... ... @@ -94,7 +94,7 @@ public class SmsCodeServiceImplTest extends BaseDbUnitTest {
94 94 public void sendSmsCode_exceedDay() {
95 95 // mock 数据
96 96 SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
97   - o -> o.setMobile("15601691300").setTodayIndex(10).setCreateTime(LocalDateTime.now()));
  97 + o -> o.setMobile("15601691300").setTodayIndex(10).setUsed(false).setCreateTime(LocalDateTime.now()));
98 98 smsCodeMapper.insert(smsCodeDO);
99 99 // 准备参数
100 100 SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
... ...
yudao-module-system/src/test/resources/sql/create_tables.sql
... ... @@ -321,7 +321,7 @@ CREATE TABLE IF NOT EXISTS &quot;system_sms_code&quot; (
321 321 "scene" bigint NOT NULL,
322 322 "create_ip" varchar NOT NULL,
323 323 "today_index" int NOT NULL,
324   - "used" bit NOT NULL DEFAULT FALSE,
  324 + "used" tinyint NOT NULL DEFAULT 0,
325 325 "used_time" timestamp DEFAULT NULL,
326 326 "used_ip" varchar NULL,
327 327 "creator" varchar(64) DEFAULT '',
... ...