From bb87d01644597b8d719a6040e760e6d657ca67c2 Mon Sep 17 00:00:00 2001 From: richjohnrambo Date: Mon, 7 Sep 2026 11:49:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E9=B8=BD=E8=BE=BE?= =?UTF-8?q?=E8=BE=BE=E5=90=8E=E5=8F=B0=E5=AE=89=E5=85=A8=E4=B8=8E=E5=AE=A1?= =?UTF-8?q?=E8=AE=A1=E6=94=B9=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/admin-adfahi-research/01-dashboard.json | 62 + .../01-dashboard.queried.json | 78 + .../02-user-management.json | 866 ++++++++++ .../02-user-management.queried.json | 1022 ++++++++++++ .../admin-adfahi-research/03-user-groups.json | 102 ++ .../03-user-groups.queried.json | 108 ++ .../04-group-management.json | 296 ++++ .../04-group-management.queried.json | 356 ++++ .../05-group-members.json | 113 ++ .../05-group-members.queried.json | 173 ++ .../06-invite-codes.json | 103 ++ .../06-invite-codes.queried.json | 162 ++ .../07-direct-messages.json | 171 ++ .../07-direct-messages.queried.json | 393 +++++ .../08-group-messages.json | 159 ++ .../08-group-messages.queried.json | 379 +++++ .../09-sensitive-words.json | 135 ++ .../09-sensitive-words.queried.json | 150 ++ docs/admin-adfahi-research/10-files.json | 288 ++++ .../10-files.queried.json | 348 ++++ docs/admin-adfahi-research/11-feedback.json | 141 ++ .../11-feedback.queried.json | 157 ++ .../12-operation-logs.json | 180 ++ .../12-operation-logs.queried.json | 218 +++ .../13-user-account-audit.json | 174 ++ .../13-user-account-audit.queried.json | 211 +++ .../14-group-event-audit.json | 172 ++ .../14-group-event-audit.queried.json | 210 +++ .../admin-adfahi-research/15-admin-login.json | 102 ++ .../15-admin-login.queried.json | 123 ++ docs/admin-adfahi-research/16-user-login.json | 202 +++ .../16-user-login.queried.json | 249 +++ .../17-ip-account-stats.json | 123 ++ .../17-ip-account-stats.queried.json | 134 ++ .../18-login-failures.json | 156 ++ .../18-login-failures.queried.json | 172 ++ .../19-private-domain-settings.json | 67 + .../19-private-domain-settings.queried.json | 75 + .../20-security-policy.json | 157 ++ .../20-security-policy.queried.json | 180 ++ .../Admin-Server改造文档.md | 409 +++++ .../IM-Server改造文档.md | 390 +++++ docs/admin-adfahi-research/api-samples.json | 70 + docs/admin-adfahi-research/index-RosMaKu2.js | 158 ++ .../screenshots-queried/00-menu-overview.png | Bin 0 -> 25933 bytes .../screenshots-queried/01-dashboard.png | Bin 0 -> 47921 bytes .../02-user-management.png | Bin 0 -> 59550 bytes .../screenshots-queried/03-user-groups.png | Bin 0 -> 39432 bytes .../04-group-management.png | Bin 0 -> 63285 bytes .../screenshots-queried/05-group-members.png | Bin 0 -> 39848 bytes .../screenshots-queried/06-invite-codes.png | Bin 0 -> 50835 bytes .../07-direct-messages.png | Bin 0 -> 59006 bytes .../screenshots-queried/08-group-messages.png | Bin 0 -> 56993 bytes .../09-sensitive-words.png | Bin 0 -> 39292 bytes .../screenshots-queried/10-files.png | Bin 0 -> 61982 bytes .../screenshots-queried/11-feedback.png | Bin 0 -> 38009 bytes .../screenshots-queried/12-operation-logs.png | Bin 0 -> 64091 bytes .../13-user-account-audit.png | Bin 0 -> 66648 bytes .../14-group-event-audit.png | Bin 0 -> 66270 bytes .../screenshots-queried/15-admin-login.png | Bin 0 -> 70675 bytes .../screenshots-queried/16-user-login.png | Bin 0 -> 65135 bytes .../17-ip-account-stats.png | Bin 0 -> 33201 bytes .../screenshots-queried/18-login-failures.png | Bin 0 -> 48931 bytes .../19-private-domain-settings.png | Bin 0 -> 48620 bytes .../20-security-policy.png | Bin 0 -> 64864 bytes .../screenshots/00-menu-overview.png | Bin 0 -> 25933 bytes .../screenshots/01-dashboard.png | Bin 0 -> 21651 bytes .../screenshots/02-user-management.png | Bin 0 -> 24712 bytes .../screenshots/03-user-groups.png | Bin 0 -> 17673 bytes .../screenshots/04-group-management.png | Bin 0 -> 26016 bytes .../screenshots/05-group-members.png | Bin 0 -> 16533 bytes .../screenshots/06-invite-codes.png | Bin 0 -> 19677 bytes .../screenshots/07-direct-messages.png | Bin 0 -> 17912 bytes .../screenshots/08-group-messages.png | Bin 0 -> 17394 bytes .../screenshots/09-sensitive-words.png | Bin 0 -> 16873 bytes .../screenshots/10-files.png | Bin 0 -> 25436 bytes .../screenshots/11-feedback.png | Bin 0 -> 16640 bytes .../screenshots/12-operation-logs.png | Bin 0 -> 26484 bytes .../screenshots/13-user-account-audit.png | Bin 0 -> 27512 bytes .../screenshots/14-group-event-audit.png | Bin 0 -> 27094 bytes .../screenshots/15-admin-login.png | Bin 0 -> 28333 bytes .../screenshots/16-user-login.png | Bin 0 -> 26971 bytes .../screenshots/17-ip-account-stats.png | Bin 0 -> 15546 bytes .../screenshots/18-login-failures.png | Bin 0 -> 21417 bytes .../19-private-domain-settings.png | Bin 0 -> 20325 bytes .../screenshots/20-security-policy.png | Bin 0 -> 25710 bytes .../sql/Admin-Server改造.sql | 350 ++++ .../sql/IM-Server改造.sql | 417 +++++ docs/admin-adfahi-research/需求文档.md | 1462 +++++++++++++++++ server/api/admin/imdashboard/im_dashboard.go | 25 + .../admin/imgroupmessage/im_group_message.go | 37 + .../imloginfailurelog/im_login_failure_log.go | 37 + .../imprivatemessage/im_private_message.go | 37 + .../imsecuritypolicy/im_security_policy.go | 59 + .../imsensitiveword/im_sensitive_word.go | 51 + .../im_user_login_history.go | 22 + .../imuserpolicygroup/im_user_policy_group.go | 57 + server/internal/consts/im_content_audit.go | 84 + server/internal/consts/im_kafka.go | 2 + server/internal/consts/im_policy.go | 118 ++ .../controller/admin/sys/im_dashboard.go | 31 + .../controller/admin/sys/im_group_message.go | 40 + .../admin/sys/im_login_failure_log.go | 39 + .../admin/sys/im_private_message.go | 40 + .../admin/sys/im_security_policy.go | 72 + .../controller/admin/sys/im_sensitive_word.go | 59 + .../admin/sys/im_user_login_history.go | 28 + .../admin/sys/im_user_policy_group.go | 66 + .../internal/dao/im_message_curfew_rules.go | 22 + server/internal/dao/im_security_ip_rules.go | 22 + server/internal/dao/im_security_policy.go | 22 + .../internal/dao/im_sensitive_word_groups.go | 22 + server/internal/dao/im_sensitive_words.go | 22 + .../dao/im_user_policy_group_members.go | 22 + server/internal/dao/im_user_policy_groups.go | 22 + .../dao/internal/im_message_curfew_rules.go | 123 ++ .../dao/internal/im_security_ip_rules.go | 109 ++ .../dao/internal/im_security_policy.go | 123 ++ .../dao/internal/im_sensitive_word_groups.go | 103 ++ .../dao/internal/im_sensitive_words.go | 115 ++ .../internal/dao/internal/im_tenant_config.go | 44 +- .../internal/im_user_policy_group_members.go | 105 ++ .../dao/internal/im_user_policy_groups.go | 111 ++ server/internal/library/casbin/casbin_test.go | 93 +- server/internal/library/network/tcp/client.go | 2 + server/internal/library/network/tcp/rpc.go | 8 +- .../library/network/tcp/tcp_example_test.go | 181 +- .../internal/library/storager/upload_local.go | 54 +- .../library/storager/upload_local_test.go | 75 +- .../logic/sys/im_admin_query_client.go | 2 +- server/internal/logic/sys/im_dashboard.go | 38 + server/internal/logic/sys/im_login_audit.go | 155 ++ server/internal/logic/sys/im_message_admin.go | 173 ++ .../internal/logic/sys/im_policy_support.go | 60 + .../internal/logic/sys/im_security_policy.go | 331 ++++ .../internal/logic/sys/im_sensitive_word.go | 266 +++ .../logic/sys/im_user_policy_group.go | 290 ++++ .../model/do/im_message_curfew_rules.go | 39 + .../internal/model/do/im_security_ip_rules.go | 32 + .../internal/model/do/im_security_policy.go | 39 + .../model/do/im_sensitive_word_groups.go | 28 + .../internal/model/do/im_sensitive_words.go | 35 + server/internal/model/do/im_tenant_config.go | 24 +- .../model/do/im_user_policy_group_members.go | 29 + .../model/do/im_user_policy_groups.go | 33 + .../model/entity/im_message_curfew_rules.go | 37 + .../model/entity/im_security_ip_rules.go | 30 + .../model/entity/im_security_policy.go | 37 + .../model/entity/im_sensitive_word_groups.go | 26 + .../model/entity/im_sensitive_words.go | 33 + .../internal/model/entity/im_tenant_config.go | 22 +- .../entity/im_user_policy_group_members.go | 27 + .../model/entity/im_user_policy_groups.go | 31 + .../model/input/sysin/im_dashboard.go | 44 + .../model/input/sysin/im_login_audit.go | 161 ++ .../model/input/sysin/im_message_admin.go | 147 ++ .../model/input/sysin/im_policy_test.go | 145 ++ .../model/input/sysin/im_security_policy.go | 324 ++++ .../model/input/sysin/im_sensitive_word.go | 190 +++ .../model/input/sysin/im_user_policy_group.go | 157 ++ .../internal/router/genrouter/im_dashboard.go | 5 + .../router/genrouter/im_group_message.go | 5 + .../router/genrouter/im_login_failure_log.go | 5 + .../router/genrouter/im_private_message.go | 5 + .../router/genrouter/im_security_policy.go | 5 + .../router/genrouter/im_sensitive_word.go | 5 + .../router/genrouter/im_user_login_history.go | 5 + .../router/genrouter/im_user_policy_group.go | 5 + server/internal/service/sys.go | 226 ++- .../data/generate/im_adfahi_batch2_menu.sql | 38 + .../data/generate/im_adfahi_policy_menu.sql | 52 + web/src/api/imDashboard/index.ts | 9 + web/src/api/imGroupMessage/index.ts | 17 + web/src/api/imLoginFailureLog/index.ts | 17 + web/src/api/imPrivateMessage/index.ts | 17 + web/src/api/imSecurityPolicy/index.ts | 18 + web/src/api/imSensitiveWord/index.ts | 16 + web/src/api/imUserLoginHistory/index.ts | 8 + web/src/api/imUserPolicyGroup/index.ts | 18 + web/src/views/imAdminQueryShared.ts | 13 + web/src/views/imDashboard/index.vue | 106 ++ web/src/views/imGroupMessage/index.vue | 4 + web/src/views/imLoginFailureLog/index.vue | 220 +++ web/src/views/imLoginFailureLog/model.ts | 92 ++ .../views/imMessageShared/MessageTable.vue | 232 +++ web/src/views/imMessageShared/model.ts | 131 ++ web/src/views/imPolicyShared.ts | 32 + web/src/views/imPrivateMessage/index.vue | 4 + web/src/views/imSecurityPolicy/index.vue | 568 +++++++ web/src/views/imSecurityPolicy/model.ts | 88 + web/src/views/imSensitiveWord/index.vue | 330 ++++ web/src/views/imSensitiveWord/model.ts | 110 ++ web/src/views/imUserLoginHistory/index.vue | 95 ++ web/src/views/imUserLoginHistory/model.ts | 109 ++ web/src/views/imUserPolicyGroup/index.vue | 364 ++++ web/src/views/imUserPolicyGroup/model.ts | 64 + 196 files changed, 19970 insertions(+), 280 deletions(-) create mode 100644 docs/admin-adfahi-research/01-dashboard.json create mode 100644 docs/admin-adfahi-research/01-dashboard.queried.json create mode 100644 docs/admin-adfahi-research/02-user-management.json create mode 100644 docs/admin-adfahi-research/02-user-management.queried.json create mode 100644 docs/admin-adfahi-research/03-user-groups.json create mode 100644 docs/admin-adfahi-research/03-user-groups.queried.json create mode 100644 docs/admin-adfahi-research/04-group-management.json create mode 100644 docs/admin-adfahi-research/04-group-management.queried.json create mode 100644 docs/admin-adfahi-research/05-group-members.json create mode 100644 docs/admin-adfahi-research/05-group-members.queried.json create mode 100644 docs/admin-adfahi-research/06-invite-codes.json create mode 100644 docs/admin-adfahi-research/06-invite-codes.queried.json create mode 100644 docs/admin-adfahi-research/07-direct-messages.json create mode 100644 docs/admin-adfahi-research/07-direct-messages.queried.json create mode 100644 docs/admin-adfahi-research/08-group-messages.json create mode 100644 docs/admin-adfahi-research/08-group-messages.queried.json create mode 100644 docs/admin-adfahi-research/09-sensitive-words.json create mode 100644 docs/admin-adfahi-research/09-sensitive-words.queried.json create mode 100644 docs/admin-adfahi-research/10-files.json create mode 100644 docs/admin-adfahi-research/10-files.queried.json create mode 100644 docs/admin-adfahi-research/11-feedback.json create mode 100644 docs/admin-adfahi-research/11-feedback.queried.json create mode 100644 docs/admin-adfahi-research/12-operation-logs.json create mode 100644 docs/admin-adfahi-research/12-operation-logs.queried.json create mode 100644 docs/admin-adfahi-research/13-user-account-audit.json create mode 100644 docs/admin-adfahi-research/13-user-account-audit.queried.json create mode 100644 docs/admin-adfahi-research/14-group-event-audit.json create mode 100644 docs/admin-adfahi-research/14-group-event-audit.queried.json create mode 100644 docs/admin-adfahi-research/15-admin-login.json create mode 100644 docs/admin-adfahi-research/15-admin-login.queried.json create mode 100644 docs/admin-adfahi-research/16-user-login.json create mode 100644 docs/admin-adfahi-research/16-user-login.queried.json create mode 100644 docs/admin-adfahi-research/17-ip-account-stats.json create mode 100644 docs/admin-adfahi-research/17-ip-account-stats.queried.json create mode 100644 docs/admin-adfahi-research/18-login-failures.json create mode 100644 docs/admin-adfahi-research/18-login-failures.queried.json create mode 100644 docs/admin-adfahi-research/19-private-domain-settings.json create mode 100644 docs/admin-adfahi-research/19-private-domain-settings.queried.json create mode 100644 docs/admin-adfahi-research/20-security-policy.json create mode 100644 docs/admin-adfahi-research/20-security-policy.queried.json create mode 100644 docs/admin-adfahi-research/Admin-Server改造文档.md create mode 100644 docs/admin-adfahi-research/IM-Server改造文档.md create mode 100644 docs/admin-adfahi-research/api-samples.json create mode 100644 docs/admin-adfahi-research/index-RosMaKu2.js create mode 100644 docs/admin-adfahi-research/screenshots-queried/00-menu-overview.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/01-dashboard.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/02-user-management.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/03-user-groups.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/04-group-management.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/05-group-members.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/06-invite-codes.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/07-direct-messages.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/08-group-messages.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/09-sensitive-words.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/10-files.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/11-feedback.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/12-operation-logs.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/13-user-account-audit.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/14-group-event-audit.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/15-admin-login.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/16-user-login.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/17-ip-account-stats.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/18-login-failures.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/19-private-domain-settings.png create mode 100644 docs/admin-adfahi-research/screenshots-queried/20-security-policy.png create mode 100644 docs/admin-adfahi-research/screenshots/00-menu-overview.png create mode 100644 docs/admin-adfahi-research/screenshots/01-dashboard.png create mode 100644 docs/admin-adfahi-research/screenshots/02-user-management.png create mode 100644 docs/admin-adfahi-research/screenshots/03-user-groups.png create mode 100644 docs/admin-adfahi-research/screenshots/04-group-management.png create mode 100644 docs/admin-adfahi-research/screenshots/05-group-members.png create mode 100644 docs/admin-adfahi-research/screenshots/06-invite-codes.png create mode 100644 docs/admin-adfahi-research/screenshots/07-direct-messages.png create mode 100644 docs/admin-adfahi-research/screenshots/08-group-messages.png create mode 100644 docs/admin-adfahi-research/screenshots/09-sensitive-words.png create mode 100644 docs/admin-adfahi-research/screenshots/10-files.png create mode 100644 docs/admin-adfahi-research/screenshots/11-feedback.png create mode 100644 docs/admin-adfahi-research/screenshots/12-operation-logs.png create mode 100644 docs/admin-adfahi-research/screenshots/13-user-account-audit.png create mode 100644 docs/admin-adfahi-research/screenshots/14-group-event-audit.png create mode 100644 docs/admin-adfahi-research/screenshots/15-admin-login.png create mode 100644 docs/admin-adfahi-research/screenshots/16-user-login.png create mode 100644 docs/admin-adfahi-research/screenshots/17-ip-account-stats.png create mode 100644 docs/admin-adfahi-research/screenshots/18-login-failures.png create mode 100644 docs/admin-adfahi-research/screenshots/19-private-domain-settings.png create mode 100644 docs/admin-adfahi-research/screenshots/20-security-policy.png create mode 100644 docs/admin-adfahi-research/sql/Admin-Server改造.sql create mode 100644 docs/admin-adfahi-research/sql/IM-Server改造.sql create mode 100644 docs/admin-adfahi-research/需求文档.md create mode 100644 server/api/admin/imdashboard/im_dashboard.go create mode 100644 server/api/admin/imgroupmessage/im_group_message.go create mode 100644 server/api/admin/imloginfailurelog/im_login_failure_log.go create mode 100644 server/api/admin/imprivatemessage/im_private_message.go create mode 100644 server/api/admin/imsecuritypolicy/im_security_policy.go create mode 100644 server/api/admin/imsensitiveword/im_sensitive_word.go create mode 100644 server/api/admin/imuserloginhistory/im_user_login_history.go create mode 100644 server/api/admin/imuserpolicygroup/im_user_policy_group.go create mode 100644 server/internal/consts/im_content_audit.go create mode 100644 server/internal/consts/im_policy.go create mode 100644 server/internal/controller/admin/sys/im_dashboard.go create mode 100644 server/internal/controller/admin/sys/im_group_message.go create mode 100644 server/internal/controller/admin/sys/im_login_failure_log.go create mode 100644 server/internal/controller/admin/sys/im_private_message.go create mode 100644 server/internal/controller/admin/sys/im_security_policy.go create mode 100644 server/internal/controller/admin/sys/im_sensitive_word.go create mode 100644 server/internal/controller/admin/sys/im_user_login_history.go create mode 100644 server/internal/controller/admin/sys/im_user_policy_group.go create mode 100644 server/internal/dao/im_message_curfew_rules.go create mode 100644 server/internal/dao/im_security_ip_rules.go create mode 100644 server/internal/dao/im_security_policy.go create mode 100644 server/internal/dao/im_sensitive_word_groups.go create mode 100644 server/internal/dao/im_sensitive_words.go create mode 100644 server/internal/dao/im_user_policy_group_members.go create mode 100644 server/internal/dao/im_user_policy_groups.go create mode 100644 server/internal/dao/internal/im_message_curfew_rules.go create mode 100644 server/internal/dao/internal/im_security_ip_rules.go create mode 100644 server/internal/dao/internal/im_security_policy.go create mode 100644 server/internal/dao/internal/im_sensitive_word_groups.go create mode 100644 server/internal/dao/internal/im_sensitive_words.go create mode 100644 server/internal/dao/internal/im_user_policy_group_members.go create mode 100644 server/internal/dao/internal/im_user_policy_groups.go create mode 100644 server/internal/logic/sys/im_dashboard.go create mode 100644 server/internal/logic/sys/im_login_audit.go create mode 100644 server/internal/logic/sys/im_message_admin.go create mode 100644 server/internal/logic/sys/im_policy_support.go create mode 100644 server/internal/logic/sys/im_security_policy.go create mode 100644 server/internal/logic/sys/im_sensitive_word.go create mode 100644 server/internal/logic/sys/im_user_policy_group.go create mode 100644 server/internal/model/do/im_message_curfew_rules.go create mode 100644 server/internal/model/do/im_security_ip_rules.go create mode 100644 server/internal/model/do/im_security_policy.go create mode 100644 server/internal/model/do/im_sensitive_word_groups.go create mode 100644 server/internal/model/do/im_sensitive_words.go create mode 100644 server/internal/model/do/im_user_policy_group_members.go create mode 100644 server/internal/model/do/im_user_policy_groups.go create mode 100644 server/internal/model/entity/im_message_curfew_rules.go create mode 100644 server/internal/model/entity/im_security_ip_rules.go create mode 100644 server/internal/model/entity/im_security_policy.go create mode 100644 server/internal/model/entity/im_sensitive_word_groups.go create mode 100644 server/internal/model/entity/im_sensitive_words.go create mode 100644 server/internal/model/entity/im_user_policy_group_members.go create mode 100644 server/internal/model/entity/im_user_policy_groups.go create mode 100644 server/internal/model/input/sysin/im_dashboard.go create mode 100644 server/internal/model/input/sysin/im_login_audit.go create mode 100644 server/internal/model/input/sysin/im_message_admin.go create mode 100644 server/internal/model/input/sysin/im_policy_test.go create mode 100644 server/internal/model/input/sysin/im_security_policy.go create mode 100644 server/internal/model/input/sysin/im_sensitive_word.go create mode 100644 server/internal/model/input/sysin/im_user_policy_group.go create mode 100644 server/internal/router/genrouter/im_dashboard.go create mode 100644 server/internal/router/genrouter/im_group_message.go create mode 100644 server/internal/router/genrouter/im_login_failure_log.go create mode 100644 server/internal/router/genrouter/im_private_message.go create mode 100644 server/internal/router/genrouter/im_security_policy.go create mode 100644 server/internal/router/genrouter/im_sensitive_word.go create mode 100644 server/internal/router/genrouter/im_user_login_history.go create mode 100644 server/internal/router/genrouter/im_user_policy_group.go create mode 100644 server/storage/data/generate/im_adfahi_batch2_menu.sql create mode 100644 server/storage/data/generate/im_adfahi_policy_menu.sql create mode 100644 web/src/api/imDashboard/index.ts create mode 100644 web/src/api/imGroupMessage/index.ts create mode 100644 web/src/api/imLoginFailureLog/index.ts create mode 100644 web/src/api/imPrivateMessage/index.ts create mode 100644 web/src/api/imSecurityPolicy/index.ts create mode 100644 web/src/api/imSensitiveWord/index.ts create mode 100644 web/src/api/imUserLoginHistory/index.ts create mode 100644 web/src/api/imUserPolicyGroup/index.ts create mode 100644 web/src/views/imAdminQueryShared.ts create mode 100644 web/src/views/imDashboard/index.vue create mode 100644 web/src/views/imGroupMessage/index.vue create mode 100644 web/src/views/imLoginFailureLog/index.vue create mode 100644 web/src/views/imLoginFailureLog/model.ts create mode 100644 web/src/views/imMessageShared/MessageTable.vue create mode 100644 web/src/views/imMessageShared/model.ts create mode 100644 web/src/views/imPolicyShared.ts create mode 100644 web/src/views/imPrivateMessage/index.vue create mode 100644 web/src/views/imSecurityPolicy/index.vue create mode 100644 web/src/views/imSecurityPolicy/model.ts create mode 100644 web/src/views/imSensitiveWord/index.vue create mode 100644 web/src/views/imSensitiveWord/model.ts create mode 100644 web/src/views/imUserLoginHistory/index.vue create mode 100644 web/src/views/imUserLoginHistory/model.ts create mode 100644 web/src/views/imUserPolicyGroup/index.vue create mode 100644 web/src/views/imUserPolicyGroup/model.ts diff --git a/docs/admin-adfahi-research/01-dashboard.json b/docs/admin-adfahi-research/01-dashboard.json new file mode 100644 index 0000000..56520b5 --- /dev/null +++ b/docs/admin-adfahi-research/01-dashboard.json @@ -0,0 +1,62 @@ +{ + "label": "数据概览", + "slug": "01-dashboard", + "route": "/dashboard", + "url": "https://admin.adfahi.cn/dashboard", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/01-dashboard.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n总用户数\n16\n活跃用户\n0\n总群组数\n6\n总会话数\n11\n总消息数\n220\n今日消息\n0\n用户增长趋势\n日期\t数量\n2026-08-28\t0\n2026-08-29\t0\n2026-08-30\t0\n2026-08-31\t0\n2026-09-01\t0\n2026-09-02\t0\n2026-09-03\t0\n消息增长趋势\n日期\t数量\n2026-08-28\t0\n2026-08-29\t0\n2026-08-30\t0\n2026-08-31\t0\n2026-09-01\t0\n2026-09-02\t0\n2026-09-03\t0", + "tables": [ + { + "headers": [ + "日期", + "数量" + ], + "idx": 0, + "rows": [ + [ + "2026-08-28", + "0" + ], + [ + "2026-08-29", + "0" + ], + [ + "2026-08-30", + "0" + ] + ] + }, + { + "headers": [ + "日期", + "数量" + ], + "idx": 1, + "rows": [ + [ + "2026-08-28", + "0" + ], + [ + "2026-08-29", + "0" + ], + [ + "2026-08-30", + "0" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/01-dashboard.queried.json b/docs/admin-adfahi-research/01-dashboard.queried.json new file mode 100644 index 0000000..fffd71a --- /dev/null +++ b/docs/admin-adfahi-research/01-dashboard.queried.json @@ -0,0 +1,78 @@ +{ + "label": "数据概览", + "slug": "01-dashboard", + "route": "/dashboard", + "url": "https://admin.adfahi.cn/dashboard", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/01-dashboard.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n总用户数\n16\n活跃用户\n0\n总群组数\n6\n总会话数\n11\n总消息数\n220\n今日消息\n0\n用户增长趋势\n日期\t数量\n2026-08-28\t0\n2026-08-29\t0\n2026-08-30\t0\n2026-08-31\t0\n2026-09-01\t0\n2026-09-02\t0\n2026-09-03\t0\n消息增长趋势\n日期\t数量\n2026-08-28\t0\n2026-08-29\t0\n2026-08-30\t0\n2026-08-31\t0\n2026-09-01\t0\n2026-09-02\t0\n2026-09-03\t0", + "tables": [ + { + "headers": [ + "日期", + "数量" + ], + "idx": 0, + "rows": [ + [ + "2026-08-28", + "0" + ], + [ + "2026-08-29", + "0" + ], + [ + "2026-08-30", + "0" + ], + [ + "2026-08-31", + "0" + ], + [ + "2026-09-01", + "0" + ] + ] + }, + { + "headers": [ + "日期", + "数量" + ], + "idx": 1, + "rows": [ + [ + "2026-08-28", + "0" + ], + [ + "2026-08-29", + "0" + ], + [ + "2026-08-30", + "0" + ], + [ + "2026-08-31", + "0" + ], + [ + "2026-09-01", + "0" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/02-user-management.json b/docs/admin-adfahi-research/02-user-management.json new file mode 100644 index 0000000..3f7f177 --- /dev/null +++ b/docs/admin-adfahi-research/02-user-management.json @@ -0,0 +1,866 @@ +{ + "label": "用户管理", + "slug": "02-user-management", + "route": "/users", + "url": "https://admin.adfahi.cn/users", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/02-user-management.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户管理\n编号\n用户分组\n全部\n状态\n全部\n关键词\n查 询\n重 置\n创建用户\n批量创建\n导入Excel\n下载模板\n编号\t头像\t用户名\t昵称\t手机号\t注册方式\t状态\t用户分组\t最近登录\t创建时间\t操作\n\n编号\n\t\n头像\n\t\n用户名\n\t\n昵称\n\t\n手机号\n\t\n注册方式\n\t\n状态\n\t\n用户分组\n\t\n最近登录\n\t\n创建时间\n\t\n操作\n\n16\t\n点击查看\n\thy73074162\tpoter001\t\t后台创建\t正常\t默认用户组\t2026-08-01 00:05:30\t2026-08-01 00:04:25\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n15\t\n点击查看\n\thy17716319\t往事随风\t\t后台创建\t正常\t默认用户组\t2026-08-01 21:16:15\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n14\t\n点击查看\n\thy34899108\t坚守的山羊\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n13\t\n点击查看\n\thy45257043\t沉稳的松鼠\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n12\t\n点击查看\n\thy69598195\t专注的白兔\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n11\t\n点击查看\n\thy20144467\t沉稳的黑猫\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n10\t\n点击查看\n\thy70299474\t坚韧的河马\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n9\t\n点击查看\n\thy23799134\t求真的猫头\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n8\t\n点击查看\n\thy18959373\t进取的北狐\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n7\t\n点击查看\n\thy80424632\t温润的乌鸦\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n6\t\n点击查看\n\thy98400466\t乐观的野马\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n5\t\n点击查看\n\thy99111080\tF\t13800001115\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:43:53\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n4\t\n点击查看\n\thy92120233\tF\t13800001114\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:43:37\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n3\t\n点击查看\n\thy69089908\tF\t13800001113\t后台创建\t正常\t默认用户组\t2026-07-31 23:26:17\t2026-07-31 22:43:12\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n2\t\n点击查看\n\thy91144536\t冯仁飞\t13800001112\t后台创建\t正常\t默认用户组\t2026-08-02 22:27:59\t2026-07-31 22:43:02\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n1\t\n点击查看\n\thy50703413\t冯宇昂\t13800001111\t后台创建\t正常\t默认用户组\t2026-07-31 23:37:42\t2026-07-31 22:42:45\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n1\n20 条/页", + "tables": [ + { + "headers": [ + "编号", + "头像", + "用户名", + "昵称", + "手机号", + "注册方式", + "状态", + "用户分组", + "最近登录", + "创建时间", + "操作", + "编号", + "头像", + "用户名", + "昵称", + "手机号", + "注册方式", + "状态", + "用户分组", + "最近登录", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "16", + "点击查看", + "hy73074162", + "poter001", + "后台创建", + "正常", + "默认用户组", + "2026-08-01 00:05:30", + "2026-08-01 00:04:25", + "详 情重置密码IP白名单调整分组封 禁强制下线强制注销" + ], + [ + "15", + "点击查看", + "hy17716319", + "往事随风", + "后台创建", + "正常", + "默认用户组", + "2026-08-01 21:16:15", + "2026-07-31 22:44:06", + "详 情重置密码IP白名单调整分组封 禁强制下线强制注销" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "用户编号", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "用户名/昵称/手机号", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "创建用户" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "批量创建" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "导入Excel" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载模板" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/02-user-management.queried.json b/docs/admin-adfahi-research/02-user-management.queried.json new file mode 100644 index 0000000..efdd673 --- /dev/null +++ b/docs/admin-adfahi-research/02-user-management.queried.json @@ -0,0 +1,1022 @@ +{ + "label": "用户管理", + "slug": "02-user-management", + "route": "/users", + "url": "https://admin.adfahi.cn/users", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/02-user-management.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户管理\n编号\n用户分组\n全部\n状态\n全部\n关键词\n查 询\n重 置\n创建用户\n批量创建\n导入Excel\n下载模板\n编号\t头像\t用户名\t昵称\t手机号\t注册方式\t状态\t用户分组\t最近登录\t创建时间\t操作\n\n编号\n\t\n头像\n\t\n用户名\n\t\n昵称\n\t\n手机号\n\t\n注册方式\n\t\n状态\n\t\n用户分组\n\t\n最近登录\n\t\n创建时间\n\t\n操作\n\n16\t\n点击查看\n\thy73074162\tpoter001\t\t后台创建\t正常\t默认用户组\t2026-08-01 00:05:30\t2026-08-01 00:04:25\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n15\t\n点击查看\n\thy17716319\t往事随风\t\t后台创建\t正常\t默认用户组\t2026-08-01 21:16:15\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n14\t\n点击查看\n\thy34899108\t坚守的山羊\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n13\t\n点击查看\n\thy45257043\t沉稳的松鼠\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n12\t\n点击查看\n\thy69598195\t专注的白兔\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n11\t\n点击查看\n\thy20144467\t沉稳的黑猫\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n10\t\n点击查看\n\thy70299474\t坚韧的河马\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n9\t\n点击查看\n\thy23799134\t求真的猫头\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n8\t\n点击查看\n\thy18959373\t进取的北狐\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n7\t\n点击查看\n\thy80424632\t温润的乌鸦\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n6\t\n点击查看\n\thy98400466\t乐观的野马\t\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:44:06\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n5\t\n点击查看\n\thy99111080\tF\t13800001115\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:43:53\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n4\t\n点击查看\n\thy92120233\tF\t13800001114\t后台创建\t正常\t默认用户组\t--\t2026-07-31 22:43:37\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n3\t\n点击查看\n\thy69089908\tF\t13800001113\t后台创建\t正常\t默认用户组\t2026-07-31 23:26:17\t2026-07-31 22:43:12\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n2\t\n点击查看\n\thy91144536\t冯仁飞\t13800001112\t后台创建\t正常\t默认用户组\t2026-08-02 22:27:59\t2026-07-31 22:43:02\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n\n1\t\n点击查看\n\thy50703413\t冯宇昂\t13800001111\t后台创建\t正常\t默认用户组\t2026-07-31 23:37:42\t2026-07-31 22:42:45\t\n详 情\n重置密码\nIP白名单\n调整分组\n封 禁\n强制下线\n强制注销\n1\n20 条/页", + "tables": [ + { + "headers": [ + "编号", + "头像", + "用户名", + "昵称", + "手机号", + "注册方式", + "状态", + "用户分组", + "最近登录", + "创建时间", + "操作", + "编号", + "头像", + "用户名", + "昵称", + "手机号", + "注册方式", + "状态", + "用户分组", + "最近登录", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "16", + "点击查看", + "hy73074162", + "poter001", + "后台创建", + "正常", + "默认用户组", + "2026-08-01 00:05:30", + "2026-08-01 00:04:25", + "详 情重置密码IP白名单调整分组封 禁强制下线强制注销" + ], + [ + "15", + "点击查看", + "hy17716319", + "往事随风", + "后台创建", + "正常", + "默认用户组", + "2026-08-01 21:16:15", + "2026-07-31 22:44:06", + "详 情重置密码IP白名单调整分组封 禁强制下线强制注销" + ], + [ + "14", + "点击查看", + "hy34899108", + "坚守的山羊", + "后台创建", + "正常", + "默认用户组", + "--", + "2026-07-31 22:44:06", + "详 情重置密码IP白名单调整分组封 禁强制下线强制注销" + ], + [ + "13", + "点击查看", + "hy45257043", + "沉稳的松鼠", + "后台创建", + "正常", + "默认用户组", + "--", + "2026-07-31 22:44:06", + "详 情重置密码IP白名单调整分组封 禁强制下线强制注销" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "用户编号", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "用户名/昵称/手机号", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "创建用户", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "批量创建", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "导入Excel", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载模板", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重置密码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "调整分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制下线", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "强制注销", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/03-user-groups.json b/docs/admin-adfahi-research/03-user-groups.json new file mode 100644 index 0000000..0a7e96a --- /dev/null +++ b/docs/admin-adfahi-research/03-user-groups.json @@ -0,0 +1,102 @@ +{ + "label": "用户分组", + "slug": "03-user-groups", + "route": "/user-policy-groups", + "url": "https://admin.adfahi.cn/user-policy-groups", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/03-user-groups.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户分组\n添加分组\nIP 白名单\n租户渠道 IP 白名单\nAPP:未配置\nWeb:未配置\n分组名称\t用户数\t允许加好友\t允许建群\t直接加好友\t好友上限\tAPP 登录\tWeb 登录\tIP 白名单\t状态\t权重\t操作\n\n分组名称\n\t\n用户数\n\t\n允许加好友\n\t\n允许建群\n\t\n直接加好友\n\t\n好友上限\n\t\nAPP 登录\n\t\nWeb 登录\n\t\nIP 白名单\n\t\n状态\n\t\n权重\n\t\n操作\n\n\n默认用户组\n默认\n\t16\t允许\t允许\t--\t不限\t允许\t允许\t未启用\t启用\t0\t\n编辑\n删除", + "tables": [ + { + "headers": [ + "分组名称", + "用户数", + "允许加好友", + "允许建群", + "直接加好友", + "好友上限", + "APP 登录", + "Web 登录", + "IP 白名单", + "状态", + "权重", + "操作", + "分组名称", + "用户数", + "允许加好友", + "允许建群", + "直接加好友", + "好友上限", + "APP 登录", + "Web 登录", + "IP 白名单", + "状态", + "权重", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "默认用户组默认", + "16", + "允许", + "允许", + "--", + "不限", + "允许", + "允许", + "未启用", + "启用", + "0", + "编辑删除" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "添加分组" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP 白名单" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "编辑" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "删除" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/03-user-groups.queried.json b/docs/admin-adfahi-research/03-user-groups.queried.json new file mode 100644 index 0000000..2021c51 --- /dev/null +++ b/docs/admin-adfahi-research/03-user-groups.queried.json @@ -0,0 +1,108 @@ +{ + "label": "用户分组", + "slug": "03-user-groups", + "route": "/user-policy-groups", + "url": "https://admin.adfahi.cn/user-policy-groups", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/03-user-groups.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户分组\n添加分组\nIP 白名单\n租户渠道 IP 白名单\nAPP:未配置\nWeb:未配置\n分组名称\t用户数\t允许加好友\t允许建群\t直接加好友\t好友上限\tAPP 登录\tWeb 登录\tIP 白名单\t状态\t权重\t操作\n\n分组名称\n\t\n用户数\n\t\n允许加好友\n\t\n允许建群\n\t\n直接加好友\n\t\n好友上限\n\t\nAPP 登录\n\t\nWeb 登录\n\t\nIP 白名单\n\t\n状态\n\t\n权重\n\t\n操作\n\n\n默认用户组\n默认\n\t16\t允许\t允许\t--\t不限\t允许\t允许\t未启用\t启用\t0\t\n编辑\n删除", + "tables": [ + { + "headers": [ + "分组名称", + "用户数", + "允许加好友", + "允许建群", + "直接加好友", + "好友上限", + "APP 登录", + "Web 登录", + "IP 白名单", + "状态", + "权重", + "操作", + "分组名称", + "用户数", + "允许加好友", + "允许建群", + "直接加好友", + "好友上限", + "APP 登录", + "Web 登录", + "IP 白名单", + "状态", + "权重", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "默认用户组默认", + "16", + "允许", + "允许", + "--", + "不限", + "允许", + "允许", + "未启用", + "启用", + "0", + "编辑删除" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "添加分组", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "IP 白名单", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "编辑", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "删除", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/04-group-management.json b/docs/admin-adfahi-research/04-group-management.json new file mode 100644 index 0000000..a1b6d44 --- /dev/null +++ b/docs/admin-adfahi-research/04-group-management.json @@ -0,0 +1,296 @@ +{ + "label": "群组管理", + "slug": "04-group-management", + "route": "/groups", + "url": "https://admin.adfahi.cn/groups", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/04-group-management.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n群组管理\n群号\n关键词\n状态\n全部\n查 询\n重 置\n群组编号\t群号\t群组名称\t成员数\t群主昵称\t群主用户名\t状态\t创建时间\t操作\n\n群组编号\n\t\n群号\n\t\n群组名称\n\t\n成员数\n\t\n群主昵称\n\t\n群主用户名\n\t\n状态\n\t\n创建时间\n\t\n操作\n\n6\t68127154\t\n冯\n\t1\tF\thy69089908\t正常\t2026-07-31 22:50:52\t\n详 情\n群文件\n封 禁\n解 散\n\n5\t62262588\t\n冯\n\t3\tF\thy69089908\t正常\t2026-07-31 22:50:38\t\n详 情\n群文件\n封 禁\n解 散\n\n4\t75874312\t\n346亿916\n\t1\t冯宇昂\thy50703413\t正常\t2026-07-31 22:47:57\t\n详 情\n群文件\n封 禁\n解 散\n\n3\t92851806\t\n64919\n\t1\t冯宇昂\thy50703413\t正常\t2026-07-31 22:47:49\t\n详 情\n群文件\n封 禁\n解 散\n\n2\t89233971\t\n冯氏家族\n\t3\t冯仁飞\thy91144536\t正常\t2026-07-31 22:46:59\t\n详 情\n群文件\n封 禁\n解 散\n\n1\t17776111\t\n冯氏家族\n\t3\t冯宇昂\thy50703413\t正常\t2026-07-31 22:45:28\t\n详 情\n群文件\n封 禁\n解 散\n1\n20 条/页", + "tables": [ + { + "headers": [ + "群组编号", + "群号", + "群组名称", + "成员数", + "群主昵称", + "群主用户名", + "状态", + "创建时间", + "操作", + "群组编号", + "群号", + "群组名称", + "成员数", + "群主昵称", + "群主用户名", + "状态", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "6", + "68127154", + "冯", + "1", + "F", + "hy69089908", + "正常", + "2026-07-31 22:50:52", + "详 情群文件封 禁解 散" + ], + [ + "5", + "62262588", + "冯", + "3", + "F", + "hy69089908", + "正常", + "2026-07-31 22:50:38", + "详 情群文件封 禁解 散" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "群号", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "群名称", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/04-group-management.queried.json b/docs/admin-adfahi-research/04-group-management.queried.json new file mode 100644 index 0000000..88cb933 --- /dev/null +++ b/docs/admin-adfahi-research/04-group-management.queried.json @@ -0,0 +1,356 @@ +{ + "label": "群组管理", + "slug": "04-group-management", + "route": "/groups", + "url": "https://admin.adfahi.cn/groups", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/04-group-management.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n群组管理\n群号\n关键词\n状态\n全部\n查 询\n重 置\n群组编号\t群号\t群组名称\t成员数\t群主昵称\t群主用户名\t状态\t创建时间\t操作\n\n群组编号\n\t\n群号\n\t\n群组名称\n\t\n成员数\n\t\n群主昵称\n\t\n群主用户名\n\t\n状态\n\t\n创建时间\n\t\n操作\n\n6\t68127154\t\n冯\n\t1\tF\thy69089908\t正常\t2026-07-31 22:50:52\t\n详 情\n群文件\n封 禁\n解 散\n\n5\t62262588\t\n冯\n\t3\tF\thy69089908\t正常\t2026-07-31 22:50:38\t\n详 情\n群文件\n封 禁\n解 散\n\n4\t75874312\t\n346亿916\n\t1\t冯宇昂\thy50703413\t正常\t2026-07-31 22:47:57\t\n详 情\n群文件\n封 禁\n解 散\n\n3\t92851806\t\n64919\n\t1\t冯宇昂\thy50703413\t正常\t2026-07-31 22:47:49\t\n详 情\n群文件\n封 禁\n解 散\n\n2\t89233971\t\n冯氏家族\n\t3\t冯仁飞\thy91144536\t正常\t2026-07-31 22:46:59\t\n详 情\n群文件\n封 禁\n解 散\n\n1\t17776111\t\n冯氏家族\n\t3\t冯宇昂\thy50703413\t正常\t2026-07-31 22:45:28\t\n详 情\n群文件\n封 禁\n解 散\n1\n20 条/页", + "tables": [ + { + "headers": [ + "群组编号", + "群号", + "群组名称", + "成员数", + "群主昵称", + "群主用户名", + "状态", + "创建时间", + "操作", + "群组编号", + "群号", + "群组名称", + "成员数", + "群主昵称", + "群主用户名", + "状态", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "6", + "68127154", + "冯", + "1", + "F", + "hy69089908", + "正常", + "2026-07-31 22:50:52", + "详 情群文件封 禁解 散" + ], + [ + "5", + "62262588", + "冯", + "3", + "F", + "hy69089908", + "正常", + "2026-07-31 22:50:38", + "详 情群文件封 禁解 散" + ], + [ + "4", + "75874312", + "346亿916", + "1", + "冯宇昂", + "hy50703413", + "正常", + "2026-07-31 22:47:57", + "详 情群文件封 禁解 散" + ], + [ + "3", + "92851806", + "64919", + "1", + "冯宇昂", + "hy50703413", + "正常", + "2026-07-31 22:47:49", + "详 情群文件封 禁解 散" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "群号", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "群名称", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详 情", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "群文件", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "封 禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解 散", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/05-group-members.json b/docs/admin-adfahi-research/05-group-members.json new file mode 100644 index 0000000..e5b22cb --- /dev/null +++ b/docs/admin-adfahi-research/05-group-members.json @@ -0,0 +1,113 @@ +{ + "label": "群成员管理", + "slug": "05-group-members", + "route": "/group-members", + "url": "https://admin.adfahi.cn/group-members", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/05-group-members.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n群成员管理\n群号\n角色\n全部\n关键词\n查 询\n重 置\n刷 新\n编号\t用户名\t昵称\t群昵称\t角色\t禁言状态\t加入时间\t操作\n\n编号\n\t\n用户名\n\t\n昵称\n\t\n群昵称\n\t\n角色\n\t\n禁言状态\n\t\n加入时间\n\t\n操作\n\n\n暂无数据", + "tables": [ + { + "headers": [ + "编号", + "用户名", + "昵称", + "群昵称", + "角色", + "禁言状态", + "加入时间", + "操作", + "编号", + "用户名", + "昵称", + "群昵称", + "角色", + "禁言状态", + "加入时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "暂无数据暂无数据" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "必填", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "用户名/昵称", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "刷 新" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/05-group-members.queried.json b/docs/admin-adfahi-research/05-group-members.queried.json new file mode 100644 index 0000000..d1d9ec3 --- /dev/null +++ b/docs/admin-adfahi-research/05-group-members.queried.json @@ -0,0 +1,173 @@ +{ + "label": "群成员管理", + "slug": "05-group-members", + "route": "/group-members", + "url": "https://admin.adfahi.cn/group-members", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/05-group-members.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n群成员管理\n群号\n角色\n全部\n关键词\n查 询\n重 置\n刷 新\n编号\t用户名\t昵称\t群昵称\t角色\t禁言状态\t加入时间\t操作\n\n编号\n\t\n用户名\n\t\n昵称\n\t\n群昵称\n\t\n角色\n\t\n禁言状态\n\t\n加入时间\n\t\n操作\n\n3\thy69089908\tF\t--\t群主\t正常\t2026-07-31 22:50:52\t\n禁 言\n踢 出\n1\n20 条/页", + "tables": [ + { + "headers": [ + "编号", + "用户名", + "昵称", + "群昵称", + "角色", + "禁言状态", + "加入时间", + "操作", + "编号", + "用户名", + "昵称", + "群昵称", + "角色", + "禁言状态", + "加入时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "3", + "hy69089908", + "F", + "--", + "群主", + "正常", + "2026-07-31 22:50:52", + "禁 言踢 出" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "必填", + "tag": "INPUT", + "text": "", + "value": "68127154" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "用户名/昵称", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "刷 新", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "禁 言", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "踢 出", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/06-invite-codes.json b/docs/admin-adfahi-research/06-invite-codes.json new file mode 100644 index 0000000..697f08c --- /dev/null +++ b/docs/admin-adfahi-research/06-invite-codes.json @@ -0,0 +1,103 @@ +{ + "label": "邀请码管理", + "slug": "06-invite-codes", + "route": "/invite-codes", + "url": "https://admin.adfahi.cn/invite-codes", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/06-invite-codes.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n邀请码管理\n状态\n全部\n邀请码\n查 询\n重 置\n生成邀请码\n每次生成 1 个邀请码,可多次使用。可指定企业与用户;勾选「不限制时间」则永久有效;开启「自动加好友」后,使用该码注册的用户将直接成为指定用户的好友。点击「查看」可查看使用该邀请码注册的用户列表。\n邀请码\t指定用户\t自动加好友\t使用人数\t创建人\t状态\t过期时间\t创建时间\t操作\n\n邀请码\n\t\n指定用户\n\t\n自动加好友\n\t\n使用人数\n\t\n创建人\n\t\n状态\n\t\n过期时间\n\t\n创建时间\n\t\n操作\n\n\n暂无数据", + "tables": [ + { + "headers": [ + "邀请码", + "指定用户", + "自动加好友", + "使用人数", + "创建人", + "状态", + "过期时间", + "创建时间", + "操作", + "邀请码", + "指定用户", + "自动加好友", + "使用人数", + "创建人", + "状态", + "过期时间", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "暂无数据暂无数据" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "6 位数字", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "生成邀请码" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/06-invite-codes.queried.json b/docs/admin-adfahi-research/06-invite-codes.queried.json new file mode 100644 index 0000000..21788ec --- /dev/null +++ b/docs/admin-adfahi-research/06-invite-codes.queried.json @@ -0,0 +1,162 @@ +{ + "label": "邀请码管理", + "slug": "06-invite-codes", + "route": "/invite-codes", + "url": "https://admin.adfahi.cn/invite-codes", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/06-invite-codes.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n用户管理\n用户分组\n群组管理\n群成员管理\n邀请码管理\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n邀请码管理\n状态\n全部\n邀请码\n查 询\n重 置\n生成邀请码\n每次生成 1 个邀请码,可多次使用。可指定企业与用户;勾选「不限制时间」则永久有效;开启「自动加好友」后,使用该码注册的用户将直接成为指定用户的好友。点击「查看」可查看使用该邀请码注册的用户列表。\n邀请码\t指定用户\t自动加好友\t使用人数\t创建人\t状态\t过期时间\t创建时间\t操作\n\n邀请码\n\t\n指定用户\n\t\n自动加好友\n\t\n使用人数\n\t\n创建人\n\t\n状态\n\t\n过期时间\n\t\n创建时间\n\t\n操作\n\n323441\t往事随风 (#2271)\t否\t0\t16\t启用\t2026-09-05 00:34:55\t2026-09-04 00:34:55\t\n查 看\n删 除\n1\n20 条/页", + "tables": [ + { + "headers": [ + "邀请码", + "指定用户", + "自动加好友", + "使用人数", + "创建人", + "状态", + "过期时间", + "创建时间", + "操作", + "邀请码", + "指定用户", + "自动加好友", + "使用人数", + "创建人", + "状态", + "过期时间", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "323441", + "往事随风 (#2271)", + "否", + "0", + "16", + "启用", + "2026-09-05 00:34:55", + "2026-09-04 00:34:55", + "查 看删 除" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "6 位数字", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "生成邀请码", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 看", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/07-direct-messages.json b/docs/admin-adfahi-research/07-direct-messages.json new file mode 100644 index 0000000..a102b6d --- /dev/null +++ b/docs/admin-adfahi-research/07-direct-messages.json @@ -0,0 +1,171 @@ +{ + "label": "单聊消息", + "slug": "07-direct-messages", + "route": "/private-messages", + "url": "https://admin.adfahi.cn/private-messages", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/07-direct-messages.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n单聊消息\n全部\n文本\n图片\n视频\n语音\n文件\n名片\n系统\n发送人用户名\n接收人用户名\n关键词\n开始时间\n结束时间\n查 询\n重 置\n刷 新\n发送人\t接收人\t类型\t内容\t状态\t发送时间\t操作\n\n发送人\n\t\n接收人\n\t\n类型\n\t\n内容\n\t\n状态\n\t\n发送时间\n\t\n操作\n\n\n暂无数据", + "tables": [ + { + "headers": [ + "发送人", + "接收人", + "类型", + "内容", + "状态", + "发送时间", + "操作", + "发送人", + "接收人", + "类型", + "内容", + "状态", + "发送时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "暂无数据暂无数据" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "关键字", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "开始时间", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "结束时间", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "刷 新" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/07-direct-messages.queried.json b/docs/admin-adfahi-research/07-direct-messages.queried.json new file mode 100644 index 0000000..0584cc9 --- /dev/null +++ b/docs/admin-adfahi-research/07-direct-messages.queried.json @@ -0,0 +1,393 @@ +{ + "label": "单聊消息", + "slug": "07-direct-messages", + "route": "/private-messages", + "url": "https://admin.adfahi.cn/private-messages", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/07-direct-messages.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n单聊消息\n全部\n文本\n图片\n视频\n语音\n文件\n名片\n系统\n发送人用户名\n接收人用户名\n关键词\n开始时间\n结束时间\n查 询\n重 置\n刷 新\n发送人\t接收人\t类型\t内容\t状态\t发送时间\t操作\n\n发送人\n\t\n接收人\n\t\n类型\n\t\n内容\n\t\n状态\n\t\n发送时间\n\t\n操作\n\n\nF\nhy69089908\n\t\n冯仁飞\nhy91144536\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:06:05\t\n删 除\n\n\nF\nhy69089908\n\t\n冯宇昂\nhy50703413\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:06:05\t\n删 除\n\n\nF\nhy69089908\n\t\n冯宇昂\nhy50703413\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:05:19\t\n删 除\n\n\nF\nhy69089908\n\t\n冯仁飞\nhy91144536\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:04:12\t\n删 除\n\n\nF\nhy69089908\n\t\n冯宇昂\nhy50703413\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:04:12\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n冯仁飞\nhy91144536\n\t系统\t\n语音通话 00:13\n\t正常\t2026-07-31 23:02:22\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n冯仁飞\nhy91144536\n\t系统\t\n语音通话 00:01\n\t正常\t2026-07-31 23:01:45\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\nF\nhy69089908\n\t系统\t\n语音通话 已取消\n\t正常\t2026-07-31 23:01:36\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\nF\nhy69089908\n\t系统\t\n语音通话 已拒绝\n\t正常\t2026-07-31 23:01:19\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t系统\t\n视频通话 已取消\n\t正常\t2026-07-31 23:00:20\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t系统\t\n视频通话 00:19\n\t正常\t2026-07-31 22:59:59\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t系统\t\n语音通话 00:07\n\t正常\t2026-07-31 22:59:32\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\nF\nhy69089908\n\t系统\t\n语音通话 已取消\n\t正常\t2026-07-31 22:59:05\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t系统\t\n语音通话 00:15\n\t正常\t2026-07-31 22:58:42\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t系统\t\n视频通话 00:07\n\t正常\t2026-07-31 22:58:20\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t系统\t\n视频通话 已取消\n\t正常\t2026-07-31 22:58:07\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\nF\nhy69089908\n\t文本\t\n红心\n\t正常\t2026-07-31 22:51:35\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t文本\t\n1\n\t正常\t2026-07-31 22:51:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\nF\nhy69089908\n\t文本\t\n你想让我\n\t正常\t2026-07-31 22:51:32\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t文本\t\n1\n\t正常\t2026-07-31 22:51:32\t\n删 除\n1\n2\n3\n4\n20 条/页", + "tables": [ + { + "headers": [ + "发送人", + "接收人", + "类型", + "内容", + "状态", + "发送时间", + "操作", + "发送人", + "接收人", + "类型", + "内容", + "状态", + "发送时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "Fhy69089908", + "冯仁飞hy91144536", + "文本", + "哈哈哈哈", + "正常", + "2026-07-31 23:06:05", + "删 除" + ], + [ + "Fhy69089908", + "冯宇昂hy50703413", + "文本", + "哈哈哈哈", + "正常", + "2026-07-31 23:06:05", + "删 除" + ], + [ + "Fhy69089908", + "冯宇昂hy50703413", + "文本", + "哈哈哈哈", + "正常", + "2026-07-31 23:05:19", + "删 除" + ], + [ + "Fhy69089908", + "冯仁飞hy91144536", + "文本", + "哈哈哈哈", + "正常", + "2026-07-31 23:04:12", + "删 除" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "关键字", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "开始时间", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "结束时间", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "刷 新", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/08-group-messages.json b/docs/admin-adfahi-research/08-group-messages.json new file mode 100644 index 0000000..b6ebb47 --- /dev/null +++ b/docs/admin-adfahi-research/08-group-messages.json @@ -0,0 +1,159 @@ +{ + "label": "群聊消息", + "slug": "08-group-messages", + "route": "/group-messages", + "url": "https://admin.adfahi.cn/group-messages", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/08-group-messages.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n群聊消息\n全部\n文本\n图片\n视频\n语音\n文件\n名片\n系统\n发送人用户名\n关键词\n开始时间\n结束时间\n查 询\n重 置\n刷 新\n发送人\t群名称\t类型\t内容\t状态\t发送时间\t操作\n\n发送人\n\t\n群名称\n\t\n类型\n\t\n内容\n\t\n状态\n\t\n发送时间\n\t\n操作\n\n\n暂无数据", + "tables": [ + { + "headers": [ + "发送人", + "群名称", + "类型", + "内容", + "状态", + "发送时间", + "操作", + "发送人", + "群名称", + "类型", + "内容", + "状态", + "发送时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "暂无数据暂无数据" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "关键字", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "开始时间", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "结束时间", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "刷 新" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/08-group-messages.queried.json b/docs/admin-adfahi-research/08-group-messages.queried.json new file mode 100644 index 0000000..81495f8 --- /dev/null +++ b/docs/admin-adfahi-research/08-group-messages.queried.json @@ -0,0 +1,379 @@ +{ + "label": "群聊消息", + "slug": "08-group-messages", + "route": "/group-messages", + "url": "https://admin.adfahi.cn/group-messages", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/08-group-messages.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n群聊消息\n全部\n文本\n图片\n视频\n语音\n文件\n名片\n系统\n发送人用户名\n关键词\n开始时间\n结束时间\n查 询\n重 置\n刷 新\n发送人\t群名称\t类型\t内容\t状态\t发送时间\t操作\n\n发送人\n\t\n群名称\n\t\n类型\n\t\n内容\n\t\n状态\n\t\n发送时间\n\t\n操作\n\n\nF\nhy69089908\n\t\n冯\n68127154\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:06:05\t\n删 除\n\n\nF\nhy69089908\n\t\n冯氏家族\n89233971\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:06:05\t\n删 除\n\n\nF\nhy69089908\n\t\n冯氏家族\n17776111\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:06:05\t\n删 除\n\n\nF\nhy69089908\n\t\n冯\n62262588\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:05:19\t\n删 除\n\n\nF\nhy69089908\n\t\n冯氏家族\n17776111\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:05:19\t\n删 除\n\n\nF\nhy69089908\n\t\n冯氏家族\n89233971\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:05:19\t\n删 除\n\n\nF\nhy69089908\n\t\n冯\n68127154\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:05:19\t\n删 除\n\n\nF\nhy69089908\n\t\n冯\n68127154\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:04:12\t\n删 除\n\n\nF\nhy69089908\n\t\n冯氏家族\n89233971\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:04:12\t\n删 除\n\n\nF\nhy69089908\n\t\n冯氏家族\n17776111\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:04:12\t\n删 除\n\n\nF\nhy69089908\n\t\n冯\n62262588\n\t文本\t\n哈哈哈哈\n\t正常\t2026-07-31 23:03:50\t\n删 除\n\n\nF\nhy69089908\n\t\n冯氏家族\n17776111\n\t文本\t\n😊😊😊😊\n\t正常\t2026-07-31 22:53:42\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\n冯氏家族\n17776111\n\t文本\t\nkddkkffjc\n\t正常\t2026-07-31 22:53:18\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\n冯氏家族\n17776111\n\t文本\t\nkdododdk\n\t正常\t2026-07-31 22:53:17\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\n冯氏家族\n17776111\n\t文本\t\nfkdkkddoso\n\t正常\t2026-07-31 22:53:16\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\n冯氏家族\n17776111\n\t文本\t\nfkkfkfkd\n\t正常\t2026-07-31 22:53:15\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\n冯氏家族\n17776111\n\t文本\t\nfkfkkdod\n\t正常\t2026-07-31 22:53:14\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n冯氏家族\n17776111\n\t文本\t\n敏敏\n\t正常\t2026-07-31 22:53:13\t\n删 除\n\n\n冯仁飞\nhy91144536\n\t\n冯氏家族\n17776111\n\t文本\t\nfkfkfkdo\n\t正常\t2026-07-31 22:53:13\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n冯氏家族\n17776111\n\t文本\t\n您提着\n\t正常\t2026-07-31 22:53:12\t\n删 除\n1\n2\n3\n4\n5\n•••\n8\n20 条/页", + "tables": [ + { + "headers": [ + "发送人", + "群名称", + "类型", + "内容", + "状态", + "发送时间", + "操作", + "发送人", + "群名称", + "类型", + "内容", + "状态", + "发送时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "Fhy69089908", + "冯68127154", + "文本", + "哈哈哈哈", + "正常", + "2026-07-31 23:06:05", + "删 除" + ], + [ + "Fhy69089908", + "冯氏家族89233971", + "文本", + "哈哈哈哈", + "正常", + "2026-07-31 23:06:05", + "删 除" + ], + [ + "Fhy69089908", + "冯氏家族17776111", + "文本", + "哈哈哈哈", + "正常", + "2026-07-31 23:06:05", + "删 除" + ], + [ + "Fhy69089908", + "冯62262588", + "文本", + "哈哈哈哈", + "正常", + "2026-07-31 23:05:19", + "删 除" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "关键字", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "开始时间", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "结束时间", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "刷 新", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/09-sensitive-words.json b/docs/admin-adfahi-research/09-sensitive-words.json new file mode 100644 index 0000000..e3fd372 --- /dev/null +++ b/docs/admin-adfahi-research/09-sensitive-words.json @@ -0,0 +1,135 @@ +{ + "label": "敏感词库", + "slug": "09-sensitive-words", + "route": "/sensitive-words", + "url": "https://admin.adfahi.cn/sensitive-words", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/09-sensitive-words.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n敏感词库\n状态\n全部\n等级\n全部\n关键词\n查 询\n重 置\n新增敏感词\n批量导入\n文件导入\n批量导出\nID\t敏感词\t等级\t替换词\t状态\t创建时间\t操作\n\nID\n\t\n敏感词\n\t\n等级\n\t\n替换词\n\t\n状态\n\t\n创建时间\n\t\n操作\n\n\n暂无数据", + "tables": [ + { + "headers": [ + "ID", + "敏感词", + "等级", + "替换词", + "状态", + "创建时间", + "操作", + "ID", + "敏感词", + "等级", + "替换词", + "状态", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "暂无数据暂无数据" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "敏感词", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "新增敏感词" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "批量导入" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "文件导入" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "批量导出" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/09-sensitive-words.queried.json b/docs/admin-adfahi-research/09-sensitive-words.queried.json new file mode 100644 index 0000000..948f0aa --- /dev/null +++ b/docs/admin-adfahi-research/09-sensitive-words.queried.json @@ -0,0 +1,150 @@ +{ + "label": "敏感词库", + "slug": "09-sensitive-words", + "route": "/sensitive-words", + "url": "https://admin.adfahi.cn/sensitive-words", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/09-sensitive-words.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n敏感词库\n状态\n全部\n等级\n全部\n关键词\n查 询\n重 置\n新增敏感词\n批量导入\n文件导入\n批量导出\nID\t敏感词\t等级\t替换词\t状态\t创建时间\t操作\n\nID\n\t\n敏感词\n\t\n等级\n\t\n替换词\n\t\n状态\n\t\n创建时间\n\t\n操作\n\n\n暂无数据", + "tables": [ + { + "headers": [ + "ID", + "敏感词", + "等级", + "替换词", + "状态", + "创建时间", + "操作", + "ID", + "敏感词", + "等级", + "替换词", + "状态", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "暂无数据暂无数据" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "敏感词", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "新增敏感词", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "批量导入", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "文件导入", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "批量导出", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/10-files.json b/docs/admin-adfahi-research/10-files.json new file mode 100644 index 0000000..ea145d7 --- /dev/null +++ b/docs/admin-adfahi-research/10-files.json @@ -0,0 +1,288 @@ +{ + "label": "文件管理", + "slug": "10-files", + "route": "/file-records", + "url": "https://admin.adfahi.cn/file-records", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/10-files.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n文件管理\n全部\n图片\n视频\n音频\n文档\n其他\n发送人用户名\n文件名\n开始时间\n结束时间\n查 询\n重 置\n刷 新\n发送人\t接收方\t类型\t内容\t文件名\t文件大小\tURL\t状态\t发送时间\t操作\n\n发送人\n\t\n接收方\n\t\n类型\n\t\n内容\n\t\n文件名\n\t\n文件大小\n\t\nURL\n\t\n状态\n\t\n发送时间\n\t\n操作\n\n\n冯宇昂\nhy50703413\n\t\nF\nhy69089908\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:48:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n冯氏家族\n17776111\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:48:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n64919\n92851806\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:48:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n346亿916\n75874312\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:48:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n冯仁飞\nhy91144536\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:46:46\t\n删 除\n1\n20 条/页", + "tables": [ + { + "headers": [ + "发送人", + "接收方", + "类型", + "内容", + "文件名", + "文件大小", + "URL", + "状态", + "发送时间", + "操作", + "发送人", + "接收方", + "类型", + "内容", + "文件名", + "文件大小", + "URL", + "状态", + "发送时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "冯宇昂hy50703413", + "Fhy69089908", + "图片", + "预览下载", + "--", + "--", + "https://gdd-chat-fls.oss-a...", + "正常", + "2026-07-31 22:48:33", + "删 除" + ], + [ + "冯宇昂hy50703413", + "冯氏家族17776111", + "图片", + "预览下载", + "--", + "--", + "https://gdd-chat-fls.oss-a...", + "正常", + "2026-07-31 22:48:33", + "删 除" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "搜索文件名", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "开始时间", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "结束时间", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "刷 新" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/10-files.queried.json b/docs/admin-adfahi-research/10-files.queried.json new file mode 100644 index 0000000..aed0453 --- /dev/null +++ b/docs/admin-adfahi-research/10-files.queried.json @@ -0,0 +1,348 @@ +{ + "label": "文件管理", + "slug": "10-files", + "route": "/file-records", + "url": "https://admin.adfahi.cn/file-records", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/10-files.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n文件管理\n全部\n图片\n视频\n音频\n文档\n其他\n发送人用户名\n文件名\n开始时间\n结束时间\n查 询\n重 置\n刷 新\n发送人\t接收方\t类型\t内容\t文件名\t文件大小\tURL\t状态\t发送时间\t操作\n\n发送人\n\t\n接收方\n\t\n类型\n\t\n内容\n\t\n文件名\n\t\n文件大小\n\t\nURL\n\t\n状态\n\t\n发送时间\n\t\n操作\n\n\n冯宇昂\nhy50703413\n\t\nF\nhy69089908\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:48:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n冯氏家族\n17776111\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:48:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n64919\n92851806\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:48:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n346亿916\n75874312\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:48:33\t\n删 除\n\n\n冯宇昂\nhy50703413\n\t\n冯仁飞\nhy91144536\n\t图片\t\n预览\n下载\n\t--\t--\thttps://gdd-chat-fls.oss-a...\n\t正常\t2026-07-31 22:46:46\t\n删 除\n1\n20 条/页", + "tables": [ + { + "headers": [ + "发送人", + "接收方", + "类型", + "内容", + "文件名", + "文件大小", + "URL", + "状态", + "发送时间", + "操作", + "发送人", + "接收方", + "类型", + "内容", + "文件名", + "文件大小", + "URL", + "状态", + "发送时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "冯宇昂hy50703413", + "Fhy69089908", + "图片", + "预览下载", + "--", + "--", + "https://gdd-chat-fls.oss-a...", + "正常", + "2026-07-31 22:48:33", + "删 除" + ], + [ + "冯宇昂hy50703413", + "冯氏家族17776111", + "图片", + "预览下载", + "--", + "--", + "https://gdd-chat-fls.oss-a...", + "正常", + "2026-07-31 22:48:33", + "删 除" + ], + [ + "冯宇昂hy50703413", + "6491992851806", + "图片", + "预览下载", + "--", + "--", + "https://gdd-chat-fls.oss-a...", + "正常", + "2026-07-31 22:48:33", + "删 除" + ], + [ + "冯宇昂hy50703413", + "346亿91675874312", + "图片", + "预览下载", + "--", + "--", + "https://gdd-chat-fls.oss-a...", + "正常", + "2026-07-31 22:48:33", + "删 除" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "搜索文件名", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "开始时间", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "结束时间", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "刷 新", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "下载", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "删 除", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/11-feedback.json b/docs/admin-adfahi-research/11-feedback.json new file mode 100644 index 0000000..3bda944 --- /dev/null +++ b/docs/admin-adfahi-research/11-feedback.json @@ -0,0 +1,141 @@ +{ + "label": "用户反馈", + "slug": "11-feedback", + "route": "/feedbacks", + "url": "https://admin.adfahi.cn/feedbacks", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/11-feedback.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户反馈\n用户ID\n状态\n全部\n优先级\n全部\n关键词\n查 询\n重 置\n批量处理\n导出 CSV\n\t用户\t优先级\t内容\t状态\t处理人\t创建时间\t操作\n\n\t\n用户\n\t\n优先级\n\t\n内容\n\t\n状态\n\t\n处理人\n\t\n创建时间\n\t\n操作\n\n\n暂无数据", + "tables": [ + { + "headers": [ + "用户", + "优先级", + "内容", + "状态", + "处理人", + "创建时间", + "操作", + "用户", + "优先级", + "内容", + "状态", + "处理人", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "暂无数据暂无数据" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "用户ID", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "内容/联系方式", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "批量处理" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "导出 CSV" + }, + { + "disabled": true, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/11-feedback.queried.json b/docs/admin-adfahi-research/11-feedback.queried.json new file mode 100644 index 0000000..cb3cc50 --- /dev/null +++ b/docs/admin-adfahi-research/11-feedback.queried.json @@ -0,0 +1,157 @@ +{ + "label": "用户反馈", + "slug": "11-feedback", + "route": "/feedbacks", + "url": "https://admin.adfahi.cn/feedbacks", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/11-feedback.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n单聊消息\n群聊消息\n敏感词库\n文件管理\n用户反馈\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户反馈\n用户ID\n状态\n全部\n优先级\n全部\n关键词\n查 询\n重 置\n批量处理\n导出 CSV\n\t用户\t优先级\t内容\t状态\t处理人\t创建时间\t操作\n\n\t\n用户\n\t\n优先级\n\t\n内容\n\t\n状态\n\t\n处理人\n\t\n创建时间\n\t\n操作\n\n\n暂无数据", + "tables": [ + { + "headers": [ + "用户", + "优先级", + "内容", + "状态", + "处理人", + "创建时间", + "操作", + "用户", + "优先级", + "内容", + "状态", + "处理人", + "创建时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "暂无数据暂无数据" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "用户ID", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "内容/联系方式", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查 询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "批量处理", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "导出 CSV", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + }, + { + "disabled": true, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "on" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/12-operation-logs.json b/docs/admin-adfahi-research/12-operation-logs.json new file mode 100644 index 0000000..3058b10 --- /dev/null +++ b/docs/admin-adfahi-research/12-operation-logs.json @@ -0,0 +1,180 @@ +{ + "label": "操作日志", + "slug": "12-operation-logs", + "route": "/audit-logs", + "url": "https://admin.adfahi.cn/audit-logs", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/12-operation-logs.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n操作日志\n动作\n全部\n目标类型\n全部\n目标用户\n目标群\n开始时间\n结束时间\n查询\n重 置\n导出 CSV\n管理员\t动作\t目标类型\t目标\t查询条件\tIP\t时间\n\n管理员\n\t\n动作\n\t\n目标类型\n\t\n目标\n\t\n查询条件\n\t\nIP\n\t\n时间\n\nheiyue\t创建用户\t用户\t\npoter001\nhy73074162\n\t\n--\n\t104.30.173.163\t2026-08-01 00:04:25\nheiyue\t重置密码\t用户\t\n往事随风\nhy17716319\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:23\nheiyue\t重置密码\t用户\t\n坚守的山羊\nhy34899108\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:19\nheiyue\t重置密码\t用户\t\n沉稳的松鼠\nhy45257043\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:16\nheiyue\t重置密码\t用户\t\n专注的白兔\nhy69598195\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:12\nheiyue\t重置密码\t用户\t\n沉稳的黑猫\nhy20144467\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:09\nheiyue\t重置密码\t用户\t\n坚韧的河马\nhy70299474\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:05\nheiyue\t重置密码\t用户\t\n求真的猫头\nhy23799134\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:00\nheiyue\t重置密码\t用户\t\n进取的北狐\nhy18959373\n\t\n--\n\t141.164.107.33\t2026-07-31 22:44:55\nheiyue\t重置密码\t用户\t\n温润的乌鸦\nhy80424632\n\t\n--\n\t141.164.107.33\t2026-07-31 22:44:51\nheiyue\t重置密码\t用户\t\n乐观的野马\nhy98400466\n\t\n--\n\t141.164.107.33\t2026-07-31 22:44:48\nheiyue\t批量创建用户\t用户\t--\t\n详情\n\t141.164.107.33\t2026-07-31 22:44:06\nheiyue\t创建用户\t用户\t\nF\nhy99111080\n\t\n--\n\t141.164.107.33\t2026-07-31 22:43:53\nheiyue\t创建用户\t用户\t\nF\nhy92120233\n\t\n--\n\t141.164.107.33\t2026-07-31 22:43:37\nheiyue\t创建用户\t用户\t\nF\nhy69089908\n\t\n--\n\t141.164.107.33\t2026-07-31 22:43:12\nheiyue\t创建用户\t用户\t\n冯仁飞\nhy91144536\n\t\n--\n\t141.164.107.33\t2026-07-31 22:43:02\nheiyue\t创建用户\t用户\t\n冯宇昂\nhy50703413\n\t\n--\n\t141.164.107.33\t2026-07-31 22:42:45\n1\n20 条/页", + "tables": [ + { + "headers": [ + "管理员", + "动作", + "目标类型", + "目标", + "查询条件", + "IP", + "时间", + "管理员", + "动作", + "目标类型", + "目标", + "查询条件", + "IP", + "时间" + ], + "idx": 0, + "rows": [ + [], + [ + "heiyue", + "创建用户", + "用户", + "poter001hy73074162", + "--", + "104.30.173.163", + "2026-08-01 00:04:25" + ], + [ + "heiyue", + "重置密码", + "用户", + "往事随风hy17716319", + "--", + "141.164.107.33", + "2026-07-31 22:45:23" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "用户名", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "群号", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "导出 CSV" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详情" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/12-operation-logs.queried.json b/docs/admin-adfahi-research/12-operation-logs.queried.json new file mode 100644 index 0000000..65388d3 --- /dev/null +++ b/docs/admin-adfahi-research/12-operation-logs.queried.json @@ -0,0 +1,218 @@ +{ + "label": "操作日志", + "slug": "12-operation-logs", + "route": "/audit-logs", + "url": "https://admin.adfahi.cn/audit-logs", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/12-operation-logs.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n操作日志\n动作\n全部\n目标类型\n全部\n目标用户\n目标群\n开始时间\n结束时间\n查询\n重 置\n导出 CSV\n管理员\t动作\t目标类型\t目标\t查询条件\tIP\t时间\n\n管理员\n\t\n动作\n\t\n目标类型\n\t\n目标\n\t\n查询条件\n\t\nIP\n\t\n时间\n\nheiyue\t创建用户\t用户\t\npoter001\nhy73074162\n\t\n--\n\t104.30.173.163\t2026-08-01 00:04:25\nheiyue\t重置密码\t用户\t\n往事随风\nhy17716319\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:23\nheiyue\t重置密码\t用户\t\n坚守的山羊\nhy34899108\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:19\nheiyue\t重置密码\t用户\t\n沉稳的松鼠\nhy45257043\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:16\nheiyue\t重置密码\t用户\t\n专注的白兔\nhy69598195\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:12\nheiyue\t重置密码\t用户\t\n沉稳的黑猫\nhy20144467\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:09\nheiyue\t重置密码\t用户\t\n坚韧的河马\nhy70299474\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:05\nheiyue\t重置密码\t用户\t\n求真的猫头\nhy23799134\n\t\n--\n\t141.164.107.33\t2026-07-31 22:45:00\nheiyue\t重置密码\t用户\t\n进取的北狐\nhy18959373\n\t\n--\n\t141.164.107.33\t2026-07-31 22:44:55\nheiyue\t重置密码\t用户\t\n温润的乌鸦\nhy80424632\n\t\n--\n\t141.164.107.33\t2026-07-31 22:44:51\nheiyue\t重置密码\t用户\t\n乐观的野马\nhy98400466\n\t\n--\n\t141.164.107.33\t2026-07-31 22:44:48\nheiyue\t批量创建用户\t用户\t--\t\n详情\n\t141.164.107.33\t2026-07-31 22:44:06\nheiyue\t创建用户\t用户\t\nF\nhy99111080\n\t\n--\n\t141.164.107.33\t2026-07-31 22:43:53\nheiyue\t创建用户\t用户\t\nF\nhy92120233\n\t\n--\n\t141.164.107.33\t2026-07-31 22:43:37\nheiyue\t创建用户\t用户\t\nF\nhy69089908\n\t\n--\n\t141.164.107.33\t2026-07-31 22:43:12\nheiyue\t创建用户\t用户\t\n冯仁飞\nhy91144536\n\t\n--\n\t141.164.107.33\t2026-07-31 22:43:02\nheiyue\t创建用户\t用户\t\n冯宇昂\nhy50703413\n\t\n--\n\t141.164.107.33\t2026-07-31 22:42:45\n1\n20 条/页", + "tables": [ + { + "headers": [ + "管理员", + "动作", + "目标类型", + "目标", + "查询条件", + "IP", + "时间", + "管理员", + "动作", + "目标类型", + "目标", + "查询条件", + "IP", + "时间" + ], + "idx": 0, + "rows": [ + [], + [ + "heiyue", + "创建用户", + "用户", + "poter001hy73074162", + "--", + "104.30.173.163", + "2026-08-01 00:04:25" + ], + [ + "heiyue", + "重置密码", + "用户", + "往事随风hy17716319", + "--", + "141.164.107.33", + "2026-07-31 22:45:23" + ], + [ + "heiyue", + "重置密码", + "用户", + "坚守的山羊hy34899108", + "--", + "141.164.107.33", + "2026-07-31 22:45:19" + ], + [ + "heiyue", + "重置密码", + "用户", + "沉稳的松鼠hy45257043", + "--", + "141.164.107.33", + "2026-07-31 22:45:16" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "用户名", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "群号", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "导出 CSV", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "详情", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/13-user-account-audit.json b/docs/admin-adfahi-research/13-user-account-audit.json new file mode 100644 index 0000000..a6d7fec --- /dev/null +++ b/docs/admin-adfahi-research/13-user-account-audit.json @@ -0,0 +1,174 @@ +{ + "label": "用户账号审计", + "slug": "13-user-account-audit", + "route": "/user-account-audit", + "url": "https://admin.adfahi.cn/user-account-audit", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/13-user-account-audit.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户账号审计\n用户编号\n用户名\n操作者\n操作\nIP\n时间\n查询\n重 置\n操作时间\t目标用户\t操作者\t操作类型\t变更摘要\tIP / 归属地\t设备/客户端\n\n操作时间\n\t\n目标用户\n\t\n操作者\n\t\n操作类型\n\t\n变更摘要\n\t\nIP / 归属地\n\t\n设备/客户端\n\n2026-08-01 00:04:25\t\nhy73074162\n编号:16\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n104.30.173.163\n美国 加利福尼亚州 罗斯维尔\n\tMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36\n2026-07-31 22:45:23\t\nhy17716319\n编号:15\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:19\t\nhy34899108\n编号:14\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:16\t\nhy45257043\n编号:13\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:12\t\nhy69598195\n编号:12\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:09\t\nhy20144467\n编号:11\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:05\t\nhy70299474\n编号:10\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:00\t\nhy23799134\n编号:9\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:44:55\t\nhy18959373\n编号:8\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:44:51\t\nhy80424632\n编号:7\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:44:48\t\nhy98400466\n编号:6\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:43:53\t\nhy99111080\n编号:5\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:43:37\t\nhy92120233\n编号:4\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:43:12\t\nhy69089908\n编号:3\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:43:02\t\nhy91144536\n编号:2\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:42:45\t\nhy50703413\n编号:1\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n共 16 条\n1\n20 条/页", + "tables": [ + { + "headers": [ + "操作时间", + "目标用户", + "操作者", + "操作类型", + "变更摘要", + "IP / 归属地", + "设备/客户端", + "操作时间", + "目标用户", + "操作者", + "操作类型", + "变更摘要", + "IP / 归属地", + "设备/客户端" + ], + "idx": 0, + "rows": [ + [], + [ + "2026-08-01 00:04:25", + "hy73074162编号:16", + "管理员heiyue", + "create_user", + "create_user", + "104.30.173.163美国 加利福尼亚州 罗斯维尔", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36" + ], + [ + "2026-07-31 22:45:23", + "hy17716319编号:15", + "管理员heiyue", + "管理员重置密码", + "管理员重置密码", + "141.164.107.33老挝 万象市 永珍", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "开始日期", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "结束日期", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/13-user-account-audit.queried.json b/docs/admin-adfahi-research/13-user-account-audit.queried.json new file mode 100644 index 0000000..abfc9ba --- /dev/null +++ b/docs/admin-adfahi-research/13-user-account-audit.queried.json @@ -0,0 +1,211 @@ +{ + "label": "用户账号审计", + "slug": "13-user-account-audit", + "route": "/user-account-audit", + "url": "https://admin.adfahi.cn/user-account-audit", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/13-user-account-audit.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户账号审计\n用户编号\n用户名\n操作者\n操作\nIP\n时间\n查询\n重 置\n操作时间\t目标用户\t操作者\t操作类型\t变更摘要\tIP / 归属地\t设备/客户端\n\n操作时间\n\t\n目标用户\n\t\n操作者\n\t\n操作类型\n\t\n变更摘要\n\t\nIP / 归属地\n\t\n设备/客户端\n\n2026-08-01 00:04:25\t\nhy73074162\n编号:16\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n104.30.173.163\n美国 加利福尼亚州 罗斯维尔\n\tMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36\n2026-07-31 22:45:23\t\nhy17716319\n编号:15\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:19\t\nhy34899108\n编号:14\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:16\t\nhy45257043\n编号:13\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:12\t\nhy69598195\n编号:12\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:09\t\nhy20144467\n编号:11\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:05\t\nhy70299474\n编号:10\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:45:00\t\nhy23799134\n编号:9\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:44:55\t\nhy18959373\n编号:8\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:44:51\t\nhy80424632\n编号:7\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:44:48\t\nhy98400466\n编号:6\n\t\n管理员\nheiyue\n\t管理员重置密码\t管理员重置密码\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:43:53\t\nhy99111080\n编号:5\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:43:37\t\nhy92120233\n编号:4\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:43:12\t\nhy69089908\n编号:3\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:43:02\t\nhy91144536\n编号:2\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n2026-07-31 22:42:45\t\nhy50703413\n编号:1\n\t\n管理员\nheiyue\n\tcreate_user\tcreate_user\t\n141.164.107.33\n老挝 万象市 永珍\n\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\n共 16 条\n1\n20 条/页", + "tables": [ + { + "headers": [ + "操作时间", + "目标用户", + "操作者", + "操作类型", + "变更摘要", + "IP / 归属地", + "设备/客户端", + "操作时间", + "目标用户", + "操作者", + "操作类型", + "变更摘要", + "IP / 归属地", + "设备/客户端" + ], + "idx": 0, + "rows": [ + [], + [ + "2026-08-01 00:04:25", + "hy73074162编号:16", + "管理员heiyue", + "create_user", + "create_user", + "104.30.173.163美国 加利福尼亚州 罗斯维尔", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36" + ], + [ + "2026-07-31 22:45:23", + "hy17716319编号:15", + "管理员heiyue", + "管理员重置密码", + "管理员重置密码", + "141.164.107.33老挝 万象市 永珍", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0" + ], + [ + "2026-07-31 22:45:19", + "hy34899108编号:14", + "管理员heiyue", + "管理员重置密码", + "管理员重置密码", + "141.164.107.33老挝 万象市 永珍", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0" + ], + [ + "2026-07-31 22:45:16", + "hy45257043编号:13", + "管理员heiyue", + "管理员重置密码", + "管理员重置密码", + "141.164.107.33老挝 万象市 永珍", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "开始日期", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "结束日期", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/14-group-event-audit.json b/docs/admin-adfahi-research/14-group-event-audit.json new file mode 100644 index 0000000..f93f17b --- /dev/null +++ b/docs/admin-adfahi-research/14-group-event-audit.json @@ -0,0 +1,172 @@ +{ + "label": "群事件审计", + "slug": "14-group-event-audit", + "route": "/group-events", + "url": "https://admin.adfahi.cn/group-events", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/14-group-event-audit.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n群事件审计\n群号\n操作人\n目标用户\n事件类型\n全部\n开始时间\n结束时间\n查询\n重 置\n群名称\t事件类型\t操作人\t目标用户\t可见范围\t旧值\t新值\t时间\n\n群名称\n\t\n事件类型\n\t\n操作人\n\t\n目标用户\n\t\n可见范围\n\t\n旧值\n\t\n新值\n\t\n时间\n\n\n冯\n62262588\n\t成员加入\t\nF\nhy69089908\n\t\n冯宇昂\nhy50703413\n\t全员可见\t--\t--\t2026-07-31 23:03:42\n\n冯\n62262588\n\t成员加入\t\nF\nhy69089908\n\t\n冯仁飞\nhy91144536\n\t全员可见\t--\t--\t2026-07-31 23:03:42\n\n冯\n68127154\n\t群创建\t\nF\nhy69089908\n\t--\t全员可见\t--\t--\t2026-07-31 22:50:52\n\n冯氏家族\n89233971\n\t成员加入\t\n冯仁飞\nhy91144536\n\t\n冯宇昂\nhy50703413\n\t全员可见\t--\t--\t2026-07-31 22:50:43\n\n冯氏家族\n89233971\n\t成员加入\t\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t全员可见\t--\t--\t2026-07-31 22:50:43\n\n冯\n62262588\n\t群创建\t\nF\nhy69089908\n\t--\t全员可见\t--\t--\t2026-07-31 22:50:38\n\n冯氏家族\n17776111\n\t成员加入\t\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t全员可见\t--\t--\t2026-07-31 22:50:34\n\n346亿916\n75874312\n\t群创建\t\n冯宇昂\nhy50703413\n\t--\t全员可见\t--\t--\t2026-07-31 22:47:57\n\n64919\n92851806\n\t群创建\t\n冯宇昂\nhy50703413\n\t--\t全员可见\t--\t--\t2026-07-31 22:47:50\n\n冯氏家族\n17776111\n\t成员加入\t\n冯宇昂\nhy50703413\n\t\n冯仁飞\nhy91144536\n\t全员可见\t--\t--\t2026-07-31 22:47:19\n\n冯氏家族\n89233971\n\t群创建\t\n冯仁飞\nhy91144536\n\t--\t全员可见\t--\t--\t2026-07-31 22:46:59\n\n冯氏家族\n17776111\n\t群创建\t\n冯宇昂\nhy50703413\n\t--\t全员可见\t--\t--\t2026-07-31 22:45:28\n1\n20 条/页", + "tables": [ + { + "headers": [ + "群名称", + "事件类型", + "操作人", + "目标用户", + "可见范围", + "旧值", + "新值", + "时间", + "群名称", + "事件类型", + "操作人", + "目标用户", + "可见范围", + "旧值", + "新值", + "时间" + ], + "idx": 0, + "rows": [ + [], + [ + "冯62262588", + "成员加入", + "Fhy69089908", + "冯宇昂hy50703413", + "全员可见", + "--", + "--", + "2026-07-31 23:03:42" + ], + [ + "冯62262588", + "成员加入", + "Fhy69089908", + "冯仁飞hy91144536", + "全员可见", + "--", + "--", + "2026-07-31 23:03:42" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "用户名", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "用户名", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/14-group-event-audit.queried.json b/docs/admin-adfahi-research/14-group-event-audit.queried.json new file mode 100644 index 0000000..84f4081 --- /dev/null +++ b/docs/admin-adfahi-research/14-group-event-audit.queried.json @@ -0,0 +1,210 @@ +{ + "label": "群事件审计", + "slug": "14-group-event-audit", + "route": "/group-events", + "url": "https://admin.adfahi.cn/group-events", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/14-group-event-audit.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n群事件审计\n群号\n操作人\n目标用户\n事件类型\n全部\n开始时间\n结束时间\n查询\n重 置\n群名称\t事件类型\t操作人\t目标用户\t可见范围\t旧值\t新值\t时间\n\n群名称\n\t\n事件类型\n\t\n操作人\n\t\n目标用户\n\t\n可见范围\n\t\n旧值\n\t\n新值\n\t\n时间\n\n\n冯\n62262588\n\t成员加入\t\nF\nhy69089908\n\t\n冯宇昂\nhy50703413\n\t全员可见\t--\t--\t2026-07-31 23:03:42\n\n冯\n62262588\n\t成员加入\t\nF\nhy69089908\n\t\n冯仁飞\nhy91144536\n\t全员可见\t--\t--\t2026-07-31 23:03:42\n\n冯\n68127154\n\t群创建\t\nF\nhy69089908\n\t--\t全员可见\t--\t--\t2026-07-31 22:50:52\n\n冯氏家族\n89233971\n\t成员加入\t\n冯仁飞\nhy91144536\n\t\n冯宇昂\nhy50703413\n\t全员可见\t--\t--\t2026-07-31 22:50:43\n\n冯氏家族\n89233971\n\t成员加入\t\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t全员可见\t--\t--\t2026-07-31 22:50:43\n\n冯\n62262588\n\t群创建\t\nF\nhy69089908\n\t--\t全员可见\t--\t--\t2026-07-31 22:50:38\n\n冯氏家族\n17776111\n\t成员加入\t\n冯仁飞\nhy91144536\n\t\nF\nhy69089908\n\t全员可见\t--\t--\t2026-07-31 22:50:34\n\n346亿916\n75874312\n\t群创建\t\n冯宇昂\nhy50703413\n\t--\t全员可见\t--\t--\t2026-07-31 22:47:57\n\n64919\n92851806\n\t群创建\t\n冯宇昂\nhy50703413\n\t--\t全员可见\t--\t--\t2026-07-31 22:47:50\n\n冯氏家族\n17776111\n\t成员加入\t\n冯宇昂\nhy50703413\n\t\n冯仁飞\nhy91144536\n\t全员可见\t--\t--\t2026-07-31 22:47:19\n\n冯氏家族\n89233971\n\t群创建\t\n冯仁飞\nhy91144536\n\t--\t全员可见\t--\t--\t2026-07-31 22:46:59\n\n冯氏家族\n17776111\n\t群创建\t\n冯宇昂\nhy50703413\n\t--\t全员可见\t--\t--\t2026-07-31 22:45:28\n1\n20 条/页", + "tables": [ + { + "headers": [ + "群名称", + "事件类型", + "操作人", + "目标用户", + "可见范围", + "旧值", + "新值", + "时间", + "群名称", + "事件类型", + "操作人", + "目标用户", + "可见范围", + "旧值", + "新值", + "时间" + ], + "idx": 0, + "rows": [ + [], + [ + "冯62262588", + "成员加入", + "Fhy69089908", + "冯宇昂hy50703413", + "全员可见", + "--", + "--", + "2026-07-31 23:03:42" + ], + [ + "冯62262588", + "成员加入", + "Fhy69089908", + "冯仁飞hy91144536", + "全员可见", + "--", + "--", + "2026-07-31 23:03:42" + ], + [ + "冯68127154", + "群创建", + "Fhy69089908", + "--", + "全员可见", + "--", + "--", + "2026-07-31 22:50:52" + ], + [ + "冯氏家族89233971", + "成员加入", + "冯仁飞hy91144536", + "冯宇昂hy50703413", + "全员可见", + "--", + "--", + "2026-07-31 22:50:43" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "用户名", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "用户名", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/15-admin-login.json b/docs/admin-adfahi-research/15-admin-login.json new file mode 100644 index 0000000..31b39ae --- /dev/null +++ b/docs/admin-adfahi-research/15-admin-login.json @@ -0,0 +1,102 @@ +{ + "label": "管理员登录", + "slug": "15-admin-login", + "route": "/admin-login-history", + "url": "https://admin.adfahi.cn/admin-login-history", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/15-admin-login.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n管理员登录历史\n开始时间\n结束时间\n查询\n用户名\t登录时间\tUser-Agent\tIP 地址\n\n用户名\n\t\n登录时间\n\t\nUser-Agent\n\t\nIP 地址\n\nheiyue\t2026-09-04 00:10:57\tMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36\t103.136.251.99\nheiyue\t2026-08-01 00:03:52\tMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36\t104.30.173.163\nheiyue\t2026-07-31 22:47:31\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36\t141.164.107.235\nheiyue\t2026-07-31 22:42:09\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\t141.164.107.33\nheiyue\t2026-07-31 21:32:28\tMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36\t104.30.173.163\nheiyue\t2026-07-31 00:45:59\tMozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1\t203.160.80.152\n1\n20 条/页", + "tables": [ + { + "headers": [ + "用户名", + "登录时间", + "User-Agent", + "IP 地址", + "用户名", + "登录时间", + "User-Agent", + "IP 地址" + ], + "idx": 0, + "rows": [ + [], + [ + "heiyue", + "2026-09-04 00:10:57", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", + "103.136.251.99" + ], + [ + "heiyue", + "2026-08-01 00:03:52", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36", + "104.30.173.163" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/15-admin-login.queried.json b/docs/admin-adfahi-research/15-admin-login.queried.json new file mode 100644 index 0000000..98278ed --- /dev/null +++ b/docs/admin-adfahi-research/15-admin-login.queried.json @@ -0,0 +1,123 @@ +{ + "label": "管理员登录", + "slug": "15-admin-login", + "route": "/admin-login-history", + "url": "https://admin.adfahi.cn/admin-login-history", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/15-admin-login.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n管理员登录历史\n开始时间\n结束时间\n查询\n用户名\t登录时间\tUser-Agent\tIP 地址\n\n用户名\n\t\n登录时间\n\t\nUser-Agent\n\t\nIP 地址\n\nheiyue\t2026-09-04 00:10:57\tMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36\t103.136.251.99\nheiyue\t2026-08-01 00:03:52\tMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36\t104.30.173.163\nheiyue\t2026-07-31 22:47:31\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36\t141.164.107.235\nheiyue\t2026-07-31 22:42:09\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\t141.164.107.33\nheiyue\t2026-07-31 21:32:28\tMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36\t104.30.173.163\nheiyue\t2026-07-31 00:45:59\tMozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1\t203.160.80.152\n1\n20 条/页", + "tables": [ + { + "headers": [ + "用户名", + "登录时间", + "User-Agent", + "IP 地址", + "用户名", + "登录时间", + "User-Agent", + "IP 地址" + ], + "idx": 0, + "rows": [ + [], + [ + "heiyue", + "2026-09-04 00:10:57", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", + "103.136.251.99" + ], + [ + "heiyue", + "2026-08-01 00:03:52", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36", + "104.30.173.163" + ], + [ + "heiyue", + "2026-07-31 22:47:31", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36", + "141.164.107.235" + ], + [ + "heiyue", + "2026-07-31 22:42:09", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0", + "141.164.107.33" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/16-user-login.json b/docs/admin-adfahi-research/16-user-login.json new file mode 100644 index 0000000..ff4f4e7 --- /dev/null +++ b/docs/admin-adfahi-research/16-user-login.json @@ -0,0 +1,202 @@ +{ + "label": "用户登录", + "slug": "16-user-login", + "route": "/user-login-history", + "url": "https://admin.adfahi.cn/user-login-history", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/16-user-login.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户登录历史\n用户编号\n用户名\n开始时间\n结束时间\nIP\n查询\n重 置\n用户编号\t用户名\t当前状态\t登录时间\t设备类型\t设备型号\t系统版本\tApp 版本\tIP 地址\t归属地\t操作\n\n用户编号\n\t\n用户名\n\t\n当前状态\n\t\n登录时间\n\t\n设备类型\n\t\n设备型号\n\t\n系统版本\n\t\nApp 版本\n\t\nIP 地址\n\t\n归属地\n\t\n操作\n\n16\thy73074162\t正常\t2026-08-01 00:04:47\tweb\tChrome Browser\tMac OS X 10.15.7\t-\t104.30.173.163\t美国 加利福尼亚州 罗斯维尔\t\n快速封禁\n\n15\thy17716319\t正常\t2026-07-31 22:50:19\tandroid\tOPPO PCHM10\tAndroid 11\t1.1.2\t141.164.107.33\t老挝 万象市 永珍\t\n快速封禁\n\n3\thy69089908\t正常\t2026-07-31 22:47:10\tandroid\tOPPO PKW110\tAndroid 16\t1.1.2\t61.153.184.95\t浙江 绍兴\t\n快速封禁\n\n2\thy91144536\t正常\t2026-07-31 22:45:28\tandroid\tHONOR LOG-AN00\tAndroid 15\t1.1.2\t61.153.184.95\t浙江 绍兴\t\n快速封禁\n\n1\thy50703413\t正常\t2026-07-31 22:45:10\tandroid\tvivo V1809A\tAndroid 9\t1.1.2\t124.160.160.95\t浙江 杭州\t\n快速封禁\n\n1\thy50703413\t正常\t2026-07-31 22:44:44\tandroid\tHONOR LOG-AN00\tAndroid 15\t1.1.2\t61.153.184.95\t浙江 绍兴\t\n快速封禁\n\n1\thy50703413\t正常\t2026-07-31 22:43:38\tandroid\tvivo V1809A\tAndroid 9\t1.1.2\t124.160.160.95\t浙江 杭州\t\n快速封禁\n1\n20 条/页", + "tables": [ + { + "headers": [ + "用户编号", + "用户名", + "当前状态", + "登录时间", + "设备类型", + "设备型号", + "系统版本", + "App 版本", + "IP 地址", + "归属地", + "操作", + "用户编号", + "用户名", + "当前状态", + "登录时间", + "设备类型", + "设备型号", + "系统版本", + "App 版本", + "IP 地址", + "归属地", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "16", + "hy73074162", + "正常", + "2026-08-01 00:04:47", + "web", + "Chrome Browser", + "Mac OS X 10.15.7", + "-", + "104.30.173.163", + "美国 加利福尼亚州 罗斯维尔", + "快速封禁" + ], + [ + "15", + "hy17716319", + "正常", + "2026-07-31 22:50:19", + "android", + "OPPO PCHM10", + "Android 11", + "1.1.2", + "141.164.107.33", + "老挝 万象市 永珍", + "快速封禁" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "登录IP", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/16-user-login.queried.json b/docs/admin-adfahi-research/16-user-login.queried.json new file mode 100644 index 0000000..6b5eba4 --- /dev/null +++ b/docs/admin-adfahi-research/16-user-login.queried.json @@ -0,0 +1,249 @@ +{ + "label": "用户登录", + "slug": "16-user-login", + "route": "/user-login-history", + "url": "https://admin.adfahi.cn/user-login-history", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/16-user-login.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n用户登录历史\n用户编号\n用户名\n开始时间\n结束时间\nIP\n查询\n重 置\n用户编号\t用户名\t当前状态\t登录时间\t设备类型\t设备型号\t系统版本\tApp 版本\tIP 地址\t归属地\t操作\n\n用户编号\n\t\n用户名\n\t\n当前状态\n\t\n登录时间\n\t\n设备类型\n\t\n设备型号\n\t\n系统版本\n\t\nApp 版本\n\t\nIP 地址\n\t\n归属地\n\t\n操作\n\n16\thy73074162\t正常\t2026-08-01 00:04:47\tweb\tChrome Browser\tMac OS X 10.15.7\t-\t104.30.173.163\t美国 加利福尼亚州 罗斯维尔\t\n快速封禁\n\n15\thy17716319\t正常\t2026-07-31 22:50:19\tandroid\tOPPO PCHM10\tAndroid 11\t1.1.2\t141.164.107.33\t老挝 万象市 永珍\t\n快速封禁\n\n3\thy69089908\t正常\t2026-07-31 22:47:10\tandroid\tOPPO PKW110\tAndroid 16\t1.1.2\t61.153.184.95\t浙江 绍兴\t\n快速封禁\n\n2\thy91144536\t正常\t2026-07-31 22:45:28\tandroid\tHONOR LOG-AN00\tAndroid 15\t1.1.2\t61.153.184.95\t浙江 绍兴\t\n快速封禁\n\n1\thy50703413\t正常\t2026-07-31 22:45:10\tandroid\tvivo V1809A\tAndroid 9\t1.1.2\t124.160.160.95\t浙江 杭州\t\n快速封禁\n\n1\thy50703413\t正常\t2026-07-31 22:44:44\tandroid\tHONOR LOG-AN00\tAndroid 15\t1.1.2\t61.153.184.95\t浙江 绍兴\t\n快速封禁\n\n1\thy50703413\t正常\t2026-07-31 22:43:38\tandroid\tvivo V1809A\tAndroid 9\t1.1.2\t124.160.160.95\t浙江 杭州\t\n快速封禁\n1\n20 条/页", + "tables": [ + { + "headers": [ + "用户编号", + "用户名", + "当前状态", + "登录时间", + "设备类型", + "设备型号", + "系统版本", + "App 版本", + "IP 地址", + "归属地", + "操作", + "用户编号", + "用户名", + "当前状态", + "登录时间", + "设备类型", + "设备型号", + "系统版本", + "App 版本", + "IP 地址", + "归属地", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "16", + "hy73074162", + "正常", + "2026-08-01 00:04:47", + "web", + "Chrome Browser", + "Mac OS X 10.15.7", + "-", + "104.30.173.163", + "美国 加利福尼亚州 罗斯维尔", + "快速封禁" + ], + [ + "15", + "hy17716319", + "正常", + "2026-07-31 22:50:19", + "android", + "OPPO PCHM10", + "Android 11", + "1.1.2", + "141.164.107.33", + "老挝 万象市 永珍", + "快速封禁" + ], + [ + "3", + "hy69089908", + "正常", + "2026-07-31 22:47:10", + "android", + "OPPO PKW110", + "Android 16", + "1.1.2", + "61.153.184.95", + "浙江 绍兴", + "快速封禁" + ], + [ + "2", + "hy91144536", + "正常", + "2026-07-31 22:45:28", + "android", + "HONOR LOG-AN00", + "Android 15", + "1.1.2", + "61.153.184.95", + "浙江 绍兴", + "快速封禁" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "登录IP", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "快速封禁", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/17-ip-account-stats.json b/docs/admin-adfahi-research/17-ip-account-stats.json new file mode 100644 index 0000000..bb0846d --- /dev/null +++ b/docs/admin-adfahi-research/17-ip-account-stats.json @@ -0,0 +1,123 @@ +{ + "label": "IP 账号统计", + "slug": "17-ip-account-stats", + "route": "/ip-user-stats", + "url": "https://admin.adfahi.cn/ip-user-stats", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/17-ip-account-stats.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\nIP 账号统计\nIP\n查询\n重 置\nIP 地址\t归属地\t关联用户\t注册用户\t登录用户\t正常\t已封禁\t最近活动\t操作\n\nIP 地址\n\t\n归属地\n\t\n关联用户\n\t\n注册用户\n\t\n登录用户\n\t\n正常\n\t\n已封禁\n\t\n最近活动\n\t\n操作\n\n61.153.184.95\t浙江 绍兴\t\n3\n多账号\n\t0\t3\t3\t0\t2026-08-02 22:27:59\t\n用户列表\n共 1 个 IP\n1\n20 条/页", + "tables": [ + { + "headers": [ + "IP 地址", + "归属地", + "关联用户", + "注册用户", + "登录用户", + "正常", + "已封禁", + "最近活动", + "操作", + "IP 地址", + "归属地", + "关联用户", + "注册用户", + "登录用户", + "正常", + "已封禁", + "最近活动", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "61.153.184.95", + "浙江 绍兴", + "3多账号", + "0", + "3", + "3", + "0", + "2026-08-02 22:27:59", + "用户列表" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "IPv4 或 IPv6", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "用户列表" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/17-ip-account-stats.queried.json b/docs/admin-adfahi-research/17-ip-account-stats.queried.json new file mode 100644 index 0000000..95622be --- /dev/null +++ b/docs/admin-adfahi-research/17-ip-account-stats.queried.json @@ -0,0 +1,134 @@ +{ + "label": "IP 账号统计", + "slug": "17-ip-account-stats", + "route": "/ip-user-stats", + "url": "https://admin.adfahi.cn/ip-user-stats", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/17-ip-account-stats.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\nIP 账号统计\nIP\n查询\n重 置\nIP 地址\t归属地\t关联用户\t注册用户\t登录用户\t正常\t已封禁\t最近活动\t操作\n\nIP 地址\n\t\n归属地\n\t\n关联用户\n\t\n注册用户\n\t\n登录用户\n\t\n正常\n\t\n已封禁\n\t\n最近活动\n\t\n操作\n\n61.153.184.95\t浙江 绍兴\t\n3\n多账号\n\t0\t3\t3\t0\t2026-08-02 22:27:59\t\n用户列表\n共 1 个 IP\n1\n20 条/页", + "tables": [ + { + "headers": [ + "IP 地址", + "归属地", + "关联用户", + "注册用户", + "登录用户", + "正常", + "已封禁", + "最近活动", + "操作", + "IP 地址", + "归属地", + "关联用户", + "注册用户", + "登录用户", + "正常", + "已封禁", + "最近活动", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "61.153.184.95", + "浙江 绍兴", + "3多账号", + "0", + "3", + "3", + "0", + "2026-08-02 22:27:59", + "用户列表" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "IPv4 或 IPv6", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "用户列表", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/18-login-failures.json b/docs/admin-adfahi-research/18-login-failures.json new file mode 100644 index 0000000..95510b3 --- /dev/null +++ b/docs/admin-adfahi-research/18-login-failures.json @@ -0,0 +1,156 @@ +{ + "label": "登录失败日志", + "slug": "18-login-failures", + "route": "/login-failure-logs", + "url": "https://admin.adfahi.cn/login-failure-logs", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/18-login-failures.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n登录失败日志\n类型\n全部\n登录账号\nIP\n开始时间\n结束时间\n查询\n重 置\n类型\t登录账号\t失败原因\tIP 地址\tUser-Agent\t时间\t操作\n\n类型\n\t\n登录账号\n\t\n失败原因\n\t\nIP 地址\n\t\nUser-Agent\n\t\n时间\n\t\n操作\n\n用户\t13800001111\t密码错误\t106.119.66.106\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\t2026-08-01 01:31:20\t\n解锁\n\n用户\t13800001111\t密码错误\t61.153.184.95\tokhttp/4.12.0\t2026-07-31 22:44:36\t\n解锁\n1\n20 条/页", + "tables": [ + { + "headers": [ + "类型", + "登录账号", + "失败原因", + "IP 地址", + "User-Agent", + "时间", + "操作", + "类型", + "登录账号", + "失败原因", + "IP 地址", + "User-Agent", + "时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "用户", + "13800001111", + "密码错误", + "106.119.66.106", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0", + "2026-08-01 01:31:20", + "解锁" + ], + [ + "用户", + "13800001111", + "密码错误", + "61.153.184.95", + "okhttp/4.12.0", + "2026-07-31 22:44:36", + "解锁" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解锁" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解锁" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/18-login-failures.queried.json b/docs/admin-adfahi-research/18-login-failures.queried.json new file mode 100644 index 0000000..86001b8 --- /dev/null +++ b/docs/admin-adfahi-research/18-login-failures.queried.json @@ -0,0 +1,172 @@ +{ + "label": "登录失败日志", + "slug": "18-login-failures", + "route": "/login-failure-logs", + "url": "https://admin.adfahi.cn/login-failure-logs", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/18-login-failures.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n操作日志\n用户账号审计\n群事件审计\n管理员登录\n用户登录\nIP 账号统计\n登录失败日志\n系统设置\nheiyue\nheiyue\n账户操作\n数据概览\n登录失败日志\n类型\n全部\n登录账号\nIP\n开始时间\n结束时间\n查询\n重 置\n类型\t登录账号\t失败原因\tIP 地址\tUser-Agent\t时间\t操作\n\n类型\n\t\n登录账号\n\t\n失败原因\n\t\nIP 地址\n\t\nUser-Agent\n\t\n时间\n\t\n操作\n\n用户\t13800001111\t密码错误\t106.119.66.106\tMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0\t2026-08-01 01:31:20\t\n解锁\n\n用户\t13800001111\t密码错误\t61.153.184.95\tokhttp/4.12.0\t2026-07-31 22:44:36\t\n解锁\n1\n20 条/页", + "tables": [ + { + "headers": [ + "类型", + "登录账号", + "失败原因", + "IP 地址", + "User-Agent", + "时间", + "操作", + "类型", + "登录账号", + "失败原因", + "IP 地址", + "User-Agent", + "时间", + "操作" + ], + "idx": 0, + "rows": [ + [], + [ + "用户", + "13800001111", + "密码错误", + "106.119.66.106", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0", + "2026-08-01 01:31:20", + "解锁" + ], + [ + "用户", + "13800001111", + "密码错误", + "61.153.184.95", + "okhttp/4.12.0", + "2026-07-31 22:44:36", + "解锁" + ] + ] + } + ], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "全部", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "可选", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "查询", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "重 置", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解锁", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "解锁", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": true, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "DIV", + "text": "20 条/页", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/19-private-domain-settings.json b/docs/admin-adfahi-research/19-private-domain-settings.json new file mode 100644 index 0000000..533c309 --- /dev/null +++ b/docs/admin-adfahi-research/19-private-domain-settings.json @@ -0,0 +1,67 @@ +{ + "label": "私域设置", + "slug": "19-private-domain-settings", + "route": "/tenant-settings", + "url": "https://admin.adfahi.cn/tenant-settings", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/19-private-domain-settings.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\n私域设置\n安全策略\nheiyue\nheiyue\n账户操作\n数据概览\n私域设置\n私域设置 - 黑月测试\n消息字符上限\n范围 1~5000,仅允许调低\n图片大小上限(MB)\n范围 1~1000 MB\n文件大小上限(MB)\n范围 1~1000 MB,默认 50 MB\n最大撤回消息时间(分钟)\n群主/管理员撤回自己或他人消息的最长时限,范围 1~1440 分钟;普通用户撤回自己的消息固定为 2 分钟\n是否开启手机验证码\n开启\n关闭\n关闭后,注册仅支持邀请码,短信登录与忘记密码不可用\n保存设置", + "tables": [], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "开启关闭" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "保存设置" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/19-private-domain-settings.queried.json b/docs/admin-adfahi-research/19-private-domain-settings.queried.json new file mode 100644 index 0000000..52c50ae --- /dev/null +++ b/docs/admin-adfahi-research/19-private-domain-settings.queried.json @@ -0,0 +1,75 @@ +{ + "label": "私域设置", + "slug": "19-private-domain-settings", + "route": "/tenant-settings", + "url": "https://admin.adfahi.cn/tenant-settings", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/19-private-domain-settings.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\n私域设置\n安全策略\nheiyue\nheiyue\n账户操作\n数据概览\n私域设置\n私域设置 - 黑月测试\n消息字符上限\n范围 1~5000,仅允许调低\n图片大小上限(MB)\n范围 1~1000 MB\n文件大小上限(MB)\n范围 1~1000 MB,默认 50 MB\n最大撤回消息时间(分钟)\n群主/管理员撤回自己或他人消息的最长时限,范围 1~1440 分钟;普通用户撤回自己的消息固定为 2 分钟\n是否开启手机验证码\n开启\n关闭\n关闭后,注册仅支持邀请码,短信登录与忘记密码不可用\n保存设置", + "tables": [], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "5000" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "10" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "50" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "2" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "开启关闭", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "保存设置", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/20-security-policy.json b/docs/admin-adfahi-research/20-security-policy.json new file mode 100644 index 0000000..f175e84 --- /dev/null +++ b/docs/admin-adfahi-research/20-security-policy.json @@ -0,0 +1,157 @@ +{ + "label": "安全策略", + "slug": "20-security-policy", + "route": "/security-settings", + "url": "https://admin.adfahi.cn/security-settings", + "title": "鸽达达管理后台", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots/20-security-policy.png", + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\n私域设置\n安全策略\nheiyue\nheiyue\n账户操作\n数据概览\n安全策略\n用户安全\n验证码触发次数\n连续密码错误该次数后要求验证码(1~10)\n密码最小位数\n用户密码最少字符数(6~32)\n强制包含字母\n开启后密码必须包含英文字母\n注册登录管控\n用户注册功能\n关闭后用户端将隐藏注册入口\n修改密码功能\n关闭后用户无法修改密码,不影响后台重置\n用户登录功能\n关闭后用户无法登录,不影响已登录用户\nWeb 端多端登录\n开启后同一账号可在多个浏览器标签页同时登录\n聊天消息管控\n全局好友功能\n关闭后无法搜索和添加好友\n全局群消息\n关闭后所有群无法发送消息\n全局私聊消息\n关闭后所有私聊无法发送消息\n群聊发言间隔(秒)\n0 表示不限制;1~1000 表示同一群内两次发言的最小间隔\n群组功能管控\n群号搜索功能\n关闭后用户端隐藏群号和群搜索入口\n群创建功能\n关闭后任何人无法新建群聊\n群解散功能\n关闭后任何人无法解散群聊,不影响后台管理员\n群管理员功能\n关闭后任何人无法设置群管理员\n是否显示群人数\n关闭后用户端查看群资料时不显示群总人数\n其他功能开关\n允许用户注销账号\n关闭后用户端将隐藏注销账号按钮\nIP 访问控制\n注册 IP 黑名单\n留空表示不限制;每行一个 IPv4、IPv6 或 CIDR。命中后无法注册及获取注册短信验证码。\n登录 IP 黑名单\n留空表示不限制;命中后无法密码登录、短信登录及刷新 Token。与用户分组登录白名单独立,黑名单优先。\n高级功能\n消息已读状态\n开启后显示消息已读/未读标记\n保存设置", + "tables": [], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "203.0.113.10\n10.0.0.0/8", + "tag": "TEXTAREA", + "text": "" + }, + { + "disabled": null, + "placeholder": "198.51.100.0/24", + "tag": "TEXTAREA", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "保存设置" + } + ], + "resources": [] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/20-security-policy.queried.json b/docs/admin-adfahi-research/20-security-policy.queried.json new file mode 100644 index 0000000..ffd3870 --- /dev/null +++ b/docs/admin-adfahi-research/20-security-policy.queried.json @@ -0,0 +1,180 @@ +{ + "label": "安全策略", + "slug": "20-security-policy", + "route": "/security-settings", + "url": "https://admin.adfahi.cn/security-settings", + "screenshot": "/Users/youshunlai/go_workspace/im_manager/docs/admin-adfahi-research/screenshots-queried/20-security-policy.png", + "queried": true, + "text": "鸽达达管理后台\n数据概览\n用户与群组\n内容审核\n日志审计\n系统设置\n私域设置\n安全策略\nheiyue\nheiyue\n账户操作\n数据概览\n安全策略\n用户安全\n验证码触发次数\n连续密码错误该次数后要求验证码(1~10)\n密码最小位数\n用户密码最少字符数(6~32)\n强制包含字母\n开启后密码必须包含英文字母\n注册登录管控\n用户注册功能\n关闭后用户端将隐藏注册入口\n修改密码功能\n关闭后用户无法修改密码,不影响后台重置\n用户登录功能\n关闭后用户无法登录,不影响已登录用户\nWeb 端多端登录\n开启后同一账号可在多个浏览器标签页同时登录\n聊天消息管控\n全局好友功能\n关闭后无法搜索和添加好友\n全局群消息\n关闭后所有群无法发送消息\n全局私聊消息\n关闭后所有私聊无法发送消息\n群聊发言间隔(秒)\n0 表示不限制;1~1000 表示同一群内两次发言的最小间隔\n群组功能管控\n群号搜索功能\n关闭后用户端隐藏群号和群搜索入口\n群创建功能\n关闭后任何人无法新建群聊\n群解散功能\n关闭后任何人无法解散群聊,不影响后台管理员\n群管理员功能\n关闭后任何人无法设置群管理员\n是否显示群人数\n关闭后用户端查看群资料时不显示群总人数\n其他功能开关\n允许用户注销账号\n关闭后用户端将隐藏注销账号按钮\nIP 访问控制\n注册 IP 黑名单\n留空表示不限制;每行一个 IPv4、IPv6 或 CIDR。命中后无法注册及获取注册短信验证码。\n登录 IP 黑名单\n留空表示不限制;命中后无法密码登录、短信登录及刷新 Token。与用户分组登录白名单独立,黑名单优先。\n高级功能\n消息已读状态\n开启后显示消息已读/未读标记\n保存设置", + "tables": [], + "controls": [ + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "3" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "INPUT", + "text": "", + "value": "0" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "203.0.113.10\n10.0.0.0/8", + "tag": "TEXTAREA", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "198.51.100.0/24", + "tag": "TEXTAREA", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "", + "value": "" + }, + { + "disabled": null, + "placeholder": "", + "tag": "BUTTON", + "text": "保存设置", + "value": "" + } + ] +} \ No newline at end of file diff --git a/docs/admin-adfahi-research/Admin-Server改造文档.md b/docs/admin-adfahi-research/Admin-Server改造文档.md new file mode 100644 index 0000000..b189d22 --- /dev/null +++ b/docs/admin-adfahi-research/Admin-Server改造文档.md @@ -0,0 +1,409 @@ +# Admin Server 改造文档:对齐鸽达达管理后台 + +本文基于 `docs/admin-adfahi-research/需求文档.md`、当前 `im_manager` 代码、`im_server` 文档与本地 MySQL 数据核对结果编写。目标是在 HotGo Admin Server 中复刻鸽达达后台的 20 个页面,并保持当前系统“Admin 只直连 hotgo 控制库,IM Server 只直连租户业务库”的边界。 + +> 实施状态(2026-09-07):Admin 第二批已完成 `imDashboard`、`imPrivateMessage`、`imGroupMessage`、`imUserLoginHistory`、`imLoginFailureLog` 的 API、service、logic、controller、路由、Vue 页面、字典、导出和菜单权限。消息隐藏/删除、失败日志封禁用户使用 Kafka Admin Command;失败 IP 加黑复用安全策略。对应菜单 SQL 为 `server/storage/data/generate/im_adfahi_batch2_menu.sql`,已在本地 `hotgo` 执行。上述查询仍依赖 IM Server 本文约定的 internal-query;本地 `tinode` 尚无 `im_user_login_logs`、`im_login_failure_logs`,需在 IM Server 批次建表并接入日志采集后才会产生真实数据。 + +## 1. 改造边界 + +Admin Server 负责后台菜单、权限、页面、查询聚合、运营配置、Kafka 管理命令投递、命令结果展示与后台审计落库。业务 IM 数据不直接跨库读写,用户、群、消息、文件、反馈、登录等租户数据通过 IM Server 内部只读接口 `/internal/admin-query/tenants/{tenant_code}/...` 查询;用户封禁、群治理、消息处置、文件处置等写操作通过 Kafka Admin Command 下发。 + +当前本地库观察: + +| 数据库 | 现状 | +| --- | --- | +| `hotgo` | 当前有 66 张表,已存在 `im_admin_commands`、`im_admin_operation_audit`、`im_admin_outbox`、`im_registration_invite_codes`、`im_external_config`、`im_file_policy`,并已新增策略分组、敏感词、安全策略和宵禁控制表。 | +| `tinode` | 当前有 73 张表,已有 `im_users`、`im_topics`、`im_subscriptions`、`im_messages`、`im_group_messages`、`im_group_settings`、`im_fileuploads`、`im_feedback_submissions` 等 IM 业务表。 | +| 联调状态 | `hotgo.im_tenant` 已补默认租户映射(`id=1`、`code=default`);`tinode` 尚无用户登录历史和登录失败日志表,对应页面待 IM Server 批次补齐数据源。 | + +敏感配置说明:`hg_sys_config` 中已有声网、阿里云、OSS、短信等配置项。文档与页面只能展示脱敏值,后续应补充加密存储、轮换、审计与权限控制。 + +## 2. 当前 Admin 能力盘点 + +已有后台 API 模块: + +| 模块 | 主要能力 | 复用结论 | +| --- | --- | --- | +| `imUser` | 用户列表、详情、设备、重置密码、状态、封禁/解封、冻结/解冻、踢设备、全端登出、注销、删除 | 可作为“用户管理”的主体,补鸽达达字段、筛选项、批量操作与审计页联动。 | +| `imGroup` | 群列表、详情、成员、群治理、资料更新、解散、禁言、成员禁言/移除、入群申请、邀请、公告、文件、管理日志 | 可覆盖“群组管理”和“群成员管理”主体,需补独立菜单页与鸽达达状态/字段映射。 | +| `imInvite` | 邀请码列表、新增、批量新增、批量查看、撤销、批量撤销、导出 | 可覆盖“邀请码管理”,但邀请码格式与鸽达达需求存在差异。 | +| `imFile` | 文件列表、详情、隔离、删除、清理孤儿文件 | 可覆盖“文件管理”,需补预览/下载链接、审核枚举、内容风险字段。 | +| `imAuditLog` | 操作日志列表、详情、导出 | 可覆盖后台操作日志的一部分,需扩展为用户账号审计、群事件审计等专题页。 | +| `imKafkaCommand`、`imDeadLetter`、`imOutbox`、`imKafkaAudit` | Kafka 命令、死信、出站事件、审计事件 | 保留为运维治理菜单,不直接出现在鸽达达 20 个业务页中。 | +| `imRegistration`、`imExternalConfig`、`imFilePolicy`、`imFeedbackConfig`、`imMailboxConfig`、`imNotification`、`imAppRelease` | 注册、第三方、文件策略、反馈、邮箱、通知、版本配置 | 可组合成“私域设置”和“安全策略”,需要按鸽达达页面重组展示。 | + +已有菜单已包含 `IM管理`、`注册邀请码`、`用户列表`、`群组列表`、`文件治理`、`Kafka命令`、`Kafka死信`、`Kafka审计事件`、`租户管理` 等。缺少与鸽达达完全一致的“单聊消息、群聊消息、敏感词库、用户反馈、用户登录、IP账号统计、登录失败日志”等前台页面。 + +## 3. 页面级改造 + +### 3.1 数据概览 + +新增或改造 `imDashboard` 页面。顶部统计按需求文档展示总用户数、活跃用户、总群组数、总会话数、总消息数、今日消息;趋势表展示最近 7 天用户增长、消息增长。现有 IM Server 内部接口已有 `/internal/admin-query/tenants/{tenant}/dashboard/summary`,但仅返回 `dead_kafka`、`pending_business`、`pending_group`、`pending_realname`、`received_abuse`、`received_feedback`、`active_groups`、`suspended_users`,不足以还原鸽达达数据概览。 + +Admin 改造: + +| 项 | 方案 | +| --- | --- | +| API | 新增 `/imDashboard/overview`、`/imDashboard/trends`。 | +| 数据源 | 控制库租户信息来自 `im_tenant`;统计与趋势来自 IM internal query。 | +| 字段 | `totalUsers`、`activeUsers`、`totalGroups`、`totalConversations`、`totalMessages`、`todayMessages`、`date`、`userCount`、`messageCount`。 | +| 按钮 | 页面无写操作;支持租户切换、日期范围查询、刷新。 | +| 缺口 | IM Server 需补 dashboard 聚合项与趋势接口;Admin 需补租户为空时的默认租户兜底提示。 | + +### 3.2 用户管理 + +复用 `imUser`,页面按鸽达达字段重排。列表数据通过 IM internal `users` 查询,详情通过 `/users/{id}`,设备通过 `/users/{id}/devices`。当前 Admin 已有 `/imUser/list`、`/imUser/view`、`/imUser/devices`、`/imUser/ban`、`/imUser/unban`、`/imUser/freeze`、`/imUser/unfreeze`、`/imUser/deviceKick`、`/imUser/logoutAll`、`/imUser/accountCancel`、`/imUser/accountDelete`、`/imUser/resetPassword`。 + +字段说明: + +| 字段 | 来源 | 说明 | +| --- | --- | --- | +| `user_id` | `tinode.im_users.id` 编码后 | 用户唯一 ID,列表、详情、审计联动主键。 | +| `username` | `im_users.username` | 登录账号。 | +| `phone` | `im_users.phone` | 手机号,页面默认脱敏,导出需权限。 | +| `nickname` | `im_user_profiles.nickname` | 昵称,支持模糊查询。 | +| `public_account` | `im_user_profiles.public_account` | 对外账号/靓号。 | +| `state` | `im_users.state` | Tinode 用户状态。建议映射为正常、封禁、冻结、注销、删除。 | +| `last_seen` | `im_users.last_seen` | 最后在线/活跃时间。 | +| `created_at` | `im_users.created_at` | 注册时间。 | +| `credentials` | IM internal 聚合 | 认证方式摘要,不展示密钥。 | + +按钮功能: + +| 按钮 | 已有接口 | 功能 | +| --- | --- | --- | +| 查询 | `/imUser/list` | 按用户 ID、昵称、账号、手机号、状态、注册时间、最后活跃时间筛选。 | +| 重置 | 前端表单重置 | 清空筛选项并重新查询。 | +| 查看 | `/imUser/view` | 展示基础信息、资料、设备、最近审计事件。 | +| 封禁/解封 | `/imUser/ban`、`/imUser/unban` | Kafka 命令 `user.ban` / `user.unban`,需填写原因和过期时间。 | +| 冻结/解冻 | `/imUser/freeze`、`/imUser/unfreeze` | Kafka 命令 `user.freeze` / `user.unfreeze`。 | +| 踢设备 | `/imUser/deviceKick` | 指定设备下线。 | +| 全端登出 | `/imUser/logoutAll` | 下发 `user.logout_all`。 | +| 注销/删除 | `/imUser/accountCancel`、`/imUser/accountDelete` | 高危操作,二次确认并写审计。 | + +枚举说明:`state` 当前来自 Tinode 状态值,Admin 应新增统一字典 `im_user_state`,至少包含正常、封禁、冻结、注销、删除。封禁/冻结原因不应写死在前端,可复用“安全策略”中的处置原因配置。 + +### 3.3 用户分组 + +当前缺少等价模块,需要新增 `imUserPolicyGroup`。该页面不是组织部门,而是账号策略分组,用于控制注册、登录、私聊、建群、入群、发文件、发消息、IP 限制等策略。 + +Admin 改造: + +| 项 | 方案 | +| --- | --- | +| 后端模块 | `api/admin/imuserpolicygroup`、`controller/admin/sys/im_user_policy_group.go`、`logic/sys/im_user_policy_group.go`、`model/input/sysin/im_user_policy_group.go`。 | +| 控制表 | 新增 `im_user_policy_groups`、`im_user_policy_group_members`。 | +| API | `/imUserPolicyGroup/list`、`/view`、`/edit`、`/delete`、`/status`、`/memberList`、`/memberAdd`、`/memberRemove`。 | +| 同步 | 策略变更写 `im_admin_outbox`,发布 Kafka config event;IM Server 缓存策略并执行。 | +| 页面按钮 | 查询、新增、编辑、删除、启用/禁用、成员管理、导出。 | + +字段说明: + +| 字段 | 说明 | +| --- | --- | +| `group_code` | 分组编码,唯一,不可编辑。 | +| `group_name` | 分组名称。 | +| `priority` | 命中多个分组时的优先级,数字越大优先级越高。 | +| `status` | 启用、禁用。 | +| `policy_json` | 策略 JSON,包含消息、好友、群、文件、登录等开关与限额。 | +| `ip_whitelist`、`ip_blacklist` | IP 白名单/黑名单,支持 CIDR。 | +| `remark` | 备注。 | + +好友策略必须覆盖移动端所有加好友入口,不能只依赖前端隐藏。分组策略中至少包含 `allow_add_friend`、`direct_add_friend`、`max_friend_count`、`allow_view_profile_when_friend_disabled`、`allow_qrcode_add_friend`、`allow_group_member_profile`。当全局或分组禁止加好友时,从搜索、通讯录推荐、群成员列表、个人名片、二维码解析、邀请注册自动加好友、转发目标联系人等入口都必须由后端返回禁止或脱敏数据。 + +枚举说明:`status` 使用 `sys_normal_disable`;策略开关使用布尔值;策略动作建议统一枚举 `allow`、`deny`、`challenge`、`audit_only`。好友入口枚举建议 `search`、`profile_card`、`group_member`、`qrcode`、`invite_auto_add`、`recommendation`。 + +### 3.4 群组管理 + +复用 `imGroup`。列表通过 IM internal `groups` 查询,详情通过 `/groups/{topic}`,现有 Admin 已有群资料、治理、成员、申请、邀请、公告、文件、日志等接口。 + +字段说明: + +| 字段 | 来源 | 说明 | +| --- | --- | --- | +| `topic` | `im_topics.name` | 群 Topic,等价群号/群唯一标识。 | +| `group_name` | `im_group_settings.group_name` | 群名称。 | +| `owner_id` | `im_topics.owner` | 群主。 | +| `group_status` | `im_group_settings.group_status` | 群业务状态。 | +| `state` | `im_topics.state` | Tinode topic 状态。 | +| `business_member_count` | `im_group_settings.business_member_count` | 成员数。 | +| `join_approval` | `im_group_settings.join_approval` | 入群审批开关。 | +| `mute_all` | `im_group_settings.mute_all` | 全员禁言。 | +| `created_at`、`updated_at` | topic/settings | 创建与更新时间。 | + +按钮功能: + +| 按钮 | 已有接口 | 功能 | +| --- | --- | --- | +| 查询 | `/imGroup/list` | 按群号、群名、群主、状态、创建时间查询。 | +| 查看 | `/imGroup/view` | 群资料、成员、公告、邀请、文件、治理配置汇总。 | +| 编辑资料 | `/imGroup/profileUpdate` | Kafka `group.profile.update`。 | +| 治理设置 | `/imGroup/governanceUpdate` | Kafka `group.governance.update`,控制入群审批、全员禁言、成员上传文件、成员私聊、成员邀请。 | +| 解散 | `/imGroup/dissolve` | 高危操作,二次确认。 | +| 禁言/解禁言 | `/imGroup/mute`、`/imGroup/unmute` | 群级禁言。 | +| 成员/申请/邀请/公告/文件/日志 | 已有子接口 | 打开子面板或跳转专题页。 | + +枚举说明:新增 `im_group_status`,建议值 `active` 正常、`muted` 禁言、`suspended` 封停、`dissolved` 已解散。当前 IM 命令未看到明确 `group.ban`/`group.unban`,如鸽达达要求群封停,需要新增 Kafka 命令或通过治理状态统一处理。 + +### 3.5 群成员管理 + +复用 `/imGroup/memberList` 与成员治理命令,新增独立菜单页 `imGroupMember`,默认要求输入群号或从群详情跳转携带 `topic`。 + +字段说明: + +| 字段 | 说明 | +| --- | --- | +| `topic` | 群 Topic。 | +| `user_id` | 成员用户 ID。 | +| `display_name`/`nickname` | 群内展示名或用户昵称。 | +| `role` | 群主、管理员、普通成员。 | +| `status` | 正常、禁言、已移除。 | +| `muted_until` | 禁言截止时间。 | +| `joined_at` | 入群时间。 | + +按钮功能:查询、查看用户、设为管理员、取消管理员、转让群主、成员禁言、解除禁言、移除成员。现有接口分别为 `/imGroup/adminSet`、`/adminRemove`、`/ownerTransfer`、`/memberMute`、`/memberUnmute`、`/memberRemove`。 + +枚举说明:`role` 新增字典 `im_group_member_role`:`owner` 群主、`admin` 管理员、`member` 成员;成员状态新增 `im_group_member_status`。 + +### 3.6 邀请码管理 + +复用 `imInvite`。本地 `hotgo.im_registration_invite_codes` 有样例数据,批次表为空。当前需求文档按鸽达达页面描述 6 位数字邀请码;历史 IM 文档曾描述 5 位 ASCII 字母邀请码,二者冲突。若以复刻鸽达达为目标,应统一改为 6 位数字,Admin 生成、IM 注册校验、数据库唯一索引与错误文案同步调整。 + +字段说明:`code` 邀请码、`batch_id` 批次、`status` 状态、`max_uses` 最大使用次数、`used_count` 已使用次数、`expires_at` 过期时间、`created_by` 创建管理员、`created_at` 创建时间、`revoked_at` 撤销时间。 + +按钮功能:查询、新增、批量生成、批量查看、撤销、批量撤销、导出。接口已有 `/imInvite/list`、`/create`、`/batchCreate`、`/batchView`、`/revoke`、`/batchRevoke`、`/export`。 + +枚举说明:新增或确认 `im_invite_status`:`unused` 未使用、`used` 已用完、`expired` 已过期、`revoked` 已撤销。 + +### 3.7 单聊消息 + +当前 Admin 缺少独立消息管理模块,需要新增 `imPrivateMessage`。IM Server 已有消息表 `im_messages`,但 internal admin query 目前只支持 `/messages/{topic}/{seq}` 单条查询,缺少按会话分页检索单聊消息的后台列表接口。 + +Admin 改造: + +| 项 | 方案 | +| --- | --- | +| API | `/imPrivateMessage/list`、`/view`、`/hide`、`/delete`、`/export`。 | +| 数据源 | 新增 IM internal query:`/tenants/{tenant}/private-messages` 或 `/messages?kind=p2p`。 | +| 写操作 | 通过 Kafka 命令新增 `message.hide`、`message.delete` 或复用 IM 已有 recall/delete 能力封装为后台命令。 | +| 页面按钮 | 查询、查看上下文、隐藏、删除、导出。 | + +字段说明:`topic` 会话 Topic、`seq_id` 消息序号、`from_user_id` 发送者、`to_user_id` 接收者、`content_type` 内容类型、`content` 内容摘要、`status` 状态、`created_at` 发送时间、`updated_at` 更新时间。 + +枚举说明:`content_type` 建议 `text`、`image`、`file`、`audio`、`video`、`card`、`system`;`status` 建议 `normal`、`recalled`、`hidden`、`deleted`。 + +### 3.8 群聊消息 + +新增 `imGroupMessage` 页面。IM Server 本地有 `im_group_messages` 表,需求需要按群号、发送者、时间、内容关键字筛选。 + +Admin 改造:新增 `/imGroupMessage/list`、`/view`、`/hide`、`/delete`、`/export`。IM Server 补 internal query `group-messages`,支持 `topic`、`sender_user_id`、`content_type`、`status`、`created_at_start/end`、`keyword`。 + +字段、按钮、枚举与单聊消息一致,额外展示 `group_name`、`member_role`、`at_users`、`reply_to_seq`。 + +### 3.9 敏感词库 + +当前 Admin 与 IM Server 未发现完整敏感词库模块,需要新增。Admin 维护词库,IM Server 在消息发送、昵称/群名修改、反馈/举报提交时执行匹配。 + +Admin 改造: + +| 项 | 方案 | +| --- | --- | +| 表 | `im_sensitive_words`、`im_sensitive_word_groups`、`im_sensitive_word_hits` 可按需拆分。 | +| API | `/imSensitiveWord/list`、`/view`、`/edit`、`/delete`、`/status`、`/import`、`/export`。 | +| 同步 | 词库变更发布 config event 或 cache invalidate,IM Server 热加载。 | +| 按钮 | 查询、新增、编辑、删除、启用/禁用、导入、导出。 | + +字段说明:`word` 敏感词、`match_type` 匹配类型、`scene` 生效场景、`action` 命中动作、`replacement` 替换文本、`level` 风险等级、`status` 状态。 + +枚举说明:`match_type` 为 `exact` 精确、`contains` 包含、`regex` 正则;`scene` 为 `message` 消息、`profile` 资料、`group` 群资料、`feedback` 反馈;`action` 为 `block` 拦截、`replace` 替换、`review` 人审、`audit_only` 仅记录。 + +### 3.10 文件管理 + +复用 `imFile`,补齐鸽达达文件字段和预览能力。IM internal 已支持 `files`、`files/{id}`、`files/{id}/links`。本地 `tinode.im_fileuploads` 有数据,`im_group_files` 暂无数据。 + +字段说明:`file_id` 文件 ID、`user_id` 上传者、`topic` 所属会话、`mime_type` MIME、`size` 文件大小、`location` 存储位置、`etag` 校验、`status` 状态、`review_status` 审核状态、`risk_level` 风险等级、`created_at` 上传时间。 + +按钮功能:查询、查看、预览/下载、隔离、删除、清理孤儿文件。现有接口 `/imFile/quarantine`、`/imFile/delete`、`/imFile/cleanupOrphan` 可复用;预览/下载建议由 Admin 获取短期签名 URL,不直接暴露 OSS 原始地址。 + +枚举说明:现有字典包括 `im_storage_provider=oss`、`im_file_review_provider`、`im_file_review_status(pending/running/clean/risky/failed)`、`im_file_review_task_type(content/malware)`;还需补 `im_file_status`:`normal` 正常、`quarantined` 已隔离、`deleted` 已删除。 + +### 3.11 用户反馈 + +IM Server 已有 `im_feedback_submissions` 和 internal resource `feedback-submissions`,Admin 目前有反馈配置和工单模块,但缺少完全按鸽达达展示的反馈列表页。建议新增 `imFeedback` 或改造 `imWorkOrder` 作为反馈处理页。 + +字段说明:`feedback_id` 反馈 ID、`user_id` 用户、`category` 分类、`content` 内容、`contact` 联系方式、`file_ids` 附件、`client_context` 客户端环境、`include_diagnostics` 是否含诊断、`status` 状态、`created_at`、`updated_at`。 + +按钮功能:查询、查看、标记处理中、标记已处理、关闭、导出。写操作建议先落 Admin 工单状态,再通过 Kafka 或 IM internal 写接口回写业务状态。 + +枚举说明:`status` 建议 `received` 已收到、`processing` 处理中、`resolved` 已解决、`closed` 已关闭;`category` 来自 `im_feedback_config.categories`,禁止前端硬编码。 + +### 3.12 操作日志 + +复用 `imAuditLog` 与 `im_admin_operation_audit`。本地该表已有 45 条记录。页面应覆盖后台管理员对 IM 资源的所有操作,包括用户、群、消息、文件、配置、邀请码、敏感词。 + +字段说明:`id`、`request_id`、`admin_id`、`admin_name`、`action`、`target_type`、`target_id`、`before_data`、`after_data`、`ip`、`user_agent`、`result`、`created_at`。 + +按钮功能:查询、查看详情、导出。详情页需展示变更前后 JSON,敏感字段脱敏。 + +枚举说明:`target_type` 建议 `user`、`group`、`message`、`file`、`invite`、`config`、`sensitive_word`;`result` 为 `success`、`failed`、`pending`。 + +### 3.13 用户账号审计 + +新增专题页 `imUserAccountAudit`,从 Admin 操作审计、IM `audit-logs`、Kafka 命令结果中聚合用户生命周期事件。 + +字段说明:`event_id`、`user_id`、`action`、`operator_type`、`operator_id`、`reason`、`ip`、`device_id`、`before_state`、`after_state`、`created_at`。 + +按钮功能:查询、查看、跳转用户详情、导出。动作枚举建议包含注册、登录、登出、登录失败、改密、重置密码、封禁、解封、冻结、解冻、注销、删除、踢设备。 + +缺口:IM Server 当前 `im_audit_logs` 本地为空,需要补登录、失败、状态变更等事件写入。 + +### 3.14 群事件审计 + +可复用 `imGroup/adminLogList`、`outbox/group-events` 和 Admin audit,新增独立页面 `imGroupEventAudit`。 + +字段说明:`event_id`、`topic`、`group_name`、`operator_id`、`target_user_id`、`action`、`object_type`、`object_id`、`before_data`、`after_data`、`created_at`。 + +按钮功能:查询、查看、跳转群详情、导出。动作枚举建议包含建群、解散、修改资料、修改治理设置、入群申请、审批通过、审批拒绝、成员禁言、解除禁言、移除成员、设管理员、取消管理员、转让群主、公告发布/删除、文件删除。 + +### 3.15 管理员登录历史 + +复用 HotGo 系统登录日志能力,不需要 IM Server 改造。若现有登录日志字段不足,补 Admin 聚合接口 `/imAdminLoginHistory/list` 或直接配置菜单指向系统日志页面。 + +字段说明:管理员 ID、账号、昵称、登录 IP、地区、浏览器、系统、登录结果、失败原因、登录时间。 + +按钮功能:查询、查看、导出。枚举 `result` 为成功、失败。 + +### 3.16 用户登录历史 + +当前缺少完整用户登录历史。IM Server 路由中未看到客户端 `/v1/im/auth/logout` 或独立 session 管理路由;本地 `im_devices` 为空,不能满足鸽达达登录历史。 + +Admin 改造:新增 `imUserLoginHistory` 页面,查询 IM internal `user-login-logs`。字段包括 `user_id`、`phone`、`login_type`、`device_id`、`platform`、`ip`、`region`、`user_agent`、`result`、`login_at`、`logout_at`。 + +枚举说明:`login_type` 为 `password`、`sms`、`token_refresh`、`third_party`;`platform` 为 `ios`、`android`、`web`、`desktop`;`result` 为 `success`、`failed`。 + +### 3.17 IP 账号统计 + +新增 `imIpAccountStats` 页面。数据由 IM Server 基于注册 IP、登录 IP、失败登录 IP 聚合生成,Admin 只查询展示。 + +字段说明:`ip`、`region`、`user_count`、`register_count`、`login_count`、`failure_count`、`first_seen_at`、`last_seen_at`、`risk_level`。 + +按钮功能:查询、查看关联账号、导出、加入黑名单。加入黑名单写入“安全策略”或“用户分组”策略并同步 IM Server。 + +枚举说明:`risk_level` 为 `low`、`medium`、`high`;黑名单动作 `block_login`、`challenge`、`audit_only`。 + +### 3.18 登录失败日志 + +新增 `imLoginFailureLog` 页面。IM Server 需要记录认证失败事件,包含错误原因、IP、设备、账号、风控命中信息。 + +字段说明:`id`、`account`、`user_id`、`failure_type`、`reason`、`ip`、`region`、`device_id`、`platform`、`user_agent`、`attempt_at`。 + +按钮功能:查询、查看、导出、加入 IP 黑名单、封禁账号。封禁账号复用 `/imUser/ban`。 + +枚举说明:`failure_type` 为 `password_error`、`code_error`、`account_not_found`、`account_disabled`、`rate_limited`、`risk_blocked`。 + +### 3.19 私域设置 + +以现有 `imRegistration`、`imExternalConfig`、`imFeedbackConfig`、`imMailboxConfig`、`imNotification`、`imAppRelease` 为基础,新增汇总页面 `imTenantSettings`,按鸽达达页面展示私域基础配置。 + +字段说明:租户标识、注册开关、邀请码开关、短信开关、默认策略分组、客服/反馈配置、上传配置、客户端功能开关、版本策略、更新时间。客户端功能开关中新增 `global_friend_enabled` 和 `message_curfew_enabled` 的只读摘要,便于运营在私域设置页看到当前私域是否允许加好友、是否存在宵禁;实际编辑入口放在“安全策略”。 + +按钮功能:查看、编辑、保存、测试第三方配置、发布配置。保存后写 `hg_sys_config` 或 `im_tenant_config`,并通过 Kafka config event 通知 IM Server 刷新缓存。 + +枚举说明:开关统一使用布尔;配置发布状态 `draft`、`published`、`failed`。 + +### 3.20 安全策略 + +新增或重组 `imSecurityPolicy` 页面,统一管理登录安全、密码策略、IP 风控、敏感词动作、文件审核、用户处置原因、消息处置策略、全局好友功能与消息宵禁。 + +字段说明:`password_policy`、`login_rate_limit`、`ip_blacklist`、`ip_whitelist`、`sensitive_word_policy`、`file_review_policy`、`realname_policy`、`risk_challenge_policy`、`global_friend_enabled`、`friend_disabled_policy`、`message_curfew_enabled`、`message_curfew_rules`。 + +全局好友功能说明: + +| 字段 | 说明 | +| --- | --- | +| `global_friend_enabled` | 全局是否允许加好友。关闭后所有移动端加好友入口都禁止。 | +| `friend_disabled_policy.hide_profile` | 禁止加好友时,群成员列表、个人名片、二维码解析是否隐藏个人资料。 | +| `friend_disabled_policy.block_qrcode` | 是否禁止通过二维码添加好友。 | +| `friend_disabled_policy.block_group_member_entry` | 是否禁止从群成员入口查看个人信息或发起添加。 | +| `friend_disabled_policy.blocked_entries` | 被禁用的移动端入口数组:`search`、`profile_card`、`group_member`、`qrcode`、`invite_auto_add`、`recommendation`。关闭全局好友功能时默认全部禁用。 | +| `friend_disabled_policy.message` | 移动端提示文案,例如“当前时段暂不允许添加好友”。 | + +宵禁功能说明: + +| 字段 | 说明 | +| --- | --- | +| `message_curfew_enabled` | 是否启用消息宵禁。 | +| `message_curfew_rules` | 宵禁规则数组,支持每天、工作日、周末、自定义日期。 | +| `start_time`、`end_time` | 宵禁开始和结束时间,支持跨天,例如 `18:00` 到次日 `09:00`。 | +| `scope` | 管控范围,默认至少包含 `private_message`,即单聊/私聊不能发消息;如产品确认,可扩展 `group_message`。 | +| `whitelist_user_ids`、`whitelist_group_ids` | 豁免用户或群,可选。 | +| `message` | 宵禁期间发送失败提示。 | + +按钮功能:查询当前策略、编辑、保存、发布、恢复默认、查看发布历史。保存必须写操作审计。 + +枚举说明:风控动作统一 `allow`、`challenge`、`block`、`audit_only`;文件审核动作 `allow`、`quarantine`、`delete`、`manual_review`;宵禁范围 `private_message` 单聊/私聊、`group_message` 群聊;日期类型 `daily` 每天、`weekday` 工作日、`weekend` 周末、`custom` 自定义。 + +## 4. 后端实现方案 + +按 HotGo 规范新增模块时,必须完成 API、controller、service、logic、model/input、router/genrouter、前端 API、views/model、index、edit。接口命名沿用当前项目风格,例如 `/imPrivateMessage/list`,不直接照搬鸽达达 `/admin/private-messages` 路径;如后续需要兼容外部路径,可单独加网关映射。 + +新增模块建议: + +| 优先级 | 模块 | 说明 | +| --- | --- | --- | +| P0 | `imDashboard` | 首页统计与趋势。 | +| P0 | `imPrivateMessage`、`imGroupMessage` | 单聊/群聊消息查询与处置。 | +| P0 | `imSensitiveWord` | 敏感词库与热更新。 | +| P0 | `imUserLoginHistory`、`imLoginFailureLog` | 用户登录与失败日志。 | +| P1 | `imUserPolicyGroup` | 用户策略分组。 | +| P1 | `imFeedback` | 用户反馈处理页。 | +| P1 | `imIpAccountStats` | IP 聚合与风控联动。 | +| P1 | `imUserAccountAudit`、`imGroupEventAudit` | 专题审计页。 | +| P2 | `imTenantSettings`、`imSecurityPolicy` | 运营配置整合页。 | + +Admin 查询 IM 数据统一走 `server/internal/library/iminternal` 或现有 `imadmin` 封装,不在 logic 层直接拼接外部 HTTP 细节。写操作统一创建 `im_admin_commands` 与 `im_admin_outbox`,等待 Kafka result 更新状态;页面展示 `pending/success/failed/dead`。 + +## 5. 数据库与字典 + +配套建表与兼容迁移脚本见 [`sql/Admin-Server改造.sql`](sql/Admin-Server改造.sql)。脚本面向 `hotgo` 控制库,只保存管理配置和发布版本,不保存租户业务消息。 + +控制库新增表优先放在 `hotgo`: + +| 表 | 用途 | +| --- | --- | +| `im_user_policy_groups` | 用户策略分组主表。 | +| `im_user_policy_group_members` | 用户与策略分组关系。 | +| `im_sensitive_word_groups` | 敏感词分组。 | +| `im_sensitive_words` | 敏感词主表。 | +| `im_security_policy` | 安全策略草稿/发布版本。 | +| `im_admin_query_snapshots` | 可选,用于缓存重型统计查询快照。 | + +字典由后端 `internal/consts` 注册,前端通过 `dict.loadOptions()` 加载。禁止在 `model.ts` 中硬编码枚举中文。 + +必补字典:`im_user_state`、`im_group_status`、`im_group_member_role`、`im_group_member_status`、`im_invite_status`、`im_message_content_type`、`im_message_status`、`im_sensitive_match_type`、`im_sensitive_scene`、`im_sensitive_action`、`im_feedback_status`、`im_login_type`、`im_login_failure_type`、`im_risk_level`、`im_policy_action`、`im_friend_entry`、`im_curfew_scope`、`im_curfew_date_type`。 + +## 6. 权限与审计 + +每个按钮权限与后端路由保持一致,例如 `/imPrivateMessage/delete`、`/imSensitiveWord/import`。高危操作包括用户删除、账号注销、群解散、消息删除、文件删除、IP 拉黑、安全策略发布,必须二次确认、记录原因、写 `im_admin_operation_audit`,并展示 Kafka 命令执行结果。 + +审计脱敏规则: + +| 类型 | 展示规则 | +| --- | --- | +| 手机号 | 中间 4 位脱敏。 | +| 身份证/实名 | 默认只展示脱敏字段。 | +| 配置密钥 | 只展示前后 3-4 位或完全隐藏。 | +| 消息内容 | 列表展示摘要,详情按权限展示全文。 | +| 文件地址 | 不展示原始存储地址,使用短期签名 URL。 | + +## 7. 联调与验收 + +验收顺序建议: + +1. 补齐 `hotgo.im_tenant` 与 `tinode` 默认租户映射,确保 Admin 能通过 tenant code 查询 IM internal。 +2. 完成数据概览、用户、群、邀请码、文件这些已有基础模块的字段对齐。 +3. 新增消息、敏感词、反馈、登录日志、IP 统计等缺口模块。 +4. 为 Kafka 命令增加幂等键、结果回写、失败重试、死信展示。 +5. 使用本地 `hotgo` 与 `tinode` 数据验证每个页面的查询、按钮、详情和导出。 + +最低验收标准:20 个菜单均可打开;查询按钮能返回真实或空态数据;表格字段与需求文档一致;所有枚举来自字典;高危按钮有二次确认、原因、审计与结果状态;敏感数据脱敏。 diff --git a/docs/admin-adfahi-research/IM-Server改造文档.md b/docs/admin-adfahi-research/IM-Server改造文档.md new file mode 100644 index 0000000..9f69b98 --- /dev/null +++ b/docs/admin-adfahi-research/IM-Server改造文档.md @@ -0,0 +1,390 @@ +# IM Server 改造文档:支撑鸽达达管理后台复刻 + +本文面向 `/Users/youshunlai/go_workspace/im_server` 的现状改造,目标是为 Admin Server 复刻鸽达达后台提供准确、稳定、可审计的数据与治理能力。当前 IM Server 已有 Tinode 风格实时链路、产品 HTTP API、独立租户库、Kafka 命令消费、配置事件消费、内部 Admin Query,但鸽达达 20 个后台页面仍需要补充若干查询资源、审计日志、风控策略与消息处置能力。 + +## 1. 当前实现现状 + +核心架构: + +| 能力 | 现状 | +| --- | --- | +| 实时链路 | `Session -> Hub -> Topic -> Store`。 | +| 客户端入口 | WebSocket `/v0/channels`,产品 HTTP `/v1/im/...`。 | +| 后台只读入口 | `/internal/admin-query/tenants/{tenant_code}/...`,要求内部签名与 capability。 | +| 后台写操作 | Kafka Admin Command 消费器 `startKafkaAdminCommandConsumer`。 | +| 配置同步 | Kafka config event、cache invalidate consumer 已存在。 | +| 消息转发 | `/v1/im/messages/forward` 已存在。 | +| 音视频入会 | `/v1/im/calls/rtc-join` 已存在。 | + +本地 `tinode` 库观察:`im_users` 有数据、`im_topics` 有群/会话、`im_subscriptions` 有订阅、`im_messages` 有大量单聊或通用消息、`im_group_messages` 有群消息、`im_feedback_submissions`、`im_abuse_reports`、`im_kafka_dead_letters` 等表已存在;`im_audit_logs` 本地为空,`im_devices` 和 `im_group_files` 数据不足,不能直接满足后台登录历史、设备历史和群文件验收。 + +已有内部查询资源: + +| 资源 | 已支持字段/场景 | +| --- | --- | +| `users` | 用户 ID、账号、手机号、状态、资料、凭证摘要、最后在线。 | +| `user_devices` | 用户设备列表。 | +| `groups` | Topic、群名、群主、群状态、治理开关、成员数。 | +| `groups/{topic}/members` | 群成员。 | +| `group_join-requests`、`group_invitations`、`group_announcements`、`group_mutes`、`group_admin-logs`、`group_files` | 群治理专题资源。 | +| `messages/{topic}/{seq}` | 单条消息详情。 | +| `files`、`files/{id}`、`files/{id}/links` | 文件列表、详情、链接关系。 | +| `feedback-submissions`、`abuse-reports`、`realname-verifications`、`audit-logs` | 用户反馈、举报、实名、审计。 | +| `dashboard/summary` | 当前只返回待办类指标,不足以覆盖鸽达达首页统计。 | + +已有 Kafka Admin Command: + +| 命令 | 用途 | +| --- | --- | +| `user.ban`、`user.unban` | 用户封禁/解封。 | +| `user.freeze`、`user.unfreeze` | 用户冻结/解冻。 | +| `user.device.kick`、`user.logout_all` | 设备踢下线、全端登出。 | +| `user.account.cancel`、`user.account.delete`、`user.password.reset` | 注销、删除、重置密码。 | +| `group.profile.update` | 群资料更新。 | +| `group.governance.update` | 群治理开关更新。 | +| `group.admin.set`、`group.admin.remove`、`group.owner.transfer` | 群角色管理。 | +| `group.member.mute`、`group.member.unmute`、`group.member.remove` | 群成员治理。 | +| `kafka.dead_letter.replay`、`ignore`、`resolve` | 死信处理。 | + +## 2. 改造原则 + +IM Server 只负责租户业务库的数据查询、业务状态变更、实时生效与审计事件产生,不直接依赖 HotGo 后台表。Admin Server 下发的配置、策略和治理命令必须具备幂等性,并通过事件结果回传 Admin。所有 internal query 必须保持只读、分页、最大 `per_page=200`、内部签名鉴权、字段脱敏。 + +响应协议继续沿用现有 `imHTTPResponse`:`code`、`data`、`reason`、`message`、`details`、`request_id`、`server_time`。写请求继续要求 `Idempotency-Key`,避免后台重复点击导致重复处置。 + +## 3. 支撑 20 个后台页面的 IM 改造 + +### 3.1 数据概览 + +现有 `dashboard/summary` 只覆盖死信、待处理 outbox、待实名、待举报、待反馈、活跃群、封禁用户等运营待办。需要新增统计字段以匹配鸽达达首页。 + +新增 internal query: + +| 路径 | 方法 | 说明 | +| --- | --- | --- | +| `/internal/admin-query/tenants/{tenant}/dashboard/overview` | GET | 返回总用户、活跃用户、总群组、总会话、总消息、今日消息。 | +| `/internal/admin-query/tenants/{tenant}/dashboard/trends` | GET | 返回最近 N 天用户增长与消息增长。 | + +字段口径: + +| 字段 | 计算建议 | +| --- | --- | +| `total_users` | `im_users` 有效用户数。 | +| `active_users` | `last_seen` 在指定窗口内或当天有消息/登录行为的用户数。 | +| `total_groups` | `im_group_settings.group_status='active'` 或有效群 topic 数。 | +| `total_conversations` | 有效 P2P topic + group topic 数。 | +| `total_messages` | `im_messages` + `im_group_messages`,按最终存储口径去重。 | +| `today_messages` | 当天创建的消息数,按租户时区对齐。 | +| `date`、`user_count`、`message_count` | 趋势表行字段。 | + +### 3.2 用户管理 + +现有 `users`、`users/{id}`、`users/{id}/devices` 基本可支撑。需要补足鸽达达页面要求的筛选和字段脱敏。 + +改造点: + +| 项 | 内容 | +| --- | --- | +| 查询筛选 | 增加 `phone`、`public_account`、`state`、`created_at_start/end`、`last_seen_start/end`。 | +| 字段补充 | 返回 `nickname`、头像文件 ID、性别、地区、签名、认证方式摘要、设备数、最近登录 IP。 | +| 状态映射 | 将 Tinode `state` 转换为 Admin 字典所需状态;保留原始值 `raw_state` 便于排错。 | +| 治理命令 | 继续使用已有 `user.ban/unban/freeze/unfreeze/device.kick/logout_all/account.cancel/account.delete/password.reset`。 | +| 审计 | 每次状态变更、重置密码、踢设备必须写 `im_audit_logs` 并产出 Kafka command result。 | + +枚举建议:`user_state` 包含正常、封禁、冻结、注销、删除;`device_platform` 包含 `ios`、`android`、`web`、`desktop`、`unknown`。 + +### 3.3 用户分组 + +当前 IM Server 没有看到独立的后台用户策略分组执行层。Admin 将新增策略分组后,IM Server 需要消费配置事件并在运行时执行。 + +新增能力: + +| 能力 | 说明 | +| --- | --- | +| 策略缓存 | 按租户缓存 `policy_group`、成员关系、优先级与规则。 | +| 匹配入口 | 登录、注册、加好友、建群、入群、发消息、上传文件、发起音视频前匹配策略。 | +| 配置事件 | 消费 `user_policy_group.updated`、`user_policy_group.deleted`,刷新缓存。 | +| 命中审计 | 命中 `deny`、`challenge` 或高风险规则时写审计与风控日志。 | + +策略动作枚举:`allow` 放行、`deny` 拦截、`challenge` 二次验证、`audit_only` 仅记录。 + +好友策略需要在后端覆盖所有移动端入口。禁止加好友时,IM Server 不能只让客户端隐藏按钮,而要在搜索用户、查看个人名片、群成员资料、二维码解析、好友申请、邀请注册自动加好友、推荐联系人等入口统一拦截或返回脱敏数据。策略字段建议包含 `allow_add_friend`、`direct_add_friend`、`max_friend_count`、`allow_qrcode_add_friend`、`allow_group_member_profile`、`hide_profile_when_friend_disabled`。 + +### 3.4 群组管理 + +已有 `groups` 查询与群治理命令可复用。需要补鸽达达群状态语义和可能的群封停动作。 + +改造点: + +| 项 | 内容 | +| --- | --- | +| 字段 | 确保 `topic`、`group_name`、`owner_id`、`group_status`、`business_member_count`、`join_approval`、`mute_all`、`created_at` 可稳定返回。 | +| 状态 | 明确 `group_status` 值:`active`、`muted`、`suspended`、`dissolved`。 | +| 命令 | 已有资料更新、治理设置、角色与成员治理;若需求要求群封停/解封,新增 `group.suspend`、`group.unsuspend`。 | +| 审计 | 群资料、治理开关、解散、禁言、成员操作均写 `im_group_admin_logs` 与 `im_audit_logs`。 | + +### 3.5 群成员管理 + +现有 `groups/{topic}/members` 与成员命令可支撑。需要确保成员列表返回群角色、禁言状态与入群时间。 + +字段建议:`topic`、`user_id`、`nickname`、`display_name`、`role`、`status`、`muted_until`、`joined_at`、`last_seen`。`role` 枚举为 `owner`、`admin`、`member`;`status` 枚举为 `active`、`muted`、`removed`。 + +按钮对应命令:设管理员 `group.admin.set`、取消管理员 `group.admin.remove`、转让群主 `group.owner.transfer`、成员禁言 `group.member.mute`、解除禁言 `group.member.unmute`、移除成员 `group.member.remove`。 + +### 3.6 邀请码管理 + +IM Server 注册链路已在 `user.go` 中记录邀请码使用,`RecordUse` 已存在。需要解决邀请码格式冲突:鸽达达需求为 6 位数字,既有 IM 文档曾要求 5 位 ASCII 字母。若严格复刻鸽达达,应将 IM 注册校验、错误提示、唯一性检查、大小写处理统一改为 6 位数字。 + +改造点: + +| 项 | 内容 | +| --- | --- | +| 校验 | 仅允许 `^[0-9]{6}$`,不做大小写转换。 | +| 使用记录 | 注册成功后写 `im_registration_invite_uses`,包含 `code`、`user_id`、`request_id`、`used_at`。 | +| 并发 | 使用事务或唯一约束防止超发。 | +| 状态 | `unused`、`used`、`expired`、`revoked`。 | + +### 3.7 单聊消息 + +当前只有单条消息 detail 查询,不足以支撑后台列表。需要新增 internal message list resource。 + +新增 internal query: + +| 路径 | 方法 | 查询参数 | +| --- | --- | --- | +| `/internal/admin-query/tenants/{tenant}/private-messages` | GET | `topic`、`from_user_id`、`to_user_id`、`content_type`、`status`、`keyword`、`created_at_start/end`、`page`、`per_page`。 | +| `/internal/admin-query/tenants/{tenant}/messages/{topic}/{seq}` | GET | 已有,继续作为详情。 | + +返回字段:`topic`、`seq_id`、`from_user_id`、`to_user_id`、`head`、`content_type`、`content_excerpt`、`status`、`created_at`、`updated_at`。全文内容只在详情返回,并根据 Admin 权限决定是否脱敏。 + +新增 Kafka 命令建议:`message.hide`、`message.unhide`、`message.delete`、`message.restore`。如果只允许软删除,命令语义必须明确为后台不可见还是客户端不可见。 + +### 3.8 群聊消息 + +新增 internal group message list resource。可读取 `im_group_messages` 或统一消息表,但需要确保与客户端可见状态一致。 + +路径:`/internal/admin-query/tenants/{tenant}/group-messages`。 + +筛选:`topic`、`sender_user_id`、`content_type`、`status`、`keyword`、`created_at_start/end`。返回字段在单聊基础上增加 `group_name`、`reply_to_seq`、`at_users`。 + +处置命令复用消息命令,审计动作记录为 `message.hidden`、`message.deleted`、`message.restored`。 + +### 3.9 敏感词库 + +IM Server 需要新增敏感词运行时,而词库主数据由 Admin 控制库维护。IM Server 只消费配置事件和执行匹配。 + +改造点: + +| 项 | 内容 | +| --- | --- | +| 缓存 | 按租户加载敏感词,支持分组、场景、优先级、状态。 | +| 匹配场景 | 消息发送、编辑消息、用户昵称/签名、群名/公告、反馈/举报内容。 | +| 动作 | `block` 拦截、`replace` 替换、`review` 进入审核、`audit_only` 仅审计。 | +| 审计 | 命中记录写 `im_sensitive_word_hits` 或统一 `im_audit_logs`。 | +| 性能 | 正常词库用 AC 自动机或等价高效结构;正则词单独限量执行。 | + +### 3.10 文件管理 + +已有 internal `files`、`files/{id}`、`files/{id}/links` 与文件生命周期 Kafka 基础。需要补后台预览、下载和处置一致性。 + +改造点: + +| 项 | 内容 | +| --- | --- | +| 文件状态 | `normal`、`quarantined`、`deleted`、`orphan`。 | +| 审核状态 | 复用 `pending`、`running`、`clean`、`risky`、`failed`。 | +| 预览下载 | 提供短期签名 URL 或代理下载,禁止返回永久存储地址。 | +| 隔离删除 | 后台命令应更新文件状态、断开消息/群文件链接、写审计。 | +| 安全审核 | 接入内容安全/恶意文件检测结果,并可重试审核。 | + +### 3.11 用户反馈 + +已有 `feedback-submissions` 资源可查询。需要补处理状态回写能力和状态审计。 + +新增能力: + +| 能力 | 说明 | +| --- | --- | +| 状态更新 | 提供 Kafka 命令或内部写接口:`feedback.status.update`。 | +| 附件 | 通过文件链接查询反馈附件,并返回签名预览 URL。 | +| 分类 | 分类来自 `im_feedback_config.categories`,Admin 配置后 IM bootstrap 同步。 | +| 审计 | 处理人、处理备注、前后状态写入审计。 | + +状态枚举:`received`、`processing`、`resolved`、`closed`。 + +### 3.12 操作日志 + +IM Server 需要补充业务侧审计完整性。当前本地 `im_audit_logs` 为空,不能支撑后台多页面审计。 + +写入场景:用户状态变更、群治理、消息处置、文件处置、反馈处理、敏感词命中、登录成功/失败、配置热更新、Kafka 命令执行结果。 + +字段:`request_id`、`actor_user_id`、`action`、`target_type`、`target_id`、`ip`、`user_agent`、`detail`、`created_at`。`detail` 中敏感值必须脱敏或存 hash。 + +### 3.13 用户账号审计 + +新增或扩展 internal resource `user-account-audit`,按用户聚合账号生命周期事件。 + +路径:`/internal/admin-query/tenants/{tenant}/user-account-audit`。 + +筛选:`user_id`、`action`、`operator_id`、`ip`、`created_at_start/end`。返回:`event_id`、`user_id`、`action`、`operator_type`、`operator_id`、`before_state`、`after_state`、`reason`、`ip`、`device_id`、`created_at`。 + +动作枚举:`registered`、`login_success`、`logout`、`login_failed`、`password_changed`、`password_reset`、`banned`、`unbanned`、`frozen`、`unfrozen`、`device_kicked`、`cancelled`、`deleted`。 + +### 3.14 群事件审计 + +已有 `im_group_admin_logs` 与 group outbox,可新增 internal resource `group-event-audit` 或复用 `group_admin-logs` 扩展为全局查询。 + +路径:`/internal/admin-query/tenants/{tenant}/group-event-audit`。 + +筛选:`topic`、`operator_id`、`target_user_id`、`action`、`created_at_start/end`。返回:`event_id`、`topic`、`operator_id`、`target_user_id`、`action`、`object_type`、`object_id`、`before_data`、`after_data`、`created_at`。 + +### 3.15 管理员登录历史 + +该页面主要由 Admin Server 的 HotGo 登录日志提供,IM Server 无需改造。若以后要展示 Admin 调用 IM internal API 的访问审计,可在 internal API 层增加 `internal_api_access_logs`,但不作为复刻 P0。 + +### 3.16 用户登录历史 + +当前缺少完整登录历史表与查询。需要在认证成功、token 刷新、主动/被动登出时记录日志。 + +新增表建议:`im_user_login_logs`。 + +字段:`id`、`user_id`、`login_type`、`device_id`、`platform`、`ip`、`region`、`user_agent`、`request_id`、`result`、`login_at`、`logout_at`、`created_at`。 + +新增 internal query:`/internal/admin-query/tenants/{tenant}/user-login-logs`,支持按 `user_id`、`phone/account`、`ip`、`platform`、`login_at_start/end` 查询。 + +### 3.17 IP 账号统计 + +新增聚合查询,来源为注册、登录成功、登录失败、风控命中日志。 + +路径:`/internal/admin-query/tenants/{tenant}/ip-account-stats`。 + +字段:`ip`、`region`、`user_count`、`register_count`、`login_count`、`failure_count`、`first_seen_at`、`last_seen_at`、`risk_level`。该接口可以实时聚合,也可以由定时任务写入快照表以降低查询成本。 + +### 3.18 登录失败日志 + +新增表建议:`im_login_failure_logs`。 + +字段:`id`、`account`、`user_id`、`failure_type`、`reason`、`ip`、`region`、`device_id`、`platform`、`user_agent`、`request_id`、`attempt_at`。 + +新增 internal query:`/internal/admin-query/tenants/{tenant}/login-failure-logs`。失败类型枚举:`password_error`、`code_error`、`account_not_found`、`account_disabled`、`rate_limited`、`risk_blocked`。 + +### 3.19 私域设置 + +IM Server 需要确保客户端 `/v1/im/bootstrap` 使用 Admin 发布后的配置,并支持热更新。 + +配置来源: + +| 配置 | 使用位置 | +| --- | --- | +| 注册/邀请码/短信 | 注册、验证码、密码找回。 | +| 上传/文件审核 | 上传、预览、消息附件。 | +| 反馈/邮箱/通知 | 客户端入口与提交表单。 | +| 版本/工作台 | bootstrap、app release、workbench。 | +| 声网/音视频 | `/v1/im/calls/rtc-join`。 | +| 好友功能 | `/v1/im/bootstrap` 返回 `global_friend_enabled`、入口隐藏建议和提示文案;实际拦截由后端完成。 | +| 消息宵禁 | `/v1/im/bootstrap` 返回当前宵禁摘要和提示文案;发送消息时仍以后端实时校验为准。 | + +改造点:配置事件必须带版本号;IM 缓存应支持按租户回滚到上一发布版本;bootstrap 返回的配置只包含客户端需要的非敏感字段。 + +### 3.20 安全策略 + +IM Server 是安全策略的执行层。需要将 Admin 发布的策略接入登录、验证码、消息、文件、群、好友、实名、音视频等关键入口。全局禁止加好友和宵禁必须后端强制执行,客户端展示仅作为体验优化。 + +策略项: + +| 策略 | 执行点 | +| --- | --- | +| 密码强度 | 注册、改密、重置密码。 | +| 登录限频 | 登录、验证码校验、密码找回。 | +| IP 黑白名单 | 登录、注册、发消息、上传文件。 | +| 敏感词 | 消息、资料、群资料、反馈。 | +| 文件审核 | 上传完成、消息发送前后、后台重审。 | +| 实名要求 | 加好友、建群、入群、发起音视频等敏感能力。 | +| 风控挑战 | 登录异常、IP 异常、设备异常。 | +| 全局好友功能 | 用户搜索、好友申请、二维码解析、群成员资料、个人名片、推荐联系人、邀请注册自动加好友。 | +| 消息宵禁 | 单聊/私聊发送消息入口,默认拦截 P2P topic 的 `{pub}`;如产品确认群聊也管控,可扩展到 group topic。 | + +动作枚举统一为 `allow`、`challenge`、`block`、`audit_only`。 + +全局禁止加好友执行规则: + +| 入口 | 后端行为 | +| --- | --- | +| 用户搜索 `/v1/im/users/search` | 可直接返回空列表,或返回脱敏结果但不允许发起好友申请。 | +| 用户详情 `/v1/im/users/{id}` | 非好友场景隐藏手机号、账号、二维码、个人扩展资料,只保留必要公开字段。 | +| 好友申请 `/v1/im/friend-requests` | 返回业务错误 reason,例如 `FRIEND_DISABLED`。 | +| 二维码解析 `/v1/im/qrcodes/resolve` | 禁止解析出可加好友目标,或返回脱敏提示。 | +| 群成员资料 | 群成员列表可保留昵称/头像用于群聊展示,但点击个人信息时返回脱敏资料并禁止添加。 | +| 邀请注册自动加好友 | 注册成功后跳过自动加好友并写审计,或按策略直接拒绝该邀请码能力。 | + +宵禁执行规则: + +| 项 | 说明 | +| --- | --- | +| 配置 | `message_curfew_enabled`、`message_curfew_rules`,规则包含时区、日期类型、开始时间、结束时间、scope、白名单、提示文案。 | +| 判断时机 | P2P topic 发布消息前校验;HTTP 消息发送、转发、草稿转发送等入口也要校验。 | +| 拦截结果 | 返回明确 reason,例如 `MESSAGE_CURFEW_ACTIVE`,并记录 `im_audit_logs` 或风控日志。 | +| 白名单 | 支持用户、系统账号、特定会话豁免。 | +| 跨天 | 支持如下班后 `18:00-09:00` 的跨天时间段。 | + +## 4. Internal Admin Query 新增清单 + +建议在 `server/internal_admin_query_resources.go` 增补资源,并在 `server/internal_api.go` 路由分发中注册: + +| 资源 | 必要性 | 说明 | +| --- | --- | --- | +| `dashboard/overview`、`dashboard/trends` | P0 | 首页统计。 | +| `private-messages`、`group-messages` | P0 | 消息管理列表。 | +| `user-login-logs`、`login-failure-logs` | P0 | 登录审计。 | +| `ip-account-stats` | P1 | IP 风险聚合。 | +| `user-account-audit`、`group-event-audit` | P1 | 专题审计。 | +| `sensitive-word-hits` | P1 | 敏感词命中查询。 | + +所有列表接口返回现有结构:`items`、`total`、`page`、`per_page`。时间筛选继续使用 `created_at_start`、`created_at_end` 等字段,UID 参数继续支持数字 ID 与 `usr...` 编码。 + +## 5. Kafka 命令新增清单 + +已有用户与群治理命令保留。为复刻后台补充以下命令: + +| 命令 | 说明 | +| --- | --- | +| `message.hide` | 后台隐藏消息,客户端不可见或后台标记隐藏。 | +| `message.unhide` | 恢复隐藏消息。 | +| `message.delete` | 后台删除消息,建议软删除。 | +| `message.restore` | 恢复误删消息。 | +| `file.quarantine` | 文件隔离。 | +| `file.delete` | 文件删除。 | +| `feedback.status.update` | 反馈处理状态更新。 | +| `group.suspend`、`group.unsuspend` | 如产品确认需要群封停/解封,则新增。 | +| `security.policy.reload` | 强制刷新安全策略缓存。 | +| `friend.policy.reload` | 强制刷新好友入口策略缓存,可与 `security.policy.reload` 合并实现。 | +| `curfew.policy.reload` | 强制刷新宵禁策略缓存,可与 `security.policy.reload` 合并实现。 | + +命令 payload 必须包含 `command_id`、`actor_user_id`、`reason`、目标 ID、`version` 或 `expected_version`。执行后发布 result,状态为 `success`、`failed`、`dead`。 + +## 6. 数据库改造建议 + +配套建表与兼容迁移脚本见 [`sql/IM-Server改造.sql`](sql/IM-Server改造.sql)。脚本默认使用本地 `tinode`,上线时必须对每个独立租户数据库分别执行,租户业务表不增加 `tenant_id`。 + +租户库新增或补强表: + +| 表 | 用途 | +| --- | --- | +| `im_user_login_logs` | 用户登录成功、登出、刷新等历史。 | +| `im_login_failure_logs` | 登录失败与风控拦截历史。 | +| `im_message_admin_actions` | 后台消息处置记录,可与消息表状态解耦。 | +| `im_sensitive_word_hits` | 敏感词命中记录。 | +| `im_ip_account_stats_daily` | IP 账号统计快照,可选。 | + +已有表需补数据写入:`im_audit_logs` 当前本地为空,需要在关键业务入口统一写;`im_devices` 本地为空,需要确认设备绑定/解绑路径是否完整;`im_group_files` 本地为空,需要验证群文件写入链路。 + +索引建议:消息列表按 `(topic, created_at)`、`(from, created_at)`;登录日志按 `(user_id, login_at)`、`(ip, login_at)`;失败日志按 `(account, attempt_at)`、`(ip, attempt_at)`;敏感词命中按 `(scene, created_at)`、`(user_id, created_at)`。 + +## 7. 验收要求 + +1. Admin 20 个页面的查询按钮均能通过 internal query 返回真实数据或标准空态。 +2. 用户、群、消息、文件、反馈的后台写操作均通过 Kafka 命令,具备幂等、结果回传、死信处理。 +3. 登录历史、失败日志、账号审计、群事件审计不再依赖空表,关键入口可产生真实审计数据。 +4. 敏感词与安全策略变更可热更新,无需重启 IM Server。 +5. 所有 internal query 均保持只读、分页、鉴权、脱敏和错误 reason 规范。 +6. 邀请码格式在 Admin 与 IM 注册链路完全一致,避免后台生成后客户端无法使用。 diff --git a/docs/admin-adfahi-research/api-samples.json b/docs/admin-adfahi-research/api-samples.json new file mode 100644 index 0000000..6cab855 --- /dev/null +++ b/docs/admin-adfahi-research/api-samples.json @@ -0,0 +1,70 @@ +[ + { + "endpoint": "/admin/stats", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/users", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/user-policy-groups", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/groups", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/groups/events", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/invite-codes", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/messages/search", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/sensitive-words", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/feedbacks", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/audit/logs", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/audit/user-account-logs", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/admin-login-history", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/user-login-history", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/audit/ip-user-stats", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/login-failure-logs", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/tenant-settings", + "error": "TypeError: window.fetch is not a function" + }, + { + "endpoint": "/admin/security-settings", + "error": "TypeError: window.fetch is not a function" + } +] \ No newline at end of file diff --git a/docs/admin-adfahi-research/index-RosMaKu2.js b/docs/admin-adfahi-research/index-RosMaKu2.js new file mode 100644 index 0000000..b10b489 --- /dev/null +++ b/docs/admin-adfahi-research/index-RosMaKu2.js @@ -0,0 +1,158 @@ +var Dh=Object.defineProperty;var Ph=(e,t,r)=>t in e?Dh(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var Or=(e,t,r)=>Ph(e,typeof t!="symbol"?t+"":t,r);import{r as g,c as Vn,g as yu,e as Nh,R as Gt,u as wu,f as Lh,h as Mh,i as Bh,j as Ge,N as la,B as Uh}from"./react-vendor-XHtC9wm2.js";import{r as zh,L as Ko,T as Cr,F as b,R as $h,a as sc,b as po,c as $n,d as Go,e as Wh,f as Hh,g as Vh,h as ac,i as ca,j as Ks,k as xi,l as Kh,m as ci,n as Su,o as Tu,p as bu,q as ic,s as Eu,t as Gh,u as Yh,v as oc,w as qh,x as lc,y as Xh,z as Yo,A as cc,M as Jh,S as Ie,B as da,D as Zh,C as zi,E as Me,I as ve,G as Mn,H as Y,Q as Qh,J as je,K as pi,N as em,O as E,P as be,U as $e,V as Es,W as Ct,X as tn,Y as Ye,Z as tm,_ as ju,$ as Iu,a0 as $r,a1 as $i,a2 as Mr,a3 as Te,a4 as un,a5 as at,a6 as qo,a7 as Ar,a8 as Xt,a9 as xl,aa as Gs,ab as pl,ac as rr,ad as Cu,ae as rn,af as Xs,ag as Cn,ah as zn,ai as An,aj as gi,ak as _i,al as vs,am as Au,an as jr,ao as go,ap as dc,aq as gl,ar as rt,as as ua,at as Js,au as js,av as rm,aw as nm,ax as Zs,ay as sm,az as Xo,aA as uc,aB as am,aC as _o,aD as im,aE as om,aF as lm}from"./antd-vendor-CXEPnBxj.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))n(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&n(o)}).observe(document,{childList:!0,subtree:!0});function r(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(s){if(s.ep)return;s.ep=!0;const i=r(s);fetch(s.href,i)}})();var ku={exports:{}},Wi={};/** + * @license React + * react-jsx-runtime.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var cm=g,dm=Symbol.for("react.element"),um=Symbol.for("react.fragment"),fm=Object.prototype.hasOwnProperty,hm=cm.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,mm={key:!0,ref:!0,__self:!0,__source:!0};function Fu(e,t,r){var n,s={},i=null,o=null;r!==void 0&&(i=""+r),t.key!==void 0&&(i=""+t.key),t.ref!==void 0&&(o=t.ref);for(n in t)fm.call(t,n)&&!mm.hasOwnProperty(n)&&(s[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps,t)s[n]===void 0&&(s[n]=t[n]);return{$$typeof:dm,type:e,key:i,ref:o,props:s,_owner:hm.current}}Wi.Fragment=um;Wi.jsx=Fu;Wi.jsxs=Fu;ku.exports=Wi;var a=ku.exports,Jo={},fc=Vn;Jo.createRoot=fc.createRoot,Jo.hydrateRoot=fc.hydrateRoot;var Hi={},Ou={exports:{}};(function(e){function t(r){return r&&r.__esModule?r:{default:r}}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports})(Ou);var Vi=Ou.exports,Ki={};Object.defineProperty(Ki,"__esModule",{value:!0});Ki.default=void 0;var xm={items_per_page:"条/页",jump_to:"跳至",jump_to_confirm:"确定",page:"页",prev_page:"上一页",next_page:"下一页",prev_5:"向前 5 页",next_5:"向后 5 页",prev_3:"向前 3 页",next_3:"向后 3 页",page_size:"页码"};Ki.default=xm;var Gi={},ba={},Yi={},Ru={exports:{}},Du={exports:{}},Pu={exports:{}},Nu={exports:{}};(function(e){function t(r){"@babel/helpers - typeof";return e.exports=t=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(n){return typeof n}:function(n){return n&&typeof Symbol=="function"&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n},e.exports.__esModule=!0,e.exports.default=e.exports,t(r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports})(Nu);var Lu=Nu.exports,Mu={exports:{}};(function(e){var t=Lu.default;function r(n,s){if(t(n)!="object"||!n)return n;var i=n[Symbol.toPrimitive];if(i!==void 0){var o=i.call(n,s||"default");if(t(o)!="object")return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return(s==="string"?String:Number)(n)}e.exports=r,e.exports.__esModule=!0,e.exports.default=e.exports})(Mu);var pm=Mu.exports;(function(e){var t=Lu.default,r=pm;function n(s){var i=r(s,"string");return t(i)=="symbol"?i:i+""}e.exports=n,e.exports.__esModule=!0,e.exports.default=e.exports})(Pu);var gm=Pu.exports;(function(e){var t=gm;function r(n,s,i){return(s=t(s))in n?Object.defineProperty(n,s,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[s]=i,n}e.exports=r,e.exports.__esModule=!0,e.exports.default=e.exports})(Du);var _m=Du.exports;(function(e){var t=_m;function r(s,i){var o=Object.keys(s);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(s);i&&(l=l.filter(function(c){return Object.getOwnPropertyDescriptor(s,c).enumerable})),o.push.apply(o,l)}return o}function n(s){for(var i=1;i{let t;const r=new Set,n=(u,h)=>{const m=typeof u=="function"?u(t):u;if(!Object.is(m,t)){const _=t;t=h??(typeof m!="object"||m===null)?m:Object.assign({},t,m),r.forEach(x=>x(t,_))}},s=()=>t,c={setState:n,getState:s,getInitialState:()=>d,subscribe:u=>(r.add(u),()=>r.delete(u)),destroy:()=>{(Nm?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),r.clear()}},d=t=e(n,s,c);return c},Lm=e=>e?mc(e):mc;var zu={exports:{}},$u={},Wu={exports:{}},Hu={};/** + * @license React + * use-sync-external-store-shim.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Is=g;function Mm(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var Bm=typeof Object.is=="function"?Object.is:Mm,Um=Is.useState,zm=Is.useEffect,$m=Is.useLayoutEffect,Wm=Is.useDebugValue;function Hm(e,t){var r=t(),n=Um({inst:{value:r,getSnapshot:t}}),s=n[0].inst,i=n[1];return $m(function(){s.value=r,s.getSnapshot=t,vo(s)&&i({inst:s})},[e,r,t]),zm(function(){return vo(s)&&i({inst:s}),e(function(){vo(s)&&i({inst:s})})},[e]),Wm(r),r}function vo(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!Bm(e,r)}catch{return!0}}function Vm(e,t){return t()}var Km=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?Vm:Hm;Hu.useSyncExternalStore=Is.useSyncExternalStore!==void 0?Is.useSyncExternalStore:Km;Wu.exports=Hu;var Gm=Wu.exports;/** + * @license React + * use-sync-external-store-shim/with-selector.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ji=g,Ym=Gm;function qm(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var Xm=typeof Object.is=="function"?Object.is:qm,Jm=Ym.useSyncExternalStore,Zm=Ji.useRef,Qm=Ji.useEffect,ex=Ji.useMemo,tx=Ji.useDebugValue;$u.useSyncExternalStoreWithSelector=function(e,t,r,n,s){var i=Zm(null);if(i.current===null){var o={hasValue:!1,value:null};i.current=o}else o=i.current;i=ex(function(){function c(_){if(!d){if(d=!0,u=_,_=n(_),s!==void 0&&o.hasValue){var x=o.value;if(s(x,_))return h=x}return h=_}if(x=h,Xm(u,_))return x;var f=n(_);return s!==void 0&&s(x,f)?(u=_,x):(u=_,h=f)}var d=!1,u,h,m=r===void 0?null:r;return[function(){return c(t())},m===null?void 0:function(){return c(m())}]},[t,r,n,s]);var l=Jm(e,i[0],i[1]);return Qm(function(){o.hasValue=!0,o.value=l},[l]),tx(l),l};zu.exports=$u;var rx=zu.exports;const nx=yu(rx),Vu={},{useDebugValue:sx}=Gt,{useSyncExternalStoreWithSelector:ax}=nx;let xc=!1;const ix=e=>e;function ox(e,t=ix,r){(Vu?"production":void 0)!=="production"&&r&&!xc&&(console.warn("[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"),xc=!0);const n=ax(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,r);return sx(n),n}const pc=e=>{(Vu?"production":void 0)!=="production"&&typeof e!="function"&&console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");const t=typeof e=="function"?Lm(e):e,r=(n,s)=>ox(t,n,s);return Object.assign(r,t),r},_l=e=>e?pc(e):pc,lx={};function Ku(e,t){let r;try{r=e()}catch{return}return{getItem:s=>{var i;const o=c=>c===null?null:JSON.parse(c,void 0),l=(i=r.getItem(s))!=null?i:null;return l instanceof Promise?l.then(o):o(l)},setItem:(s,i)=>r.setItem(s,JSON.stringify(i,void 0)),removeItem:s=>r.removeItem(s)}}const fa=e=>t=>{try{const r=e(t);return r instanceof Promise?r:{then(n){return fa(n)(r)},catch(n){return this}}}catch(r){return{then(n){return this},catch(n){return fa(n)(r)}}}},cx=(e,t)=>(r,n,s)=>{let i={getStorage:()=>localStorage,serialize:JSON.stringify,deserialize:JSON.parse,partialize:p=>p,version:0,merge:(p,I)=>({...I,...p}),...t},o=!1;const l=new Set,c=new Set;let d;try{d=i.getStorage()}catch{}if(!d)return e((...p)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),r(...p)},n,s);const u=fa(i.serialize),h=()=>{const p=i.partialize({...n()});let I;const S=u({state:p,version:i.version}).then(w=>d.setItem(i.name,w)).catch(w=>{I=w});if(I)throw I;return S},m=s.setState;s.setState=(p,I)=>{m(p,I),h()};const _=e((...p)=>{r(...p),h()},n,s);let x;const f=()=>{var p;if(!d)return;o=!1,l.forEach(S=>S(n()));const I=((p=i.onRehydrateStorage)==null?void 0:p.call(i,n()))||void 0;return fa(d.getItem.bind(d))(i.name).then(S=>{if(S)return i.deserialize(S)}).then(S=>{if(S)if(typeof S.version=="number"&&S.version!==i.version){if(i.migrate)return i.migrate(S.state,S.version);console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return S.state}).then(S=>{var w;return x=i.merge(S,(w=n())!=null?w:_),r(x,!0),h()}).then(()=>{I==null||I(x,void 0),o=!0,c.forEach(S=>S(x))}).catch(S=>{I==null||I(void 0,S)})};return s.persist={setOptions:p=>{i={...i,...p},p.getStorage&&(d=p.getStorage())},clearStorage:()=>{d==null||d.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>f(),hasHydrated:()=>o,onHydrate:p=>(l.add(p),()=>{l.delete(p)}),onFinishHydration:p=>(c.add(p),()=>{c.delete(p)})},f(),x||_},dx=(e,t)=>(r,n,s)=>{let i={storage:Ku(()=>localStorage),partialize:f=>f,version:0,merge:(f,p)=>({...p,...f}),...t},o=!1;const l=new Set,c=new Set;let d=i.storage;if(!d)return e((...f)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),r(...f)},n,s);const u=()=>{const f=i.partialize({...n()});return d.setItem(i.name,{state:f,version:i.version})},h=s.setState;s.setState=(f,p)=>{h(f,p),u()};const m=e((...f)=>{r(...f),u()},n,s);s.getInitialState=()=>m;let _;const x=()=>{var f,p;if(!d)return;o=!1,l.forEach(S=>{var w;return S((w=n())!=null?w:m)});const I=((p=i.onRehydrateStorage)==null?void 0:p.call(i,(f=n())!=null?f:m))||void 0;return fa(d.getItem.bind(d))(i.name).then(S=>{if(S)if(typeof S.version=="number"&&S.version!==i.version){if(i.migrate)return[!0,i.migrate(S.state,S.version)];console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return[!1,S.state];return[!1,void 0]}).then(S=>{var w;const[v,y]=S;if(_=i.merge(y,(w=n())!=null?w:m),r(_,!0),v)return u()}).then(()=>{I==null||I(_,void 0),_=n(),o=!0,c.forEach(S=>S(_))}).catch(S=>{I==null||I(void 0,S)})};return s.persist={setOptions:f=>{i={...i,...f},f.storage&&(d=f.storage)},clearStorage:()=>{d==null||d.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>x(),hasHydrated:()=>o,onHydrate:f=>(l.add(f),()=>{l.delete(f)}),onFinishHydration:f=>(c.add(f),()=>{c.delete(f)})},i.skipHydration||x(),_||m},ux=(e,t)=>"getStorage"in t||"serialize"in t||"deserialize"in t?((lx?"production":void 0)!=="production"&&console.warn("[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead."),cx(e,t)):dx(e,t),fx=ux,gc="admin_access_token",pt=_l()(fx(e=>({admin:null,permissions:null,token:null,isAuthenticated:!1,setAuth:(t,r,n)=>{sessionStorage.setItem(gc,r),e({admin:t,token:r,permissions:n??t.permissions,isAuthenticated:!0})},setAdmin:t=>e({admin:t,permissions:t.permissions}),clearAuth:()=>{sessionStorage.removeItem(gc),e({admin:null,permissions:null,token:null,isAuthenticated:!1})}}),{name:"admin-auth-storage",storage:Ku(()=>sessionStorage),partialize:e=>({admin:e.admin,permissions:e.permissions,token:e.token,isAuthenticated:e.isAuthenticated})}));function hx(){for(var e=arguments.length,t=new Array(e),r=0;rn=>{t.forEach(s=>s(n))},t)}const Zi=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function Os(e){const t=Object.prototype.toString.call(e);return t==="[object Window]"||t==="[object global]"}function vl(e){return"nodeType"in e}function _r(e){var t,r;return e?Os(e)?e:vl(e)&&(t=(r=e.ownerDocument)==null?void 0:r.defaultView)!=null?t:window:window}function yl(e){const{Document:t}=_r(e);return e instanceof t}function ja(e){return Os(e)?!1:e instanceof _r(e).HTMLElement}function Gu(e){return e instanceof _r(e).SVGElement}function Rs(e){return e?Os(e)?e.document:vl(e)?yl(e)?e:ja(e)||Gu(e)?e.ownerDocument:document:document:document}const sn=Zi?g.useLayoutEffect:g.useEffect;function wl(e){const t=g.useRef(e);return sn(()=>{t.current=e}),g.useCallback(function(){for(var r=arguments.length,n=new Array(r),s=0;s{e.current=setInterval(n,s)},[]),r=g.useCallback(()=>{e.current!==null&&(clearInterval(e.current),e.current=null)},[]);return[t,r]}function ha(e,t){t===void 0&&(t=[e]);const r=g.useRef(e);return sn(()=>{r.current!==e&&(r.current=e)},t),r}function Ia(e,t){const r=g.useRef();return g.useMemo(()=>{const n=e(r.current);return r.current=n,n},[...t])}function vi(e){const t=wl(e),r=g.useRef(null),n=g.useCallback(s=>{s!==r.current&&(t==null||t(s,r.current)),r.current=s},[]);return[r,n]}function Zo(e){const t=g.useRef();return g.useEffect(()=>{t.current=e},[e]),t.current}let yo={};function Ca(e,t){return g.useMemo(()=>{if(t)return t;const r=yo[e]==null?0:yo[e]+1;return yo[e]=r,e+"-"+r},[e,t])}function Yu(e){return function(t){for(var r=arguments.length,n=new Array(r>1?r-1:0),s=1;s{const l=Object.entries(o);for(const[c,d]of l){const u=i[c];u!=null&&(i[c]=u+e*d)}return i},{...t})}}const ys=Yu(1),yi=Yu(-1);function xx(e){return"clientX"in e&&"clientY"in e}function Sl(e){if(!e)return!1;const{KeyboardEvent:t}=_r(e.target);return t&&e instanceof t}function px(e){if(!e)return!1;const{TouchEvent:t}=_r(e.target);return t&&e instanceof t}function Qo(e){if(px(e)){if(e.touches&&e.touches.length){const{clientX:t,clientY:r}=e.touches[0];return{x:t,y:r}}else if(e.changedTouches&&e.changedTouches.length){const{clientX:t,clientY:r}=e.changedTouches[0];return{x:t,y:r}}}return xx(e)?{x:e.clientX,y:e.clientY}:null}const ma=Object.freeze({Translate:{toString(e){if(!e)return;const{x:t,y:r}=e;return"translate3d("+(t?Math.round(t):0)+"px, "+(r?Math.round(r):0)+"px, 0)"}},Scale:{toString(e){if(!e)return;const{scaleX:t,scaleY:r}=e;return"scaleX("+t+") scaleY("+r+")"}},Transform:{toString(e){if(e)return[ma.Translate.toString(e),ma.Scale.toString(e)].join(" ")}},Transition:{toString(e){let{property:t,duration:r,easing:n}=e;return t+" "+r+"ms "+n}}}),_c="a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]";function gx(e){return e.matches(_c)?e:e.querySelector(_c)}const _x={display:"none"};function vx(e){let{id:t,value:r}=e;return Gt.createElement("div",{id:t,style:_x},r)}function yx(e){let{id:t,announcement:r,ariaLiveType:n="assertive"}=e;const s={position:"fixed",top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0 0 0 0)",clipPath:"inset(100%)",whiteSpace:"nowrap"};return Gt.createElement("div",{id:t,style:s,role:"status","aria-live":n,"aria-atomic":!0},r)}function wx(){const[e,t]=g.useState("");return{announce:g.useCallback(n=>{n!=null&&t(n)},[]),announcement:e}}const qu=g.createContext(null);function Sx(e){const t=g.useContext(qu);g.useEffect(()=>{if(!t)throw new Error("useDndMonitor must be used within a children of ");return t(e)},[e,t])}function Tx(){const[e]=g.useState(()=>new Set),t=g.useCallback(n=>(e.add(n),()=>e.delete(n)),[e]);return[g.useCallback(n=>{let{type:s,event:i}=n;e.forEach(o=>{var l;return(l=o[s])==null?void 0:l.call(o,i)})},[e]),t]}const bx={draggable:` + To pick up a draggable item, press the space bar. + While dragging, use the arrow keys to move the item. + Press space again to drop the item in its new position, or press escape to cancel. + `},Ex={onDragStart(e){let{active:t}=e;return"Picked up draggable item "+t.id+"."},onDragOver(e){let{active:t,over:r}=e;return r?"Draggable item "+t.id+" was moved over droppable area "+r.id+".":"Draggable item "+t.id+" is no longer over a droppable area."},onDragEnd(e){let{active:t,over:r}=e;return r?"Draggable item "+t.id+" was dropped over droppable area "+r.id:"Draggable item "+t.id+" was dropped."},onDragCancel(e){let{active:t}=e;return"Dragging was cancelled. Draggable item "+t.id+" was dropped."}};function jx(e){let{announcements:t=Ex,container:r,hiddenTextDescribedById:n,screenReaderInstructions:s=bx}=e;const{announce:i,announcement:o}=wx(),l=Ca("DndLiveRegion"),[c,d]=g.useState(!1);if(g.useEffect(()=>{d(!0)},[]),Sx(g.useMemo(()=>({onDragStart(h){let{active:m}=h;i(t.onDragStart({active:m}))},onDragMove(h){let{active:m,over:_}=h;t.onDragMove&&i(t.onDragMove({active:m,over:_}))},onDragOver(h){let{active:m,over:_}=h;i(t.onDragOver({active:m,over:_}))},onDragEnd(h){let{active:m,over:_}=h;i(t.onDragEnd({active:m,over:_}))},onDragCancel(h){let{active:m,over:_}=h;i(t.onDragCancel({active:m,over:_}))}}),[i,t])),!c)return null;const u=Gt.createElement(Gt.Fragment,null,Gt.createElement(vx,{id:n,value:s.draggable}),Gt.createElement(yx,{id:l,announcement:o}));return r?Vn.createPortal(u,r):u}var Mt;(function(e){e.DragStart="dragStart",e.DragMove="dragMove",e.DragEnd="dragEnd",e.DragCancel="dragCancel",e.DragOver="dragOver",e.RegisterDroppable="registerDroppable",e.SetDroppableDisabled="setDroppableDisabled",e.UnregisterDroppable="unregisterDroppable"})(Mt||(Mt={}));function wi(){}function Ix(e,t){return g.useMemo(()=>({sensor:e,options:t??{}}),[e,t])}function Cx(){for(var e=arguments.length,t=new Array(e),r=0;r[...t].filter(n=>n!=null),[...t])}const Kr=Object.freeze({x:0,y:0});function Ax(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function kx(e,t){let{data:{value:r}}=e,{data:{value:n}}=t;return r-n}function Fx(e,t){let{data:{value:r}}=e,{data:{value:n}}=t;return n-r}function Ox(e,t){if(!e||e.length===0)return null;const[r]=e;return r[t]}function vc(e,t,r){return t===void 0&&(t=e.left),r===void 0&&(r=e.top),{x:t+e.width*.5,y:r+e.height*.5}}const Rx=e=>{let{collisionRect:t,droppableRects:r,droppableContainers:n}=e;const s=vc(t,t.left,t.top),i=[];for(const o of n){const{id:l}=o,c=r.get(l);if(c){const d=Ax(vc(c),s);i.push({id:l,data:{droppableContainer:o,value:d}})}}return i.sort(kx)};function Dx(e,t){const r=Math.max(t.top,e.top),n=Math.max(t.left,e.left),s=Math.min(t.left+t.width,e.left+e.width),i=Math.min(t.top+t.height,e.top+e.height),o=s-n,l=i-r;if(n{let{collisionRect:t,droppableRects:r,droppableContainers:n}=e;const s=[];for(const i of n){const{id:o}=i,l=r.get(o);if(l){const c=Dx(l,t);c>0&&s.push({id:o,data:{droppableContainer:i,value:c}})}}return s.sort(Fx)};function Nx(e,t,r){return{...e,scaleX:t&&r?t.width/r.width:1,scaleY:t&&r?t.height/r.height:1}}function Xu(e,t){return e&&t?{x:e.left-t.left,y:e.top-t.top}:Kr}function Lx(e){return function(r){for(var n=arguments.length,s=new Array(n>1?n-1:0),i=1;i({...o,top:o.top+e*l.y,bottom:o.bottom+e*l.y,left:o.left+e*l.x,right:o.right+e*l.x}),{...r})}}const Mx=Lx(1);function Bx(e){if(e.startsWith("matrix3d(")){const t=e.slice(9,-1).split(/, /);return{x:+t[12],y:+t[13],scaleX:+t[0],scaleY:+t[5]}}else if(e.startsWith("matrix(")){const t=e.slice(7,-1).split(/, /);return{x:+t[4],y:+t[5],scaleX:+t[0],scaleY:+t[3]}}return null}function Ux(e,t,r){const n=Bx(t);if(!n)return e;const{scaleX:s,scaleY:i,x:o,y:l}=n,c=e.left-o-(1-s)*parseFloat(r),d=e.top-l-(1-i)*parseFloat(r.slice(r.indexOf(" ")+1)),u=s?e.width/s:e.width,h=i?e.height/i:e.height;return{width:u,height:h,top:d,right:c+u,bottom:d+h,left:c}}const zx={ignoreTransform:!1};function Ds(e,t){t===void 0&&(t=zx);let r=e.getBoundingClientRect();if(t.ignoreTransform){const{transform:d,transformOrigin:u}=_r(e).getComputedStyle(e);d&&(r=Ux(r,d,u))}const{top:n,left:s,width:i,height:o,bottom:l,right:c}=r;return{top:n,left:s,width:i,height:o,bottom:l,right:c}}function yc(e){return Ds(e,{ignoreTransform:!0})}function $x(e){const t=e.innerWidth,r=e.innerHeight;return{top:0,left:0,right:t,bottom:r,width:t,height:r}}function Wx(e,t){return t===void 0&&(t=_r(e).getComputedStyle(e)),t.position==="fixed"}function Hx(e,t){t===void 0&&(t=_r(e).getComputedStyle(e));const r=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(s=>{const i=t[s];return typeof i=="string"?r.test(i):!1})}function Tl(e,t){const r=[];function n(s){if(t!=null&&r.length>=t||!s)return r;if(yl(s)&&s.scrollingElement!=null&&!r.includes(s.scrollingElement))return r.push(s.scrollingElement),r;if(!ja(s)||Gu(s)||r.includes(s))return r;const i=_r(e).getComputedStyle(s);return s!==e&&Hx(s,i)&&r.push(s),Wx(s,i)?r:n(s.parentNode)}return e?n(e):r}function Ju(e){const[t]=Tl(e,1);return t??null}function wo(e){return!Zi||!e?null:Os(e)?e:vl(e)?yl(e)||e===Rs(e).scrollingElement?window:ja(e)?e:null:null}function Zu(e){return Os(e)?e.scrollX:e.scrollLeft}function Qu(e){return Os(e)?e.scrollY:e.scrollTop}function el(e){return{x:Zu(e),y:Qu(e)}}var Bt;(function(e){e[e.Forward=1]="Forward",e[e.Backward=-1]="Backward"})(Bt||(Bt={}));function e0(e){return!Zi||!e?!1:e===document.scrollingElement}function t0(e){const t={x:0,y:0},r=e0(e)?{height:window.innerHeight,width:window.innerWidth}:{height:e.clientHeight,width:e.clientWidth},n={x:e.scrollWidth-r.width,y:e.scrollHeight-r.height},s=e.scrollTop<=t.y,i=e.scrollLeft<=t.x,o=e.scrollTop>=n.y,l=e.scrollLeft>=n.x;return{isTop:s,isLeft:i,isBottom:o,isRight:l,maxScroll:n,minScroll:t}}const Vx={x:.2,y:.2};function Kx(e,t,r,n,s){let{top:i,left:o,right:l,bottom:c}=r;n===void 0&&(n=10),s===void 0&&(s=Vx);const{isTop:d,isBottom:u,isLeft:h,isRight:m}=t0(e),_={x:0,y:0},x={x:0,y:0},f={height:t.height*s.y,width:t.width*s.x};return!d&&i<=t.top+f.height?(_.y=Bt.Backward,x.y=n*Math.abs((t.top+f.height-i)/f.height)):!u&&c>=t.bottom-f.height&&(_.y=Bt.Forward,x.y=n*Math.abs((t.bottom-f.height-c)/f.height)),!m&&l>=t.right-f.width?(_.x=Bt.Forward,x.x=n*Math.abs((t.right-f.width-l)/f.width)):!h&&o<=t.left+f.width&&(_.x=Bt.Backward,x.x=n*Math.abs((t.left+f.width-o)/f.width)),{direction:_,speed:x}}function Gx(e){if(e===document.scrollingElement){const{innerWidth:i,innerHeight:o}=window;return{top:0,left:0,right:i,bottom:o,width:i,height:o}}const{top:t,left:r,right:n,bottom:s}=e.getBoundingClientRect();return{top:t,left:r,right:n,bottom:s,width:e.clientWidth,height:e.clientHeight}}function r0(e){return e.reduce((t,r)=>ys(t,el(r)),Kr)}function Yx(e){return e.reduce((t,r)=>t+Zu(r),0)}function qx(e){return e.reduce((t,r)=>t+Qu(r),0)}function Xx(e,t){if(t===void 0&&(t=Ds),!e)return;const{top:r,left:n,bottom:s,right:i}=t(e);Ju(e)&&(s<=0||i<=0||r>=window.innerHeight||n>=window.innerWidth)&&e.scrollIntoView({block:"center",inline:"center"})}const Jx=[["x",["left","right"],Yx],["y",["top","bottom"],qx]];class bl{constructor(t,r){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const n=Tl(r),s=r0(n);this.rect={...t},this.width=t.width,this.height=t.height;for(const[i,o,l]of Jx)for(const c of o)Object.defineProperty(this,c,{get:()=>{const d=l(n),u=s[i]-d;return this.rect[c]+u},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class Qs{constructor(t){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(r=>{var n;return(n=this.target)==null?void 0:n.removeEventListener(...r)})},this.target=t}add(t,r,n){var s;(s=this.target)==null||s.addEventListener(t,r,n),this.listeners.push([t,r,n])}}function Zx(e){const{EventTarget:t}=_r(e);return e instanceof t?e:Rs(e)}function So(e,t){const r=Math.abs(e.x),n=Math.abs(e.y);return typeof t=="number"?Math.sqrt(r**2+n**2)>t:"x"in t&&"y"in t?r>t.x&&n>t.y:"x"in t?r>t.x:"y"in t?n>t.y:!1}var Lr;(function(e){e.Click="click",e.DragStart="dragstart",e.Keydown="keydown",e.ContextMenu="contextmenu",e.Resize="resize",e.SelectionChange="selectionchange",e.VisibilityChange="visibilitychange"})(Lr||(Lr={}));function wc(e){e.preventDefault()}function Qx(e){e.stopPropagation()}var lt;(function(e){e.Space="Space",e.Down="ArrowDown",e.Right="ArrowRight",e.Left="ArrowLeft",e.Up="ArrowUp",e.Esc="Escape",e.Enter="Enter",e.Tab="Tab"})(lt||(lt={}));const n0={start:[lt.Space,lt.Enter],cancel:[lt.Esc],end:[lt.Space,lt.Enter,lt.Tab]},ep=(e,t)=>{let{currentCoordinates:r}=t;switch(e.code){case lt.Right:return{...r,x:r.x+25};case lt.Left:return{...r,x:r.x-25};case lt.Down:return{...r,y:r.y+25};case lt.Up:return{...r,y:r.y-25}}};class s0{constructor(t){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=t;const{event:{target:r}}=t;this.props=t,this.listeners=new Qs(Rs(r)),this.windowListeners=new Qs(_r(r)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(Lr.Resize,this.handleCancel),this.windowListeners.add(Lr.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(Lr.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:t,onStart:r}=this.props,n=t.node.current;n&&Xx(n),r(Kr)}handleKeyDown(t){if(Sl(t)){const{active:r,context:n,options:s}=this.props,{keyboardCodes:i=n0,coordinateGetter:o=ep,scrollBehavior:l="smooth"}=s,{code:c}=t;if(i.end.includes(c)){this.handleEnd(t);return}if(i.cancel.includes(c)){this.handleCancel(t);return}const{collisionRect:d}=n.current,u=d?{x:d.left,y:d.top}:Kr;this.referenceCoordinates||(this.referenceCoordinates=u);const h=o(t,{active:r,context:n.current,currentCoordinates:u});if(h){const m=yi(h,u),_={x:0,y:0},{scrollableAncestors:x}=n.current;for(const f of x){const p=t.code,{isTop:I,isRight:S,isLeft:w,isBottom:v,maxScroll:y,minScroll:R}=t0(f),j=Gx(f),T={x:Math.min(p===lt.Right?j.right-j.width/2:j.right,Math.max(p===lt.Right?j.left:j.left+j.width/2,h.x)),y:Math.min(p===lt.Down?j.bottom-j.height/2:j.bottom,Math.max(p===lt.Down?j.top:j.top+j.height/2,h.y))},C=p===lt.Right&&!S||p===lt.Left&&!w,F=p===lt.Down&&!v||p===lt.Up&&!I;if(C&&T.x!==h.x){const P=f.scrollLeft+m.x,V=p===lt.Right&&P<=y.x||p===lt.Left&&P>=R.x;if(V&&!m.y){f.scrollTo({left:P,behavior:l});return}V?_.x=f.scrollLeft-P:_.x=p===lt.Right?f.scrollLeft-y.x:f.scrollLeft-R.x,_.x&&f.scrollBy({left:-_.x,behavior:l});break}else if(F&&T.y!==h.y){const P=f.scrollTop+m.y,V=p===lt.Down&&P<=y.y||p===lt.Up&&P>=R.y;if(V&&!m.x){f.scrollTo({top:P,behavior:l});return}V?_.y=f.scrollTop-P:_.y=p===lt.Down?f.scrollTop-y.y:f.scrollTop-R.y,_.y&&f.scrollBy({top:-_.y,behavior:l});break}}this.handleMove(t,ys(yi(h,this.referenceCoordinates),_))}}}handleMove(t,r){const{onMove:n}=this.props;t.preventDefault(),n(r)}handleEnd(t){const{onEnd:r}=this.props;t.preventDefault(),this.detach(),r()}handleCancel(t){const{onCancel:r}=this.props;t.preventDefault(),this.detach(),r()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}s0.activators=[{eventName:"onKeyDown",handler:(e,t,r)=>{let{keyboardCodes:n=n0,onActivation:s}=t,{active:i}=r;const{code:o}=e.nativeEvent;if(n.start.includes(o)){const l=i.activatorNode.current;return l&&e.target!==l?!1:(e.preventDefault(),s==null||s({event:e.nativeEvent}),!0)}return!1}}];function Sc(e){return!!(e&&"distance"in e)}function Tc(e){return!!(e&&"delay"in e)}class El{constructor(t,r,n){var s;n===void 0&&(n=Zx(t.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=t,this.events=r;const{event:i}=t,{target:o}=i;this.props=t,this.events=r,this.document=Rs(o),this.documentListeners=new Qs(this.document),this.listeners=new Qs(n),this.windowListeners=new Qs(_r(o)),this.initialCoordinates=(s=Qo(i))!=null?s:Kr,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:t,props:{options:{activationConstraint:r,bypassActivationConstraint:n}}}=this;if(this.listeners.add(t.move.name,this.handleMove,{passive:!1}),this.listeners.add(t.end.name,this.handleEnd),t.cancel&&this.listeners.add(t.cancel.name,this.handleCancel),this.windowListeners.add(Lr.Resize,this.handleCancel),this.windowListeners.add(Lr.DragStart,wc),this.windowListeners.add(Lr.VisibilityChange,this.handleCancel),this.windowListeners.add(Lr.ContextMenu,wc),this.documentListeners.add(Lr.Keydown,this.handleKeydown),r){if(n!=null&&n({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(Tc(r)){this.timeoutId=setTimeout(this.handleStart,r.delay),this.handlePending(r);return}if(Sc(r)){this.handlePending(r);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(t,r){const{active:n,onPending:s}=this.props;s(n,t,this.initialCoordinates,r)}handleStart(){const{initialCoordinates:t}=this,{onStart:r}=this.props;t&&(this.activated=!0,this.documentListeners.add(Lr.Click,Qx,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(Lr.SelectionChange,this.removeTextSelection),r(t))}handleMove(t){var r;const{activated:n,initialCoordinates:s,props:i}=this,{onMove:o,options:{activationConstraint:l}}=i;if(!s)return;const c=(r=Qo(t))!=null?r:Kr,d=yi(s,c);if(!n&&l){if(Sc(l)){if(l.tolerance!=null&&So(d,l.tolerance))return this.handleCancel();if(So(d,l.distance))return this.handleStart()}if(Tc(l)&&So(d,l.tolerance))return this.handleCancel();this.handlePending(l,d);return}t.cancelable&&t.preventDefault(),o(c)}handleEnd(){const{onAbort:t,onEnd:r}=this.props;this.detach(),this.activated||t(this.props.active),r()}handleCancel(){const{onAbort:t,onCancel:r}=this.props;this.detach(),this.activated||t(this.props.active),r()}handleKeydown(t){t.code===lt.Esc&&this.handleCancel()}removeTextSelection(){var t;(t=this.document.getSelection())==null||t.removeAllRanges()}}const tp={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class jl extends El{constructor(t){const{event:r}=t,n=Rs(r.target);super(t,tp,n)}}jl.activators=[{eventName:"onPointerDown",handler:(e,t)=>{let{nativeEvent:r}=e,{onActivation:n}=t;return!r.isPrimary||r.button!==0?!1:(n==null||n({event:r}),!0)}}];const rp={move:{name:"mousemove"},end:{name:"mouseup"}};var tl;(function(e){e[e.RightClick=2]="RightClick"})(tl||(tl={}));class np extends El{constructor(t){super(t,rp,Rs(t.event.target))}}np.activators=[{eventName:"onMouseDown",handler:(e,t)=>{let{nativeEvent:r}=e,{onActivation:n}=t;return r.button===tl.RightClick?!1:(n==null||n({event:r}),!0)}}];const To={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class sp extends El{constructor(t){super(t,To)}static setup(){return window.addEventListener(To.move.name,t,{capture:!1,passive:!1}),function(){window.removeEventListener(To.move.name,t)};function t(){}}}sp.activators=[{eventName:"onTouchStart",handler:(e,t)=>{let{nativeEvent:r}=e,{onActivation:n}=t;const{touches:s}=r;return s.length>1?!1:(n==null||n({event:r}),!0)}}];var ea;(function(e){e[e.Pointer=0]="Pointer",e[e.DraggableRect=1]="DraggableRect"})(ea||(ea={}));var Si;(function(e){e[e.TreeOrder=0]="TreeOrder",e[e.ReversedTreeOrder=1]="ReversedTreeOrder"})(Si||(Si={}));function ap(e){let{acceleration:t,activator:r=ea.Pointer,canScroll:n,draggingRect:s,enabled:i,interval:o=5,order:l=Si.TreeOrder,pointerCoordinates:c,scrollableAncestors:d,scrollableAncestorRects:u,delta:h,threshold:m}=e;const _=op({delta:h,disabled:!i}),[x,f]=mx(),p=g.useRef({x:0,y:0}),I=g.useRef({x:0,y:0}),S=g.useMemo(()=>{switch(r){case ea.Pointer:return c?{top:c.y,bottom:c.y,left:c.x,right:c.x}:null;case ea.DraggableRect:return s}},[r,s,c]),w=g.useRef(null),v=g.useCallback(()=>{const R=w.current;if(!R)return;const j=p.current.x*I.current.x,T=p.current.y*I.current.y;R.scrollBy(j,T)},[]),y=g.useMemo(()=>l===Si.TreeOrder?[...d].reverse():d,[l,d]);g.useEffect(()=>{if(!i||!d.length||!S){f();return}for(const R of y){if((n==null?void 0:n(R))===!1)continue;const j=d.indexOf(R),T=u[j];if(!T)continue;const{direction:C,speed:F}=Kx(R,T,S,t,m);for(const P of["x","y"])_[P][C[P]]||(F[P]=0,C[P]=0);if(F.x>0||F.y>0){f(),w.current=R,x(v,o),p.current=F,I.current=C;return}}p.current={x:0,y:0},I.current={x:0,y:0},f()},[t,v,n,f,i,o,JSON.stringify(S),JSON.stringify(_),x,d,y,u,JSON.stringify(m)])}const ip={x:{[Bt.Backward]:!1,[Bt.Forward]:!1},y:{[Bt.Backward]:!1,[Bt.Forward]:!1}};function op(e){let{delta:t,disabled:r}=e;const n=Zo(t);return Ia(s=>{if(r||!n||!s)return ip;const i={x:Math.sign(t.x-n.x),y:Math.sign(t.y-n.y)};return{x:{[Bt.Backward]:s.x[Bt.Backward]||i.x===-1,[Bt.Forward]:s.x[Bt.Forward]||i.x===1},y:{[Bt.Backward]:s.y[Bt.Backward]||i.y===-1,[Bt.Forward]:s.y[Bt.Forward]||i.y===1}}},[r,t,n])}function lp(e,t){const r=t!=null?e.get(t):void 0,n=r?r.node.current:null;return Ia(s=>{var i;return t==null?null:(i=n??s)!=null?i:null},[n,t])}function cp(e,t){return g.useMemo(()=>e.reduce((r,n)=>{const{sensor:s}=n,i=s.activators.map(o=>({eventName:o.eventName,handler:t(o.handler,n)}));return[...r,...i]},[]),[e,t])}var xa;(function(e){e[e.Always=0]="Always",e[e.BeforeDragging=1]="BeforeDragging",e[e.WhileDragging=2]="WhileDragging"})(xa||(xa={}));var rl;(function(e){e.Optimized="optimized"})(rl||(rl={}));const bc=new Map;function dp(e,t){let{dragging:r,dependencies:n,config:s}=t;const[i,o]=g.useState(null),{frequency:l,measure:c,strategy:d}=s,u=g.useRef(e),h=p(),m=ha(h),_=g.useCallback(function(I){I===void 0&&(I=[]),!m.current&&o(S=>S===null?I:S.concat(I.filter(w=>!S.includes(w))))},[m]),x=g.useRef(null),f=Ia(I=>{if(h&&!r)return bc;if(!I||I===bc||u.current!==e||i!=null){const S=new Map;for(let w of e){if(!w)continue;if(i&&i.length>0&&!i.includes(w.id)&&w.rect.current){S.set(w.id,w.rect.current);continue}const v=w.node.current,y=v?new bl(c(v),v):null;w.rect.current=y,y&&S.set(w.id,y)}return S}return I},[e,i,r,h,c]);return g.useEffect(()=>{u.current=e},[e]),g.useEffect(()=>{h||_()},[r,h]),g.useEffect(()=>{i&&i.length>0&&o(null)},[JSON.stringify(i)]),g.useEffect(()=>{h||typeof l!="number"||x.current!==null||(x.current=setTimeout(()=>{_(),x.current=null},l))},[l,h,_,...n]),{droppableRects:f,measureDroppableContainers:_,measuringScheduled:i!=null};function p(){switch(d){case xa.Always:return!1;case xa.BeforeDragging:return r;default:return!r}}}function a0(e,t){return Ia(r=>e?r||(typeof t=="function"?t(e):e):null,[t,e])}function up(e,t){return a0(e,t)}function fp(e){let{callback:t,disabled:r}=e;const n=wl(t),s=g.useMemo(()=>{if(r||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:i}=window;return new i(n)},[n,r]);return g.useEffect(()=>()=>s==null?void 0:s.disconnect(),[s]),s}function Qi(e){let{callback:t,disabled:r}=e;const n=wl(t),s=g.useMemo(()=>{if(r||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:i}=window;return new i(n)},[r]);return g.useEffect(()=>()=>s==null?void 0:s.disconnect(),[s]),s}function hp(e){return new bl(Ds(e),e)}function Ec(e,t,r){t===void 0&&(t=hp);const[n,s]=g.useState(null);function i(){s(c=>{if(!e)return null;if(e.isConnected===!1){var d;return(d=c??r)!=null?d:null}const u=t(e);return JSON.stringify(c)===JSON.stringify(u)?c:u})}const o=fp({callback(c){if(e)for(const d of c){const{type:u,target:h}=d;if(u==="childList"&&h instanceof HTMLElement&&h.contains(e)){i();break}}}}),l=Qi({callback:i});return sn(()=>{i(),e?(l==null||l.observe(e),o==null||o.observe(document.body,{childList:!0,subtree:!0})):(l==null||l.disconnect(),o==null||o.disconnect())},[e]),n}function mp(e){const t=a0(e);return Xu(e,t)}const jc=[];function xp(e){const t=g.useRef(e),r=Ia(n=>e?n&&n!==jc&&e&&t.current&&e.parentNode===t.current.parentNode?n:Tl(e):jc,[e]);return g.useEffect(()=>{t.current=e},[e]),r}function pp(e){const[t,r]=g.useState(null),n=g.useRef(e),s=g.useCallback(i=>{const o=wo(i.target);o&&r(l=>l?(l.set(o,el(o)),new Map(l)):null)},[]);return g.useEffect(()=>{const i=n.current;if(e!==i){o(i);const l=e.map(c=>{const d=wo(c);return d?(d.addEventListener("scroll",s,{passive:!0}),[d,el(d)]):null}).filter(c=>c!=null);r(l.length?new Map(l):null),n.current=e}return()=>{o(e),o(i)};function o(l){l.forEach(c=>{const d=wo(c);d==null||d.removeEventListener("scroll",s)})}},[s,e]),g.useMemo(()=>e.length?t?Array.from(t.values()).reduce((i,o)=>ys(i,o),Kr):r0(e):Kr,[e,t])}function Ic(e,t){t===void 0&&(t=[]);const r=g.useRef(null);return g.useEffect(()=>{r.current=null},t),g.useEffect(()=>{const n=e!==Kr;n&&!r.current&&(r.current=e),!n&&r.current&&(r.current=null)},[e]),r.current?yi(e,r.current):Kr}function gp(e){g.useEffect(()=>{if(!Zi)return;const t=e.map(r=>{let{sensor:n}=r;return n.setup==null?void 0:n.setup()});return()=>{for(const r of t)r==null||r()}},e.map(t=>{let{sensor:r}=t;return r}))}function _p(e,t){return g.useMemo(()=>e.reduce((r,n)=>{let{eventName:s,handler:i}=n;return r[s]=o=>{i(o,t)},r},{}),[e,t])}function i0(e){return g.useMemo(()=>e?$x(e):null,[e])}const Cc=[];function vp(e,t){t===void 0&&(t=Ds);const[r]=e,n=i0(r?_r(r):null),[s,i]=g.useState(Cc);function o(){i(()=>e.length?e.map(c=>e0(c)?n:new bl(t(c),c)):Cc)}const l=Qi({callback:o});return sn(()=>{l==null||l.disconnect(),o(),e.forEach(c=>l==null?void 0:l.observe(c))},[e]),s}function yp(e){if(!e)return null;if(e.children.length>1)return e;const t=e.children[0];return ja(t)?t:e}function wp(e){let{measure:t}=e;const[r,n]=g.useState(null),s=g.useCallback(d=>{for(const{target:u}of d)if(ja(u)){n(h=>{const m=t(u);return h?{...h,width:m.width,height:m.height}:m});break}},[t]),i=Qi({callback:s}),o=g.useCallback(d=>{const u=yp(d);i==null||i.disconnect(),u&&(i==null||i.observe(u)),n(u?t(u):null)},[t,i]),[l,c]=vi(o);return g.useMemo(()=>({nodeRef:l,rect:r,setRef:c}),[r,l,c])}const Sp=[{sensor:jl,options:{}},{sensor:s0,options:{}}],Tp={current:{}},di={draggable:{measure:yc},droppable:{measure:yc,strategy:xa.WhileDragging,frequency:rl.Optimized},dragOverlay:{measure:Ds}};class ta extends Map{get(t){var r;return t!=null&&(r=super.get(t))!=null?r:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(t=>{let{disabled:r}=t;return!r})}getNodeFor(t){var r,n;return(r=(n=this.get(t))==null?void 0:n.node.current)!=null?r:void 0}}const bp={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new ta,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:wi},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:di,measureDroppableContainers:wi,windowRect:null,measuringScheduled:!1},Ep={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:wi,draggableNodes:new Map,over:null,measureDroppableContainers:wi},eo=g.createContext(Ep),o0=g.createContext(bp);function jp(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new ta}}}function Ip(e,t){switch(t.type){case Mt.DragStart:return{...e,draggable:{...e.draggable,initialCoordinates:t.initialCoordinates,active:t.active}};case Mt.DragMove:return e.draggable.active==null?e:{...e,draggable:{...e.draggable,translate:{x:t.coordinates.x-e.draggable.initialCoordinates.x,y:t.coordinates.y-e.draggable.initialCoordinates.y}}};case Mt.DragEnd:case Mt.DragCancel:return{...e,draggable:{...e.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case Mt.RegisterDroppable:{const{element:r}=t,{id:n}=r,s=new ta(e.droppable.containers);return s.set(n,r),{...e,droppable:{...e.droppable,containers:s}}}case Mt.SetDroppableDisabled:{const{id:r,key:n,disabled:s}=t,i=e.droppable.containers.get(r);if(!i||n!==i.key)return e;const o=new ta(e.droppable.containers);return o.set(r,{...i,disabled:s}),{...e,droppable:{...e.droppable,containers:o}}}case Mt.UnregisterDroppable:{const{id:r,key:n}=t,s=e.droppable.containers.get(r);if(!s||n!==s.key)return e;const i=new ta(e.droppable.containers);return i.delete(r),{...e,droppable:{...e.droppable,containers:i}}}default:return e}}function Cp(e){let{disabled:t}=e;const{active:r,activatorEvent:n,draggableNodes:s}=g.useContext(eo),i=Zo(n),o=Zo(r==null?void 0:r.id);return g.useEffect(()=>{if(!t&&!n&&i&&o!=null){if(!Sl(i)||document.activeElement===i.target)return;const l=s.get(o);if(!l)return;const{activatorNode:c,node:d}=l;if(!c.current&&!d.current)return;requestAnimationFrame(()=>{for(const u of[c.current,d.current]){if(!u)continue;const h=gx(u);if(h){h.focus();break}}})}},[n,t,s,o,i]),null}function Ap(e,t){let{transform:r,...n}=t;return e!=null&&e.length?e.reduce((s,i)=>i({transform:s,...n}),r):r}function kp(e){return g.useMemo(()=>({draggable:{...di.draggable,...e==null?void 0:e.draggable},droppable:{...di.droppable,...e==null?void 0:e.droppable},dragOverlay:{...di.dragOverlay,...e==null?void 0:e.dragOverlay}}),[e==null?void 0:e.draggable,e==null?void 0:e.droppable,e==null?void 0:e.dragOverlay])}function Fp(e){let{activeNode:t,measure:r,initialRect:n,config:s=!0}=e;const i=g.useRef(!1),{x:o,y:l}=typeof s=="boolean"?{x:s,y:s}:s;sn(()=>{if(!o&&!l||!t){i.current=!1;return}if(i.current||!n)return;const d=t==null?void 0:t.node.current;if(!d||d.isConnected===!1)return;const u=r(d),h=Xu(u,n);if(o||(h.x=0),l||(h.y=0),i.current=!0,Math.abs(h.x)>0||Math.abs(h.y)>0){const m=Ju(d);m&&m.scrollBy({top:h.y,left:h.x})}},[t,o,l,n,r])}const l0=g.createContext({...Kr,scaleX:1,scaleY:1});var kn;(function(e){e[e.Uninitialized=0]="Uninitialized",e[e.Initializing=1]="Initializing",e[e.Initialized=2]="Initialized"})(kn||(kn={}));const Op=g.memo(function(t){var r,n,s,i;let{id:o,accessibility:l,autoScroll:c=!0,children:d,sensors:u=Sp,collisionDetection:h=Px,measuring:m,modifiers:_,...x}=t;const f=g.useReducer(Ip,void 0,jp),[p,I]=f,[S,w]=Tx(),[v,y]=g.useState(kn.Uninitialized),R=v===kn.Initialized,{draggable:{active:j,nodes:T,translate:C},droppable:{containers:F}}=p,P=j!=null?T.get(j):null,V=g.useRef({initial:null,translated:null}),X=g.useMemo(()=>{var St;return j!=null?{id:j,data:(St=P==null?void 0:P.data)!=null?St:Tp,rect:V}:null},[j,P]),_e=g.useRef(null),[B,te]=g.useState(null),[J,G]=g.useState(null),se=ha(x,Object.values(x)),Q=Ca("DndDescribedBy",o),de=g.useMemo(()=>F.getEnabled(),[F]),k=kp(m),{droppableRects:W,measureDroppableContainers:z,measuringScheduled:D}=dp(de,{dragging:R,dependencies:[C.x,C.y],config:k.droppable}),q=lp(T,j),K=g.useMemo(()=>J?Qo(J):null,[J]),Z=En(),me=up(q,k.draggable.measure);Fp({activeNode:j!=null?T.get(j):null,config:Z.layoutShiftCompensation,initialRect:me,measure:k.draggable.measure});const ie=Ec(q,k.draggable.measure,me),he=Ec(q?q.parentElement:null),we=g.useRef({activatorEvent:null,active:null,activeNode:q,collisionRect:null,collisions:null,droppableRects:W,draggableNodes:T,draggingNode:null,draggingNodeRect:null,droppableContainers:F,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),He=F.getNodeFor((r=we.current.over)==null?void 0:r.id),ze=wp({measure:k.dragOverlay.measure}),gt=(n=ze.nodeRef.current)!=null?n:q,qe=R?(s=ze.rect)!=null?s:ie:null,le=!!(ze.nodeRef.current&&ze.rect),fe=mp(le?null:ie),Re=i0(gt?_r(gt):null),Ue=xp(R?He??q:null),nt=vp(Ue),Tt=Ap(_,{transform:{x:C.x-fe.x,y:C.y-fe.y,scaleX:1,scaleY:1},activatorEvent:J,active:X,activeNodeRect:ie,containerNodeRect:he,draggingNodeRect:qe,over:we.current.over,overlayNodeRect:ze.rect,scrollableAncestors:Ue,scrollableAncestorRects:nt,windowRect:Re}),yt=K?ys(K,C):null,De=pp(Ue),Ce=Ic(De),Qe=Ic(De,[ie]),Xe=ys(Tt,Ce),Je=qe?Mx(qe,Tt):null,xe=X&&Je?h({active:X,collisionRect:Je,droppableRects:W,droppableContainers:de,pointerCoordinates:yt}):null,ke=Ox(xe,"id"),[et,_t]=g.useState(null),Wt=le?Tt:ys(Tt,Qe),Sn=Nx(Wt,(i=et==null?void 0:et.rect)!=null?i:null,ie),cr=g.useRef(null),as=g.useCallback((St,st)=>{let{sensor:kt,options:dr}=st;if(_e.current==null)return;const Qt=T.get(_e.current);if(!Qt)return;const Ht=St.nativeEvent,ur=new kt({active:_e.current,activeNode:Qt,event:Ht,options:dr,context:we,onAbort(It){if(!T.get(It))return;const{onDragAbort:er}=se.current,vr={id:It};er==null||er(vr),S({type:"onDragAbort",event:vr})},onPending(It,Fr,er,vr){if(!T.get(It))return;const{onDragPending:ln}=se.current,A={id:It,constraint:Fr,initialCoordinates:er,offset:vr};ln==null||ln(A),S({type:"onDragPending",event:A})},onStart(It){const Fr=_e.current;if(Fr==null)return;const er=T.get(Fr);if(!er)return;const{onDragStart:vr}=se.current,on={activatorEvent:Ht,active:{id:Fr,data:er.data,rect:V}};Vn.unstable_batchedUpdates(()=>{vr==null||vr(on),y(kn.Initializing),I({type:Mt.DragStart,initialCoordinates:It,active:Fr}),S({type:"onDragStart",event:on}),te(cr.current),G(Ht)})},onMove(It){I({type:Mt.DragMove,coordinates:It})},onEnd:Xr(Mt.DragEnd),onCancel:Xr(Mt.DragCancel)});cr.current=ur;function Xr(It){return async function(){const{active:er,collisions:vr,over:on,scrollAdjustedTranslate:ln}=we.current;let A=null;if(er&&ln){const{cancelDrop:L}=se.current;A={activatorEvent:Ht,active:er,collisions:vr,delta:ln,over:on},It===Mt.DragEnd&&typeof L=="function"&&await Promise.resolve(L(A))&&(It=Mt.DragCancel)}_e.current=null,Vn.unstable_batchedUpdates(()=>{I({type:It}),y(kn.Uninitialized),_t(null),te(null),G(null),cr.current=null;const L=It===Mt.DragEnd?"onDragEnd":"onDragCancel";if(A){const O=se.current[L];O==null||O(A),S({type:L,event:A})}})}}},[T]),Tn=g.useCallback((St,st)=>(kt,dr)=>{const Qt=kt.nativeEvent,Ht=T.get(dr);if(_e.current!==null||!Ht||Qt.dndKit||Qt.defaultPrevented)return;const ur={active:Ht};St(kt,st.options,ur)===!0&&(Qt.dndKit={capturedBy:st.sensor},_e.current=dr,as(kt,st))},[T,as]),kr=cp(u,Tn);gp(u),sn(()=>{ie&&v===kn.Initializing&&y(kn.Initialized)},[ie,v]),g.useEffect(()=>{const{onDragMove:St}=se.current,{active:st,activatorEvent:kt,collisions:dr,over:Qt}=we.current;if(!st||!kt)return;const Ht={active:st,activatorEvent:kt,collisions:dr,delta:{x:Xe.x,y:Xe.y},over:Qt};Vn.unstable_batchedUpdates(()=>{St==null||St(Ht),S({type:"onDragMove",event:Ht})})},[Xe.x,Xe.y]),g.useEffect(()=>{const{active:St,activatorEvent:st,collisions:kt,droppableContainers:dr,scrollAdjustedTranslate:Qt}=we.current;if(!St||_e.current==null||!st||!Qt)return;const{onDragOver:Ht}=se.current,ur=dr.get(ke),Xr=ur&&ur.rect.current?{id:ur.id,rect:ur.rect.current,data:ur.data,disabled:ur.disabled}:null,It={active:St,activatorEvent:st,collisions:kt,delta:{x:Qt.x,y:Qt.y},over:Xr};Vn.unstable_batchedUpdates(()=>{_t(Xr),Ht==null||Ht(It),S({type:"onDragOver",event:It})})},[ke]),sn(()=>{we.current={activatorEvent:J,active:X,activeNode:q,collisionRect:Je,collisions:xe,droppableRects:W,draggableNodes:T,draggingNode:gt,draggingNodeRect:qe,droppableContainers:F,over:et,scrollableAncestors:Ue,scrollAdjustedTranslate:Xe},V.current={initial:qe,translated:Je}},[X,q,xe,Je,T,gt,qe,W,F,et,Ue,Xe]),ap({...Z,delta:C,draggingRect:Je,pointerCoordinates:yt,scrollableAncestors:Ue,scrollableAncestorRects:nt});const qr=g.useMemo(()=>({active:X,activeNode:q,activeNodeRect:ie,activatorEvent:J,collisions:xe,containerNodeRect:he,dragOverlay:ze,draggableNodes:T,droppableContainers:F,droppableRects:W,over:et,measureDroppableContainers:z,scrollableAncestors:Ue,scrollableAncestorRects:nt,measuringConfiguration:k,measuringScheduled:D,windowRect:Re}),[X,q,ie,J,xe,he,ze,T,F,W,et,z,Ue,nt,k,D,Re]),bn=g.useMemo(()=>({activatorEvent:J,activators:kr,active:X,activeNodeRect:ie,ariaDescribedById:{draggable:Q},dispatch:I,draggableNodes:T,over:et,measureDroppableContainers:z}),[J,kr,X,ie,I,Q,T,et,z]);return Gt.createElement(qu.Provider,{value:w},Gt.createElement(eo.Provider,{value:bn},Gt.createElement(o0.Provider,{value:qr},Gt.createElement(l0.Provider,{value:Sn},d)),Gt.createElement(Cp,{disabled:(l==null?void 0:l.restoreFocus)===!1})),Gt.createElement(jx,{...l,hiddenTextDescribedById:Q}));function En(){const St=(B==null?void 0:B.autoScrollEnabled)===!1,st=typeof c=="object"?c.enabled===!1:c===!1,kt=R&&!St&&!st;return typeof c=="object"?{...c,enabled:kt}:{enabled:kt}}}),Rp=g.createContext(null),Ac="button",Dp="Draggable";function Pp(e){let{id:t,data:r,disabled:n=!1,attributes:s}=e;const i=Ca(Dp),{activators:o,activatorEvent:l,active:c,activeNodeRect:d,ariaDescribedById:u,draggableNodes:h,over:m}=g.useContext(eo),{role:_=Ac,roleDescription:x="draggable",tabIndex:f=0}=s??{},p=(c==null?void 0:c.id)===t,I=g.useContext(p?l0:Rp),[S,w]=vi(),[v,y]=vi(),R=_p(o,t),j=ha(r);sn(()=>(h.set(t,{id:t,key:i,node:S,activatorNode:v,data:j}),()=>{const C=h.get(t);C&&C.key===i&&h.delete(t)}),[h,t]);const T=g.useMemo(()=>({role:_,tabIndex:f,"aria-disabled":n,"aria-pressed":p&&_===Ac?!0:void 0,"aria-roledescription":x,"aria-describedby":u.draggable}),[n,_,f,p,x,u.draggable]);return{active:c,activatorEvent:l,activeNodeRect:d,attributes:T,isDragging:p,listeners:n?void 0:R,node:S,over:m,setNodeRef:w,setActivatorNodeRef:y,transform:I}}function Np(){return g.useContext(o0)}const Lp="Droppable",Mp={timeout:25};function Bp(e){let{data:t,disabled:r=!1,id:n,resizeObserverConfig:s}=e;const i=Ca(Lp),{active:o,dispatch:l,over:c,measureDroppableContainers:d}=g.useContext(eo),u=g.useRef({disabled:r}),h=g.useRef(!1),m=g.useRef(null),_=g.useRef(null),{disabled:x,updateMeasurementsFor:f,timeout:p}={...Mp,...s},I=ha(f??n),S=g.useCallback(()=>{if(!h.current){h.current=!0;return}_.current!=null&&clearTimeout(_.current),_.current=setTimeout(()=>{d(Array.isArray(I.current)?I.current:[I.current]),_.current=null},p)},[p]),w=Qi({callback:S,disabled:x||!o}),v=g.useCallback((T,C)=>{w&&(C&&(w.unobserve(C),h.current=!1),T&&w.observe(T))},[w]),[y,R]=vi(v),j=ha(t);return g.useEffect(()=>{!w||!y.current||(w.disconnect(),h.current=!1,w.observe(y.current))},[y,w]),g.useEffect(()=>(l({type:Mt.RegisterDroppable,element:{id:n,key:i,disabled:r,node:y,rect:m,data:j}}),()=>l({type:Mt.UnregisterDroppable,key:i,id:n})),[n]),g.useEffect(()=>{r!==u.current.disabled&&(l({type:Mt.SetDroppableDisabled,id:n,key:i,disabled:r}),u.current.disabled=r)},[n,i,r,l]),{active:o,rect:m,isOver:(c==null?void 0:c.id)===n,node:y,over:c,setNodeRef:R}}function Il(e,t,r){const n=e.slice();return n.splice(r<0?n.length+r:r,0,n.splice(t,1)[0]),n}function Up(e,t){return e.reduce((r,n,s)=>{const i=t.get(n);return i&&(r[s]=i),r},Array(e.length))}function Ua(e){return e!==null&&e>=0}function zp(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let r=0;r{var t;let{rects:r,activeNodeRect:n,activeIndex:s,overIndex:i,index:o}=e;const l=(t=r[s])!=null?t:n;if(!l)return null;const c=Hp(r,o,s);if(o===s){const d=r[i];return d?{x:ss&&o<=i?{x:-l.width-c,y:0,...za}:o=i?{x:l.width+c,y:0,...za}:{x:0,y:0,...za}};function Hp(e,t,r){const n=e[t],s=e[t-1],i=e[t+1];return!n||!s&&!i?0:r{let{rects:t,activeIndex:r,overIndex:n,index:s}=e;const i=Il(t,n,r),o=t[s],l=i[s];return!l||!o?null:{x:l.left-o.left,y:l.top-o.top,scaleX:l.width/o.width,scaleY:l.height/o.height}},d0="Sortable",u0=Gt.createContext({activeIndex:-1,containerId:d0,disableTransforms:!1,items:[],overIndex:-1,useDragOverlay:!1,sortedRects:[],strategy:c0,disabled:{draggable:!1,droppable:!1}});function Vp(e){let{children:t,id:r,items:n,strategy:s=c0,disabled:i=!1}=e;const{active:o,dragOverlay:l,droppableRects:c,over:d,measureDroppableContainers:u}=Np(),h=Ca(d0,r),m=l.rect!==null,_=g.useMemo(()=>n.map(R=>typeof R=="object"&&"id"in R?R.id:R),[n]),x=o!=null,f=o?_.indexOf(o.id):-1,p=d?_.indexOf(d.id):-1,I=g.useRef(_),S=!zp(_,I.current),w=p!==-1&&f===-1||S,v=$p(i);sn(()=>{S&&x&&u(_)},[S,_,x,u]),g.useEffect(()=>{I.current=_},[_]);const y=g.useMemo(()=>({activeIndex:f,containerId:h,disabled:v,disableTransforms:w,items:_,overIndex:p,useDragOverlay:m,sortedRects:Up(_,c),strategy:s}),[f,h,v.draggable,v.droppable,w,_,p,c,m,s]);return Gt.createElement(u0.Provider,{value:y},t)}const Kp=e=>{let{id:t,items:r,activeIndex:n,overIndex:s}=e;return Il(r,n,s).indexOf(t)},Gp=e=>{let{containerId:t,isSorting:r,wasDragging:n,index:s,items:i,newIndex:o,previousItems:l,previousContainerId:c,transition:d}=e;return!d||!n||l!==i&&s===o?!1:r?!0:o!==s&&t===c},Yp={duration:200,easing:"ease"},f0="transform",qp=ma.Transition.toString({property:f0,duration:0,easing:"linear"}),Xp={roleDescription:"sortable"};function Jp(e){let{disabled:t,index:r,node:n,rect:s}=e;const[i,o]=g.useState(null),l=g.useRef(r);return sn(()=>{if(!t&&r!==l.current&&n.current){const c=s.current;if(c){const d=Ds(n.current,{ignoreTransform:!0}),u={x:c.left-d.left,y:c.top-d.top,scaleX:c.width/d.width,scaleY:c.height/d.height};(u.x||u.y)&&o(u)}}r!==l.current&&(l.current=r)},[t,r,n,s]),g.useEffect(()=>{i&&o(null)},[i]),i}function Zp(e){let{animateLayoutChanges:t=Gp,attributes:r,disabled:n,data:s,getNewIndex:i=Kp,id:o,strategy:l,resizeObserverConfig:c,transition:d=Yp}=e;const{items:u,containerId:h,activeIndex:m,disabled:_,disableTransforms:x,sortedRects:f,overIndex:p,useDragOverlay:I,strategy:S}=g.useContext(u0),w=Qp(n,_),v=u.indexOf(o),y=g.useMemo(()=>({sortable:{containerId:h,index:v,items:u},...s}),[h,s,v,u]),R=g.useMemo(()=>u.slice(u.indexOf(o)),[u,o]),{rect:j,node:T,isOver:C,setNodeRef:F}=Bp({id:o,data:y,disabled:w.droppable,resizeObserverConfig:{updateMeasurementsFor:R,...c}}),{active:P,activatorEvent:V,activeNodeRect:X,attributes:_e,setNodeRef:B,listeners:te,isDragging:J,over:G,setActivatorNodeRef:se,transform:Q}=Pp({id:o,data:y,attributes:{...Xp,...r},disabled:w.draggable}),de=hx(F,B),k=!!P,W=k&&!x&&Ua(m)&&Ua(p),z=!I&&J,D=z&&W?Q:null,K=W?D??(l??S)({rects:f,activeNodeRect:X,activeIndex:m,overIndex:p,index:v}):null,Z=Ua(m)&&Ua(p)?i({id:o,items:u,activeIndex:m,overIndex:p}):v,me=P==null?void 0:P.id,ie=g.useRef({activeId:me,items:u,newIndex:Z,containerId:h}),he=u!==ie.current.items,we=t({active:P,containerId:h,isDragging:J,isSorting:k,id:o,index:v,items:u,newIndex:ie.current.newIndex,previousItems:ie.current.items,previousContainerId:ie.current.containerId,transition:d,wasDragging:ie.current.activeId!=null}),He=Jp({disabled:!we,index:v,node:T,rect:j});return g.useEffect(()=>{k&&ie.current.newIndex!==Z&&(ie.current.newIndex=Z),h!==ie.current.containerId&&(ie.current.containerId=h),u!==ie.current.items&&(ie.current.items=u)},[k,Z,h,u]),g.useEffect(()=>{if(me===ie.current.activeId)return;if(me!=null&&ie.current.activeId==null){ie.current.activeId=me;return}const gt=setTimeout(()=>{ie.current.activeId=me},50);return()=>clearTimeout(gt)},[me]),{active:P,activeIndex:m,attributes:_e,data:y,rect:j,index:v,newIndex:Z,items:u,isOver:C,isSorting:k,isDragging:J,listeners:te,node:T,overIndex:p,over:G,setNodeRef:de,setActivatorNodeRef:se,setDroppableNodeRef:F,setDraggableNodeRef:B,transform:He??K,transition:ze()};function ze(){if(He||he&&ie.current.newIndex===v)return qp;if(!(z&&!Sl(V)||!d)&&(k||we))return ma.Transition.toString({...d,property:f0})}}function Qp(e,t){var r,n;return typeof e=="boolean"?{draggable:e,droppable:!1}:{draggable:(r=e==null?void 0:e.draggable)!=null?r:t.draggable,droppable:(n=e==null?void 0:e.droppable)!=null?n:t.droppable}}lt.Down,lt.Right,lt.Up,lt.Left;function Cl(e){return e==null}function h0(e){return Object.prototype.toString.call(e)==="[object RegExp]"}function nl(e){return Array.isArray(e)}function sl(e){return typeof e=="function"}function m0(e){return{set:(t,r)=>(e.setAttribute(t,r),m0(e))}}function kc(e=100){let t;return new Promise((r,n)=>{t=setTimeout(()=>{r(),Cl(t)||clearTimeout(t)},e)})}function Fc(e,t){return(nl(e)?e:Cl(e)?[]:[e]).some(r=>h0(r)?r.test(t):t===r)}function bo(e){setTimeout(e,0)}var e1=g.createContext({active:!1,refresh:()=>{},destroy:()=>Promise.resolve(),destroyAll:()=>Promise.resolve(),destroyOther:()=>Promise.resolve(),getCacheNodes:()=>[]}),t1=g.memo(function(e){let{children:t,active:r,refresh:n,destroy:s,destroyAll:i,destroyOther:o,getCacheNodes:l}=e,c=g.useMemo(()=>({active:r,refresh:n,destroy:s,destroyAll:i,destroyOther:o,getCacheNodes:l}),[r,n,s,i,o,l]);return a.jsx(e1.Provider,{value:c,children:t})}),r1=t1,x0=g.Activity,n1=x0??g.Fragment,s1=!!x0,p0="keepalive-cache-div";function g0(e){return e?Array.from(e.children):[]}function al(e){e.forEach(t=>{t.classList.contains(p0)&&t.remove()})}function Oc(e,t){let r=g0(e);al(r),e.appendChild(t),t.classList.remove("inactive"),t.classList.add("active")}function Rc(e,t){let r=g0(e).filter(n=>n.classList.contains("active")&&n.getAttribute("data-cache-key")!==t);return r.forEach(n=>{n.classList.remove("active"),n.classList.add("inactive")}),r}function a1(e,t,r){return r?Fc(r,e):t?!Fc(t,e):!0}var i1=g.memo(function(e){let{errorElement:t=g.Fragment,cacheNodeClassName:r,children:n,cacheKey:s,exclude:i,include:o,enableActivity:l}=e,{active:c,renderCount:d,destroy:u,transition:h,viewTransition:m,duration:_,containerDivRef:x}=e,f=g.useRef(!1);f.current=f.current||c;let p=g.useMemo(()=>{let I=document.createElement("div");return m0(I).set("data-cache-key",s).set("style","height: 100%").set("data-render-count",d.toString()),I.className=p0+(r?` ${r}`:""),I},[d,r]);return g.useEffect(()=>{let I=a1(s,i,o),S=x.current;if(!S){console.warn("keepalive: cache container not found");return}if(h)(async()=>{if(c){let w=Rc(S,s);if(await kc(_-40),al(w),S.contains(p))return;Oc(S,p)}else I||(await kc(_),u(s))})();else if(c){let w=()=>{let v=Rc(S,s);al(v),!S.contains(p)&&Oc(S,p)};m&&document.startViewTransition?document.startViewTransition(w):w()}else I||u(s)},[c,x,s,i,o]),f.current?Vn.createPortal(a.jsx(t,{children:s1&&l?a.jsxs(n1,{mode:c?"visible":"hidden",children:[" ",n]}):n}),p,s):null},(e,t)=>e.active===t.active&&e.renderCount===t.renderCount&&e.children===t.children&&e.exclude===t.exclude&&e.include===t.include),o1=i1,l1=e=>{typeof g.startTransition<"u"&&sl(g.startTransition)?g.startTransition(e):e()},c1=l1;function d1(){return g.useRef(null)}function u1(e){let{activeCacheKey:t,max:r=10,exclude:n,include:s,onBeforeActive:i,customContainerRef:o,cacheNodeClassName:l="cache-component",containerClassName:c="keep-alive-render",errorElement:d,transition:u=!1,viewTransition:h=!1,duration:m=200,children:_,aliveRef:x,maxAliveTime:f=0,enableActivity:p=!1}=e,I=o||g.useRef(null),[S,w]=g.useState([]);g.useLayoutEffect(()=>{Cl(t)||c1(()=>{w(C=>{let F=Date.now();if(C.find(P=>P.cacheKey===t))return C.map(P=>{if(P.cacheKey===t){let V=!1;if(sl(i)&&i(t),f){let X=P.lastActiveTime;if(nl(f)){let _e=f.find(B=>h0(B.match)?B.match.test(t):B.match===t);_e&&(V=_e&&X+_e.expire*1e3r){let P=C.reduce((V,X)=>V.lastActiveTime{w(F=>{let P=C||t;return F.map(V=>V.cacheKey===P?{...V,renderCount:V.renderCount+1}:V)})},[w,t]),y=g.useCallback(C=>{let F=C||t,P=nl(F)?F:[F];return new Promise(V=>{bo(()=>{w(X=>[...X.filter(_e=>!P.includes(_e.cacheKey))]),V()})})},[w,t]),R=g.useCallback(()=>new Promise(C=>{bo(()=>{w([]),C()})}),[w]),j=g.useCallback(C=>{let F=C||t;return new Promise(P=>{bo(()=>{w(V=>[...V.filter(X=>X.cacheKey===F)]),P()})})},[t,w]),T=g.useCallback(()=>S,[S]);return g.useImperativeHandle(x,()=>({refresh:v,destroy:y,destroyAll:R,destroyOther:j,getCacheNodes:T})),a.jsxs(g.Fragment,{children:[a.jsx("div",{ref:I,className:c,style:{height:"100%"}}),S.map(C=>{let{cacheKey:F,ele:P,renderCount:V}=C;return a.jsx(r1,{active:t===F,refresh:v,destroy:y,destroyAll:R,destroyOther:j,getCacheNodes:T,children:a.jsx(o1,{destroy:y,include:s,exclude:n,transition:u,viewTransition:h,duration:m,renderCount:V,containerDivRef:I,errorElement:d,active:t===F,cacheNodeClassName:l,cacheKey:F,enableActivity:p,children:P})},`${F}-${V}`)})]})}var f1=u1;function _0(e,t){return function(){return e.apply(t,arguments)}}const{toString:h1}=Object.prototype,{getPrototypeOf:Al}=Object,{iterator:to,toStringTag:v0}=Symbol,ro=(e=>t=>{const r=h1.call(t);return e[r]||(e[r]=r.slice(8,-1).toLowerCase())})(Object.create(null)),Gr=e=>(e=e.toLowerCase(),t=>ro(t)===e),no=e=>t=>typeof t===e,{isArray:Ps}=Array,Cs=no("undefined");function Aa(e){return e!==null&&!Cs(e)&&e.constructor!==null&&!Cs(e.constructor)&&hr(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const y0=Gr("ArrayBuffer");function m1(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&y0(e.buffer),t}const x1=no("string"),hr=no("function"),w0=no("number"),ka=e=>e!==null&&typeof e=="object",p1=e=>e===!0||e===!1,ui=e=>{if(ro(e)!=="object")return!1;const t=Al(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(v0 in e)&&!(to in e)},g1=e=>{if(!ka(e)||Aa(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},_1=Gr("Date"),v1=Gr("File"),y1=Gr("Blob"),w1=Gr("FileList"),S1=e=>ka(e)&&hr(e.pipe),T1=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||hr(e.append)&&((t=ro(e))==="formdata"||t==="object"&&hr(e.toString)&&e.toString()==="[object FormData]"))},b1=Gr("URLSearchParams"),[E1,j1,I1,C1]=["ReadableStream","Request","Response","Headers"].map(Gr),A1=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function Fa(e,t,{allOwnKeys:r=!1}={}){if(e===null||typeof e>"u")return;let n,s;if(typeof e!="object"&&(e=[e]),Ps(e))for(n=0,s=e.length;n0;)if(s=r[n],t===s.toLowerCase())return s;return null}const Kn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,T0=e=>!Cs(e)&&e!==Kn;function il(){const{caseless:e,skipUndefined:t}=T0(this)&&this||{},r={},n=(s,i)=>{const o=e&&S0(r,i)||i;ui(r[o])&&ui(s)?r[o]=il(r[o],s):ui(s)?r[o]=il({},s):Ps(s)?r[o]=s.slice():(!t||!Cs(s))&&(r[o]=s)};for(let s=0,i=arguments.length;s(Fa(t,(s,i)=>{r&&hr(s)?Object.defineProperty(e,i,{value:_0(s,r),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(e,i,{value:s,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:n}),e),F1=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),O1=(e,t,r,n)=>{e.prototype=Object.create(t.prototype,n),Object.defineProperty(e.prototype,"constructor",{value:e,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(e,"super",{value:t.prototype}),r&&Object.assign(e.prototype,r)},R1=(e,t,r,n)=>{let s,i,o;const l={};if(t=t||{},e==null)return t;do{for(s=Object.getOwnPropertyNames(e),i=s.length;i-- >0;)o=s[i],(!n||n(o,e,t))&&!l[o]&&(t[o]=e[o],l[o]=!0);e=r!==!1&&Al(e)}while(e&&(!r||r(e,t))&&e!==Object.prototype);return t},D1=(e,t,r)=>{e=String(e),(r===void 0||r>e.length)&&(r=e.length),r-=t.length;const n=e.indexOf(t,r);return n!==-1&&n===r},P1=e=>{if(!e)return null;if(Ps(e))return e;let t=e.length;if(!w0(t))return null;const r=new Array(t);for(;t-- >0;)r[t]=e[t];return r},N1=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&Al(Uint8Array)),L1=(e,t)=>{const n=(e&&e[to]).call(e);let s;for(;(s=n.next())&&!s.done;){const i=s.value;t.call(e,i[0],i[1])}},M1=(e,t)=>{let r;const n=[];for(;(r=e.exec(t))!==null;)n.push(r);return n},B1=Gr("HTMLFormElement"),U1=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(r,n,s){return n.toUpperCase()+s}),Dc=(({hasOwnProperty:e})=>(t,r)=>e.call(t,r))(Object.prototype),z1=Gr("RegExp"),b0=(e,t)=>{const r=Object.getOwnPropertyDescriptors(e),n={};Fa(r,(s,i)=>{let o;(o=t(s,i,e))!==!1&&(n[i]=o||s)}),Object.defineProperties(e,n)},$1=e=>{b0(e,(t,r)=>{if(hr(e)&&["arguments","caller","callee"].indexOf(r)!==-1)return!1;const n=e[r];if(hr(n)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+r+"'")})}})},W1=(e,t)=>{const r={},n=s=>{s.forEach(i=>{r[i]=!0})};return Ps(e)?n(e):n(String(e).split(t)),r},H1=()=>{},V1=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function K1(e){return!!(e&&hr(e.append)&&e[v0]==="FormData"&&e[to])}const G1=e=>{const t=new Array(10),r=(n,s)=>{if(ka(n)){if(t.indexOf(n)>=0)return;if(Aa(n))return n;if(!("toJSON"in n)){t[s]=n;const i=Ps(n)?[]:{};return Fa(n,(o,l)=>{const c=r(o,s+1);!Cs(c)&&(i[l]=c)}),t[s]=void 0,i}}return n};return r(e,0)},Y1=Gr("AsyncFunction"),q1=e=>e&&(ka(e)||hr(e))&&hr(e.then)&&hr(e.catch),E0=((e,t)=>e?setImmediate:t?((r,n)=>(Kn.addEventListener("message",({source:s,data:i})=>{s===Kn&&i===r&&n.length&&n.shift()()},!1),s=>{n.push(s),Kn.postMessage(r,"*")}))(`axios@${Math.random()}`,[]):r=>setTimeout(r))(typeof setImmediate=="function",hr(Kn.postMessage)),X1=typeof queueMicrotask<"u"?queueMicrotask.bind(Kn):typeof process<"u"&&process.nextTick||E0,J1=e=>e!=null&&hr(e[to]),ue={isArray:Ps,isArrayBuffer:y0,isBuffer:Aa,isFormData:T1,isArrayBufferView:m1,isString:x1,isNumber:w0,isBoolean:p1,isObject:ka,isPlainObject:ui,isEmptyObject:g1,isReadableStream:E1,isRequest:j1,isResponse:I1,isHeaders:C1,isUndefined:Cs,isDate:_1,isFile:v1,isBlob:y1,isRegExp:z1,isFunction:hr,isStream:S1,isURLSearchParams:b1,isTypedArray:N1,isFileList:w1,forEach:Fa,merge:il,extend:k1,trim:A1,stripBOM:F1,inherits:O1,toFlatObject:R1,kindOf:ro,kindOfTest:Gr,endsWith:D1,toArray:P1,forEachEntry:L1,matchAll:M1,isHTMLForm:B1,hasOwnProperty:Dc,hasOwnProp:Dc,reduceDescriptors:b0,freezeMethods:$1,toObjectSet:W1,toCamelCase:U1,noop:H1,toFiniteNumber:V1,findKey:S0,global:Kn,isContextDefined:T0,isSpecCompliantForm:K1,toJSONObject:G1,isAsyncFn:Y1,isThenable:q1,setImmediate:E0,asap:X1,isIterable:J1};let Ve=class j0 extends Error{static from(t,r,n,s,i,o){const l=new j0(t.message,r||t.code,n,s,i);return l.cause=t,l.name=t.name,o&&Object.assign(l,o),l}constructor(t,r,n,s,i){super(t),this.name="AxiosError",this.isAxiosError=!0,r&&(this.code=r),n&&(this.config=n),s&&(this.request=s),i&&(this.response=i,this.status=i.status)}toJSON(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:ue.toJSONObject(this.config),code:this.code,status:this.status}}};Ve.ERR_BAD_OPTION_VALUE="ERR_BAD_OPTION_VALUE";Ve.ERR_BAD_OPTION="ERR_BAD_OPTION";Ve.ECONNABORTED="ECONNABORTED";Ve.ETIMEDOUT="ETIMEDOUT";Ve.ERR_NETWORK="ERR_NETWORK";Ve.ERR_FR_TOO_MANY_REDIRECTS="ERR_FR_TOO_MANY_REDIRECTS";Ve.ERR_DEPRECATED="ERR_DEPRECATED";Ve.ERR_BAD_RESPONSE="ERR_BAD_RESPONSE";Ve.ERR_BAD_REQUEST="ERR_BAD_REQUEST";Ve.ERR_CANCELED="ERR_CANCELED";Ve.ERR_NOT_SUPPORT="ERR_NOT_SUPPORT";Ve.ERR_INVALID_URL="ERR_INVALID_URL";const Z1=null;function ol(e){return ue.isPlainObject(e)||ue.isArray(e)}function I0(e){return ue.endsWith(e,"[]")?e.slice(0,-2):e}function Pc(e,t,r){return e?e.concat(t).map(function(s,i){return s=I0(s),!r&&i?"["+s+"]":s}).join(r?".":""):t}function Q1(e){return ue.isArray(e)&&!e.some(ol)}const eg=ue.toFlatObject(ue,{},null,function(t){return/^is[A-Z]/.test(t)});function so(e,t,r){if(!ue.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,r=ue.toFlatObject(r,{metaTokens:!0,dots:!1,indexes:!1},!1,function(f,p){return!ue.isUndefined(p[f])});const n=r.metaTokens,s=r.visitor||u,i=r.dots,o=r.indexes,c=(r.Blob||typeof Blob<"u"&&Blob)&&ue.isSpecCompliantForm(t);if(!ue.isFunction(s))throw new TypeError("visitor must be a function");function d(x){if(x===null)return"";if(ue.isDate(x))return x.toISOString();if(ue.isBoolean(x))return x.toString();if(!c&&ue.isBlob(x))throw new Ve("Blob is not supported. Use a Buffer instead.");return ue.isArrayBuffer(x)||ue.isTypedArray(x)?c&&typeof Blob=="function"?new Blob([x]):Buffer.from(x):x}function u(x,f,p){let I=x;if(x&&!p&&typeof x=="object"){if(ue.endsWith(f,"{}"))f=n?f:f.slice(0,-2),x=JSON.stringify(x);else if(ue.isArray(x)&&Q1(x)||(ue.isFileList(x)||ue.endsWith(f,"[]"))&&(I=ue.toArray(x)))return f=I0(f),I.forEach(function(w,v){!(ue.isUndefined(w)||w===null)&&t.append(o===!0?Pc([f],v,i):o===null?f:f+"[]",d(w))}),!1}return ol(x)?!0:(t.append(Pc(p,f,i),d(x)),!1)}const h=[],m=Object.assign(eg,{defaultVisitor:u,convertValue:d,isVisitable:ol});function _(x,f){if(!ue.isUndefined(x)){if(h.indexOf(x)!==-1)throw Error("Circular reference detected in "+f.join("."));h.push(x),ue.forEach(x,function(I,S){(!(ue.isUndefined(I)||I===null)&&s.call(t,I,ue.isString(S)?S.trim():S,f,m))===!0&&_(I,f?f.concat(S):[S])}),h.pop()}}if(!ue.isObject(e))throw new TypeError("data must be an object");return _(e),t}function Nc(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(n){return t[n]})}function kl(e,t){this._pairs=[],e&&so(e,this,t)}const C0=kl.prototype;C0.append=function(t,r){this._pairs.push([t,r])};C0.toString=function(t){const r=t?function(n){return t.call(this,n,Nc)}:Nc;return this._pairs.map(function(s){return r(s[0])+"="+r(s[1])},"").join("&")};function tg(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function A0(e,t,r){if(!t)return e;const n=r&&r.encode||tg,s=ue.isFunction(r)?{serialize:r}:r,i=s&&s.serialize;let o;if(i?o=i(t,s):o=ue.isURLSearchParams(t)?t.toString():new kl(t,s).toString(n),o){const l=e.indexOf("#");l!==-1&&(e=e.slice(0,l)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class Lc{constructor(){this.handlers=[]}use(t,r,n){return this.handlers.push({fulfilled:t,rejected:r,synchronous:n?n.synchronous:!1,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){ue.forEach(this.handlers,function(n){n!==null&&t(n)})}}const k0={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},rg=typeof URLSearchParams<"u"?URLSearchParams:kl,ng=typeof FormData<"u"?FormData:null,sg=typeof Blob<"u"?Blob:null,ag={isBrowser:!0,classes:{URLSearchParams:rg,FormData:ng,Blob:sg},protocols:["http","https","file","blob","url","data"]},Fl=typeof window<"u"&&typeof document<"u",ll=typeof navigator=="object"&&navigator||void 0,ig=Fl&&(!ll||["ReactNative","NativeScript","NS"].indexOf(ll.product)<0),og=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",lg=Fl&&window.location.href||"http://localhost",cg=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Fl,hasStandardBrowserEnv:ig,hasStandardBrowserWebWorkerEnv:og,navigator:ll,origin:lg},Symbol.toStringTag,{value:"Module"})),nr={...cg,...ag};function dg(e,t){return so(e,new nr.classes.URLSearchParams,{visitor:function(r,n,s,i){return nr.isNode&&ue.isBuffer(r)?(this.append(n,r.toString("base64")),!1):i.defaultVisitor.apply(this,arguments)},...t})}function ug(e){return ue.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function fg(e){const t={},r=Object.keys(e);let n;const s=r.length;let i;for(n=0;n=r.length;return o=!o&&ue.isArray(s)?s.length:o,c?(ue.hasOwnProp(s,o)?s[o]=[s[o],n]:s[o]=n,!l):((!s[o]||!ue.isObject(s[o]))&&(s[o]=[]),t(r,n,s[o],i)&&ue.isArray(s[o])&&(s[o]=fg(s[o])),!l)}if(ue.isFormData(e)&&ue.isFunction(e.entries)){const r={};return ue.forEachEntry(e,(n,s)=>{t(ug(n),s,r,0)}),r}return null}function hg(e,t,r){if(ue.isString(e))try{return(t||JSON.parse)(e),ue.trim(e)}catch(n){if(n.name!=="SyntaxError")throw n}return(r||JSON.stringify)(e)}const Oa={transitional:k0,adapter:["xhr","http","fetch"],transformRequest:[function(t,r){const n=r.getContentType()||"",s=n.indexOf("application/json")>-1,i=ue.isObject(t);if(i&&ue.isHTMLForm(t)&&(t=new FormData(t)),ue.isFormData(t))return s?JSON.stringify(F0(t)):t;if(ue.isArrayBuffer(t)||ue.isBuffer(t)||ue.isStream(t)||ue.isFile(t)||ue.isBlob(t)||ue.isReadableStream(t))return t;if(ue.isArrayBufferView(t))return t.buffer;if(ue.isURLSearchParams(t))return r.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(i){if(n.indexOf("application/x-www-form-urlencoded")>-1)return dg(t,this.formSerializer).toString();if((l=ue.isFileList(t))||n.indexOf("multipart/form-data")>-1){const c=this.env&&this.env.FormData;return so(l?{"files[]":t}:t,c&&new c,this.formSerializer)}}return i||s?(r.setContentType("application/json",!1),hg(t)):t}],transformResponse:[function(t){const r=this.transitional||Oa.transitional,n=r&&r.forcedJSONParsing,s=this.responseType==="json";if(ue.isResponse(t)||ue.isReadableStream(t))return t;if(t&&ue.isString(t)&&(n&&!this.responseType||s)){const o=!(r&&r.silentJSONParsing)&&s;try{return JSON.parse(t,this.parseReviver)}catch(l){if(o)throw l.name==="SyntaxError"?Ve.from(l,Ve.ERR_BAD_RESPONSE,this,null,this.response):l}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:nr.classes.FormData,Blob:nr.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};ue.forEach(["delete","get","head","post","put","patch"],e=>{Oa.headers[e]={}});const mg=ue.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),xg=e=>{const t={};let r,n,s;return e&&e.split(` +`).forEach(function(o){s=o.indexOf(":"),r=o.substring(0,s).trim().toLowerCase(),n=o.substring(s+1).trim(),!(!r||t[r]&&mg[r])&&(r==="set-cookie"?t[r]?t[r].push(n):t[r]=[n]:t[r]=t[r]?t[r]+", "+n:n)}),t},Mc=Symbol("internals");function Us(e){return e&&String(e).trim().toLowerCase()}function fi(e){return e===!1||e==null?e:ue.isArray(e)?e.map(fi):String(e)}function pg(e){const t=Object.create(null),r=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let n;for(;n=r.exec(e);)t[n[1]]=n[2];return t}const gg=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Eo(e,t,r,n,s){if(ue.isFunction(n))return n.call(this,t,r);if(s&&(t=r),!!ue.isString(t)){if(ue.isString(n))return t.indexOf(n)!==-1;if(ue.isRegExp(n))return n.test(t)}}function _g(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,r,n)=>r.toUpperCase()+n)}function vg(e,t){const r=ue.toCamelCase(" "+t);["get","set","has"].forEach(n=>{Object.defineProperty(e,n+r,{value:function(s,i,o){return this[n].call(this,t,s,i,o)},configurable:!0})})}let mr=class{constructor(t){t&&this.set(t)}set(t,r,n){const s=this;function i(l,c,d){const u=Us(c);if(!u)throw new Error("header name must be a non-empty string");const h=ue.findKey(s,u);(!h||s[h]===void 0||d===!0||d===void 0&&s[h]!==!1)&&(s[h||c]=fi(l))}const o=(l,c)=>ue.forEach(l,(d,u)=>i(d,u,c));if(ue.isPlainObject(t)||t instanceof this.constructor)o(t,r);else if(ue.isString(t)&&(t=t.trim())&&!gg(t))o(xg(t),r);else if(ue.isObject(t)&&ue.isIterable(t)){let l={},c,d;for(const u of t){if(!ue.isArray(u))throw TypeError("Object iterator must return a key-value pair");l[d=u[0]]=(c=l[d])?ue.isArray(c)?[...c,u[1]]:[c,u[1]]:u[1]}o(l,r)}else t!=null&&i(r,t,n);return this}get(t,r){if(t=Us(t),t){const n=ue.findKey(this,t);if(n){const s=this[n];if(!r)return s;if(r===!0)return pg(s);if(ue.isFunction(r))return r.call(this,s,n);if(ue.isRegExp(r))return r.exec(s);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,r){if(t=Us(t),t){const n=ue.findKey(this,t);return!!(n&&this[n]!==void 0&&(!r||Eo(this,this[n],n,r)))}return!1}delete(t,r){const n=this;let s=!1;function i(o){if(o=Us(o),o){const l=ue.findKey(n,o);l&&(!r||Eo(n,n[l],l,r))&&(delete n[l],s=!0)}}return ue.isArray(t)?t.forEach(i):i(t),s}clear(t){const r=Object.keys(this);let n=r.length,s=!1;for(;n--;){const i=r[n];(!t||Eo(this,this[i],i,t,!0))&&(delete this[i],s=!0)}return s}normalize(t){const r=this,n={};return ue.forEach(this,(s,i)=>{const o=ue.findKey(n,i);if(o){r[o]=fi(s),delete r[i];return}const l=t?_g(i):String(i).trim();l!==i&&delete r[i],r[l]=fi(s),n[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const r=Object.create(null);return ue.forEach(this,(n,s)=>{n!=null&&n!==!1&&(r[s]=t&&ue.isArray(n)?n.join(", "):n)}),r}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,r])=>t+": "+r).join(` +`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...r){const n=new this(t);return r.forEach(s=>n.set(s)),n}static accessor(t){const n=(this[Mc]=this[Mc]={accessors:{}}).accessors,s=this.prototype;function i(o){const l=Us(o);n[l]||(vg(s,o),n[l]=!0)}return ue.isArray(t)?t.forEach(i):i(t),this}};mr.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);ue.reduceDescriptors(mr.prototype,({value:e},t)=>{let r=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(n){this[r]=n}}});ue.freezeMethods(mr);function jo(e,t){const r=this||Oa,n=t||r,s=mr.from(n.headers);let i=n.data;return ue.forEach(e,function(l){i=l.call(r,i,s.normalize(),t?t.status:void 0)}),s.normalize(),i}function O0(e){return!!(e&&e.__CANCEL__)}let Ra=class extends Ve{constructor(t,r,n){super(t??"canceled",Ve.ERR_CANCELED,r,n),this.name="CanceledError",this.__CANCEL__=!0}};function R0(e,t,r){const n=r.config.validateStatus;!r.status||!n||n(r.status)?e(r):t(new Ve("Request failed with status code "+r.status,[Ve.ERR_BAD_REQUEST,Ve.ERR_BAD_RESPONSE][Math.floor(r.status/100)-4],r.config,r.request,r))}function yg(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function wg(e,t){e=e||10;const r=new Array(e),n=new Array(e);let s=0,i=0,o;return t=t!==void 0?t:1e3,function(c){const d=Date.now(),u=n[i];o||(o=d),r[s]=c,n[s]=d;let h=i,m=0;for(;h!==s;)m+=r[h++],h=h%e;if(s=(s+1)%e,s===i&&(i=(i+1)%e),d-o{r=u,s=null,i&&(clearTimeout(i),i=null),e(...d)};return[(...d)=>{const u=Date.now(),h=u-r;h>=n?o(d,u):(s=d,i||(i=setTimeout(()=>{i=null,o(s)},n-h)))},()=>s&&o(s)]}const Ti=(e,t,r=3)=>{let n=0;const s=wg(50,250);return Sg(i=>{const o=i.loaded,l=i.lengthComputable?i.total:void 0,c=o-n,d=s(c),u=o<=l;n=o;const h={loaded:o,total:l,progress:l?o/l:void 0,bytes:c,rate:d||void 0,estimated:d&&l&&u?(l-o)/d:void 0,event:i,lengthComputable:l!=null,[t?"download":"upload"]:!0};e(h)},r)},Bc=(e,t)=>{const r=e!=null;return[n=>t[0]({lengthComputable:r,total:e,loaded:n}),t[1]]},Uc=e=>(...t)=>ue.asap(()=>e(...t)),Tg=nr.hasStandardBrowserEnv?((e,t)=>r=>(r=new URL(r,nr.origin),e.protocol===r.protocol&&e.host===r.host&&(t||e.port===r.port)))(new URL(nr.origin),nr.navigator&&/(msie|trident)/i.test(nr.navigator.userAgent)):()=>!0,bg=nr.hasStandardBrowserEnv?{write(e,t,r,n,s,i,o){if(typeof document>"u")return;const l=[`${e}=${encodeURIComponent(t)}`];ue.isNumber(r)&&l.push(`expires=${new Date(r).toUTCString()}`),ue.isString(n)&&l.push(`path=${n}`),ue.isString(s)&&l.push(`domain=${s}`),i===!0&&l.push("secure"),ue.isString(o)&&l.push(`SameSite=${o}`),document.cookie=l.join("; ")},read(e){if(typeof document>"u")return null;const t=document.cookie.match(new RegExp("(?:^|; )"+e+"=([^;]*)"));return t?decodeURIComponent(t[1]):null},remove(e){this.write(e,"",Date.now()-864e5,"/")}}:{write(){},read(){return null},remove(){}};function Eg(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function jg(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function D0(e,t,r){let n=!Eg(t);return e&&(n||r==!1)?jg(e,t):t}const zc=e=>e instanceof mr?{...e}:e;function qn(e,t){t=t||{};const r={};function n(d,u,h,m){return ue.isPlainObject(d)&&ue.isPlainObject(u)?ue.merge.call({caseless:m},d,u):ue.isPlainObject(u)?ue.merge({},u):ue.isArray(u)?u.slice():u}function s(d,u,h,m){if(ue.isUndefined(u)){if(!ue.isUndefined(d))return n(void 0,d,h,m)}else return n(d,u,h,m)}function i(d,u){if(!ue.isUndefined(u))return n(void 0,u)}function o(d,u){if(ue.isUndefined(u)){if(!ue.isUndefined(d))return n(void 0,d)}else return n(void 0,u)}function l(d,u,h){if(h in t)return n(d,u);if(h in e)return n(void 0,d)}const c={url:i,method:i,data:i,baseURL:o,transformRequest:o,transformResponse:o,paramsSerializer:o,timeout:o,timeoutMessage:o,withCredentials:o,withXSRFToken:o,adapter:o,responseType:o,xsrfCookieName:o,xsrfHeaderName:o,onUploadProgress:o,onDownloadProgress:o,decompress:o,maxContentLength:o,maxBodyLength:o,beforeRedirect:o,transport:o,httpAgent:o,httpsAgent:o,cancelToken:o,socketPath:o,responseEncoding:o,validateStatus:l,headers:(d,u,h)=>s(zc(d),zc(u),h,!0)};return ue.forEach(Object.keys({...e,...t}),function(u){const h=c[u]||s,m=h(e[u],t[u],u);ue.isUndefined(m)&&h!==l||(r[u]=m)}),r}const P0=e=>{const t=qn({},e);let{data:r,withXSRFToken:n,xsrfHeaderName:s,xsrfCookieName:i,headers:o,auth:l}=t;if(t.headers=o=mr.from(o),t.url=A0(D0(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),l&&o.set("Authorization","Basic "+btoa((l.username||"")+":"+(l.password?unescape(encodeURIComponent(l.password)):""))),ue.isFormData(r)){if(nr.hasStandardBrowserEnv||nr.hasStandardBrowserWebWorkerEnv)o.setContentType(void 0);else if(ue.isFunction(r.getHeaders)){const c=r.getHeaders(),d=["content-type","content-length"];Object.entries(c).forEach(([u,h])=>{d.includes(u.toLowerCase())&&o.set(u,h)})}}if(nr.hasStandardBrowserEnv&&(n&&ue.isFunction(n)&&(n=n(t)),n||n!==!1&&Tg(t.url))){const c=s&&i&&bg.read(i);c&&o.set(s,c)}return t},Ig=typeof XMLHttpRequest<"u",Cg=Ig&&function(e){return new Promise(function(r,n){const s=P0(e);let i=s.data;const o=mr.from(s.headers).normalize();let{responseType:l,onUploadProgress:c,onDownloadProgress:d}=s,u,h,m,_,x;function f(){_&&_(),x&&x(),s.cancelToken&&s.cancelToken.unsubscribe(u),s.signal&&s.signal.removeEventListener("abort",u)}let p=new XMLHttpRequest;p.open(s.method.toUpperCase(),s.url,!0),p.timeout=s.timeout;function I(){if(!p)return;const w=mr.from("getAllResponseHeaders"in p&&p.getAllResponseHeaders()),y={data:!l||l==="text"||l==="json"?p.responseText:p.response,status:p.status,statusText:p.statusText,headers:w,config:e,request:p};R0(function(j){r(j),f()},function(j){n(j),f()},y),p=null}"onloadend"in p?p.onloadend=I:p.onreadystatechange=function(){!p||p.readyState!==4||p.status===0&&!(p.responseURL&&p.responseURL.indexOf("file:")===0)||setTimeout(I)},p.onabort=function(){p&&(n(new Ve("Request aborted",Ve.ECONNABORTED,e,p)),p=null)},p.onerror=function(v){const y=v&&v.message?v.message:"Network Error",R=new Ve(y,Ve.ERR_NETWORK,e,p);R.event=v||null,n(R),p=null},p.ontimeout=function(){let v=s.timeout?"timeout of "+s.timeout+"ms exceeded":"timeout exceeded";const y=s.transitional||k0;s.timeoutErrorMessage&&(v=s.timeoutErrorMessage),n(new Ve(v,y.clarifyTimeoutError?Ve.ETIMEDOUT:Ve.ECONNABORTED,e,p)),p=null},i===void 0&&o.setContentType(null),"setRequestHeader"in p&&ue.forEach(o.toJSON(),function(v,y){p.setRequestHeader(y,v)}),ue.isUndefined(s.withCredentials)||(p.withCredentials=!!s.withCredentials),l&&l!=="json"&&(p.responseType=s.responseType),d&&([m,x]=Ti(d,!0),p.addEventListener("progress",m)),c&&p.upload&&([h,_]=Ti(c),p.upload.addEventListener("progress",h),p.upload.addEventListener("loadend",_)),(s.cancelToken||s.signal)&&(u=w=>{p&&(n(!w||w.type?new Ra(null,e,p):w),p.abort(),p=null)},s.cancelToken&&s.cancelToken.subscribe(u),s.signal&&(s.signal.aborted?u():s.signal.addEventListener("abort",u)));const S=yg(s.url);if(S&&nr.protocols.indexOf(S)===-1){n(new Ve("Unsupported protocol "+S+":",Ve.ERR_BAD_REQUEST,e));return}p.send(i||null)})},Ag=(e,t)=>{const{length:r}=e=e?e.filter(Boolean):[];if(t||r){let n=new AbortController,s;const i=function(d){if(!s){s=!0,l();const u=d instanceof Error?d:this.reason;n.abort(u instanceof Ve?u:new Ra(u instanceof Error?u.message:u))}};let o=t&&setTimeout(()=>{o=null,i(new Ve(`timeout of ${t}ms exceeded`,Ve.ETIMEDOUT))},t);const l=()=>{e&&(o&&clearTimeout(o),o=null,e.forEach(d=>{d.unsubscribe?d.unsubscribe(i):d.removeEventListener("abort",i)}),e=null)};e.forEach(d=>d.addEventListener("abort",i));const{signal:c}=n;return c.unsubscribe=()=>ue.asap(l),c}},kg=function*(e,t){let r=e.byteLength;if(r{const s=Fg(e,t);let i=0,o,l=c=>{o||(o=!0,n&&n(c))};return new ReadableStream({async pull(c){try{const{done:d,value:u}=await s.next();if(d){l(),c.close();return}let h=u.byteLength;if(r){let m=i+=h;r(m)}c.enqueue(new Uint8Array(u))}catch(d){throw l(d),d}},cancel(c){return l(c),s.return()}},{highWaterMark:2})},Wc=64*1024,{isFunction:$a}=ue,Rg=(({Request:e,Response:t})=>({Request:e,Response:t}))(ue.global),{ReadableStream:Hc,TextEncoder:Vc}=ue.global,Kc=(e,...t)=>{try{return!!e(...t)}catch{return!1}},Dg=e=>{e=ue.merge.call({skipUndefined:!0},Rg,e);const{fetch:t,Request:r,Response:n}=e,s=t?$a(t):typeof fetch=="function",i=$a(r),o=$a(n);if(!s)return!1;const l=s&&$a(Hc),c=s&&(typeof Vc=="function"?(x=>f=>x.encode(f))(new Vc):async x=>new Uint8Array(await new r(x).arrayBuffer())),d=i&&l&&Kc(()=>{let x=!1;const f=new r(nr.origin,{body:new Hc,method:"POST",get duplex(){return x=!0,"half"}}).headers.has("Content-Type");return x&&!f}),u=o&&l&&Kc(()=>ue.isReadableStream(new n("").body)),h={stream:u&&(x=>x.body)};s&&["text","arrayBuffer","blob","formData","stream"].forEach(x=>{!h[x]&&(h[x]=(f,p)=>{let I=f&&f[x];if(I)return I.call(f);throw new Ve(`Response type '${x}' is not supported`,Ve.ERR_NOT_SUPPORT,p)})});const m=async x=>{if(x==null)return 0;if(ue.isBlob(x))return x.size;if(ue.isSpecCompliantForm(x))return(await new r(nr.origin,{method:"POST",body:x}).arrayBuffer()).byteLength;if(ue.isArrayBufferView(x)||ue.isArrayBuffer(x))return x.byteLength;if(ue.isURLSearchParams(x)&&(x=x+""),ue.isString(x))return(await c(x)).byteLength},_=async(x,f)=>{const p=ue.toFiniteNumber(x.getContentLength());return p??m(f)};return async x=>{let{url:f,method:p,data:I,signal:S,cancelToken:w,timeout:v,onDownloadProgress:y,onUploadProgress:R,responseType:j,headers:T,withCredentials:C="same-origin",fetchOptions:F}=P0(x),P=t||fetch;j=j?(j+"").toLowerCase():"text";let V=Ag([S,w&&w.toAbortSignal()],v),X=null;const _e=V&&V.unsubscribe&&(()=>{V.unsubscribe()});let B;try{if(R&&d&&p!=="get"&&p!=="head"&&(B=await _(T,I))!==0){let de=new r(f,{method:"POST",body:I,duplex:"half"}),k;if(ue.isFormData(I)&&(k=de.headers.get("content-type"))&&T.setContentType(k),de.body){const[W,z]=Bc(B,Ti(Uc(R)));I=$c(de.body,Wc,W,z)}}ue.isString(C)||(C=C?"include":"omit");const te=i&&"credentials"in r.prototype,J={...F,signal:V,method:p.toUpperCase(),headers:T.normalize().toJSON(),body:I,duplex:"half",credentials:te?C:void 0};X=i&&new r(f,J);let G=await(i?P(X,F):P(f,J));const se=u&&(j==="stream"||j==="response");if(u&&(y||se&&_e)){const de={};["status","statusText","headers"].forEach(D=>{de[D]=G[D]});const k=ue.toFiniteNumber(G.headers.get("content-length")),[W,z]=y&&Bc(k,Ti(Uc(y),!0))||[];G=new n($c(G.body,Wc,W,()=>{z&&z(),_e&&_e()}),de)}j=j||"text";let Q=await h[ue.findKey(h,j)||"text"](G,x);return!se&&_e&&_e(),await new Promise((de,k)=>{R0(de,k,{data:Q,headers:mr.from(G.headers),status:G.status,statusText:G.statusText,config:x,request:X})})}catch(te){throw _e&&_e(),te&&te.name==="TypeError"&&/Load failed|fetch/i.test(te.message)?Object.assign(new Ve("Network Error",Ve.ERR_NETWORK,x,X),{cause:te.cause||te}):Ve.from(te,te&&te.code,x,X)}}},Pg=new Map,N0=e=>{let t=e&&e.env||{};const{fetch:r,Request:n,Response:s}=t,i=[n,s,r];let o=i.length,l=o,c,d,u=Pg;for(;l--;)c=i[l],d=u.get(c),d===void 0&&u.set(c,d=l?new Map:Dg(t)),u=d;return d};N0();const Ol={http:Z1,xhr:Cg,fetch:{get:N0}};ue.forEach(Ol,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const Gc=e=>`- ${e}`,Ng=e=>ue.isFunction(e)||e===null||e===!1;function Lg(e,t){e=ue.isArray(e)?e:[e];const{length:r}=e;let n,s;const i={};for(let o=0;o`adapter ${c} `+(d===!1?"is not supported by the environment":"is not available in the build"));let l=r?o.length>1?`since : +`+o.map(Gc).join(` +`):" "+Gc(o[0]):"as no adapter specified";throw new Ve("There is no suitable adapter to dispatch the request "+l,"ERR_NOT_SUPPORT")}return s}const L0={getAdapter:Lg,adapters:Ol};function Io(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Ra(null,e)}function Yc(e){return Io(e),e.headers=mr.from(e.headers),e.data=jo.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),L0.getAdapter(e.adapter||Oa.adapter,e)(e).then(function(n){return Io(e),n.data=jo.call(e,e.transformResponse,n),n.headers=mr.from(n.headers),n},function(n){return O0(n)||(Io(e),n&&n.response&&(n.response.data=jo.call(e,e.transformResponse,n.response),n.response.headers=mr.from(n.response.headers))),Promise.reject(n)})}const M0="1.13.3",ao={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{ao[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}});const qc={};ao.transitional=function(t,r,n){function s(i,o){return"[Axios v"+M0+"] Transitional option '"+i+"'"+o+(n?". "+n:"")}return(i,o,l)=>{if(t===!1)throw new Ve(s(o," has been removed"+(r?" in "+r:"")),Ve.ERR_DEPRECATED);return r&&!qc[o]&&(qc[o]=!0,console.warn(s(o," has been deprecated since v"+r+" and will be removed in the near future"))),t?t(i,o,l):!0}};ao.spelling=function(t){return(r,n)=>(console.warn(`${n} is likely a misspelling of ${t}`),!0)};function Mg(e,t,r){if(typeof e!="object")throw new Ve("options must be an object",Ve.ERR_BAD_OPTION_VALUE);const n=Object.keys(e);let s=n.length;for(;s-- >0;){const i=n[s],o=t[i];if(o){const l=e[i],c=l===void 0||o(l,i,e);if(c!==!0)throw new Ve("option "+i+" must be "+c,Ve.ERR_BAD_OPTION_VALUE);continue}if(r!==!0)throw new Ve("Unknown option "+i,Ve.ERR_BAD_OPTION)}}const hi={assertOptions:Mg,validators:ao},Jr=hi.validators;let Gn=class{constructor(t){this.defaults=t||{},this.interceptors={request:new Lc,response:new Lc}}async request(t,r){try{return await this._request(t,r)}catch(n){if(n instanceof Error){let s={};Error.captureStackTrace?Error.captureStackTrace(s):s=new Error;const i=s.stack?s.stack.replace(/^.+\n/,""):"";try{n.stack?i&&!String(n.stack).endsWith(i.replace(/^.+\n.+\n/,""))&&(n.stack+=` +`+i):n.stack=i}catch{}}throw n}}_request(t,r){typeof t=="string"?(r=r||{},r.url=t):r=t||{},r=qn(this.defaults,r);const{transitional:n,paramsSerializer:s,headers:i}=r;n!==void 0&&hi.assertOptions(n,{silentJSONParsing:Jr.transitional(Jr.boolean),forcedJSONParsing:Jr.transitional(Jr.boolean),clarifyTimeoutError:Jr.transitional(Jr.boolean)},!1),s!=null&&(ue.isFunction(s)?r.paramsSerializer={serialize:s}:hi.assertOptions(s,{encode:Jr.function,serialize:Jr.function},!0)),r.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?r.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:r.allowAbsoluteUrls=!0),hi.assertOptions(r,{baseUrl:Jr.spelling("baseURL"),withXsrfToken:Jr.spelling("withXSRFToken")},!0),r.method=(r.method||this.defaults.method||"get").toLowerCase();let o=i&&ue.merge(i.common,i[r.method]);i&&ue.forEach(["delete","get","head","post","put","patch","common"],x=>{delete i[x]}),r.headers=mr.concat(o,i);const l=[];let c=!0;this.interceptors.request.forEach(function(f){typeof f.runWhen=="function"&&f.runWhen(r)===!1||(c=c&&f.synchronous,l.unshift(f.fulfilled,f.rejected))});const d=[];this.interceptors.response.forEach(function(f){d.push(f.fulfilled,f.rejected)});let u,h=0,m;if(!c){const x=[Yc.bind(this),void 0];x.unshift(...l),x.push(...d),m=x.length,u=Promise.resolve(r);let f=r;for(;h{f=p!==void 0?p:f}).catch(x[h++]).then(()=>f);return u}m=l.length;let _=r;for(;h{if(!n._listeners)return;let i=n._listeners.length;for(;i-- >0;)n._listeners[i](s);n._listeners=null}),this.promise.then=s=>{let i;const o=new Promise(l=>{n.subscribe(l),i=l}).then(s);return o.cancel=function(){n.unsubscribe(i)},o},t(function(i,o,l){n.reason||(n.reason=new Ra(i,o,l),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const r=this._listeners.indexOf(t);r!==-1&&this._listeners.splice(r,1)}toAbortSignal(){const t=new AbortController,r=n=>{t.abort(n)};return this.subscribe(r),t.signal.unsubscribe=()=>this.unsubscribe(r),t.signal}static source(){let t;return{token:new B0(function(s){t=s}),cancel:t}}};function Ug(e){return function(r){return e.apply(null,r)}}function zg(e){return ue.isObject(e)&&e.isAxiosError===!0}const cl={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(cl).forEach(([e,t])=>{cl[t]=e});function U0(e){const t=new Gn(e),r=_0(Gn.prototype.request,t);return ue.extend(r,Gn.prototype,t,{allOwnKeys:!0}),ue.extend(r,t,null,{allOwnKeys:!0}),r.create=function(s){return U0(qn(e,s))},r}const At=U0(Oa);At.Axios=Gn;At.CanceledError=Ra;At.CancelToken=Bg;At.isCancel=O0;At.VERSION=M0;At.toFormData=so;At.AxiosError=Ve;At.Cancel=At.CanceledError;At.all=function(t){return Promise.all(t)};At.spread=Ug;At.isAxiosError=zg;At.mergeConfig=qn;At.AxiosHeaders=mr;At.formToJSON=e=>F0(ue.isHTMLForm(e)?new FormData(e):e);At.getAdapter=L0.getAdapter;At.HttpStatusCode=cl;At.default=At;const{Axios:u4,AxiosError:f4,CanceledError:h4,isCancel:m4,CancelToken:x4,VERSION:p4,all:g4,Cancel:_4,isAxiosError:v4,spread:y4,toFormData:w4,AxiosHeaders:S4,HttpStatusCode:T4,formToJSON:b4,getAdapter:E4,mergeConfig:j4}=At;/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */function $g(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function fr(e,t,r=""){const n=$g(e),s=e==null?void 0:e.length,i=t!==void 0;if(!n||i&&s!==t){const o=r&&`"${r}" `,l=i?` of length ${t}`:"",c=n?`length=${s}`:`type=${typeof e}`;throw new Error(o+"expected Uint8Array"+l+", got "+c)}return e}function bi(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function z0(e,t){fr(e,void 0,"output");const r=t.outputLen;if(e.length{function r(n,...s){if(fr(n,void 0,"key"),!Hg)throw new Error("Non little-endian hardware is not yet supported");if(e.nonceLength!==void 0){const u=s[0];fr(u,e.varSizeNonce?void 0:e.nonceLength,"nonce")}const i=e.tagLength;i&&s[1]!==void 0&&fr(s[1],void 0,"AAD");const o=t(n,...s),l=(u,h)=>{if(h!==void 0){if(u!==2)throw new Error("cipher output not supported");fr(h,void 0,"output")}};let c=!1;return{encrypt(u,h){if(c)throw new Error("cannot encrypt() twice with same key + nonce");return c=!0,fr(u),l(o.encrypt.length,h),o.encrypt(u,h)},decrypt(u,h){if(fr(u),i&&u.length{const s=n&1;return{s3:r<<31|n>>>1,s2:t<<31|r>>>1,s1:e<<31|t>>>1,s0:e>>>1^qg<<24&-(s&1)}},Pr=e=>(e>>>0&255)<<24|(e>>>8&255)<<16|(e>>>16&255)<<8|e>>>24&255|0;function Jg(e){e.reverse();const t=e[15]&1;let r=0;for(let n=0;n>>1|r,r=(s&1)<<7}return e[0]^=-t&225,e}const Zg=e=>e>64*1024?8:e>1024?4:2;class $0{constructor(t,r){Or(this,"blockLen",fn);Or(this,"outputLen",fn);Or(this,"s0",0);Or(this,"s1",0);Or(this,"s2",0);Or(this,"s3",0);Or(this,"finished",!1);Or(this,"t");Or(this,"W");Or(this,"windowSize");fr(t,16,"key"),t=Xn(t);const n=io(t);let s=n.getUint32(0,!1),i=n.getUint32(4,!1),o=n.getUint32(8,!1),l=n.getUint32(12,!1);const c=[];for(let x=0;x<128;x++)c.push({s0:Pr(s),s1:Pr(i),s2:Pr(o),s3:Pr(l)}),{s0:s,s1:i,s2:o,s3:l}=Xg(s,i,o,l);const d=Zg(r||1024);if(![1,2,4,8].includes(d))throw new Error("ghash: invalid window size, expected 2, 4 or 8");this.W=d;const h=128/d,m=this.windowSize=2**d,_=[];for(let x=0;x>>d-v-1&1))continue;const{s0:R,s1:j,s2:T,s3:C}=c[d*x+v];p^=R,I^=j,S^=T,w^=C}_.push({s0:p,s1:I,s2:S,s3:w})}this.t=_}_updateBlock(t,r,n,s){t^=this.s0,r^=this.s1,n^=this.s2,s^=this.s3;const{W:i,t:o,windowSize:l}=this;let c=0,d=0,u=0,h=0;const m=(1<>>8*f&255;for(let I=8/i-1;I>=0;I--){const S=p>>>i*I&m,{s0:w,s1:v,s2:y,s3:R}=o[_*l+S];c^=w,d^=v,u^=y,h^=R,_+=1}}this.s0=c,this.s1=d,this.s2=u,this.s3=h}update(t){bi(this),fr(t),t=Xn(t);const r=mn(t),n=Math.floor(t.length/fn),s=t.length%fn;for(let i=0;ie(s,n.length).update(n).digest(),r=e(new Uint8Array(16),0);return t.outputLen=r.outputLen,t.blockLen=r.blockLen,t.create=(n,s)=>e(n,s),t}const Xc=W0((e,t)=>new $0(e,t));W0((e,t)=>new Qg(e,t));const dl=16,e_=4,Wa=new Uint8Array(dl),t_=283;function r_(e){if(![16,24,32].includes(e.length))throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length='+e.length)}function Dl(e){return e<<1^t_&-(e>>7)}function Jc(e,t){let r=0;for(;t>0;t>>=1)r^=e&-(t&1),e=Dl(e);return r}const n_=(()=>{const e=new Uint8Array(256);for(let r=0,n=1;r<256;r++,n^=Dl(n))e[r]=n;const t=new Uint8Array(256);t[0]=99;for(let r=0;r<255;r++){let n=e[255-r];n|=n<<8,t[e[r]]=(n^n>>4^n>>5^n>>6^n>>7^99)&255}return _n(e),t})(),s_=e=>e<<24|e>>>8,Co=e=>e<<8|e>>>24;function a_(e,t){if(e.length!==256)throw new Error("Wrong sbox length");const r=new Uint32Array(256).map((d,u)=>t(e[u])),n=r.map(Co),s=n.map(Co),i=s.map(Co),o=new Uint32Array(256*256),l=new Uint32Array(256*256),c=new Uint16Array(256*256);for(let d=0;d<256;d++)for(let u=0;u<256;u++){const h=d*256+u;o[h]=r[d]^n[u],l[h]=s[d]^i[u],c[h]=e[d]<<8|e[u]}return{sbox:e,sbox2:c,T0:r,T1:n,T2:s,T3:i,T01:o,T23:l}}const H0=a_(n_,e=>Jc(e,3)<<24|e<<16|e<<8|Jc(e,2)),i_=(()=>{const e=new Uint8Array(16);for(let t=0,r=1;t<16;t++,r=Dl(r))e[t]=r;return e})();function o_(e){fr(e);const t=e.length;r_(e);const{sbox2:r}=H0,n=[];Ei(e)||n.push(e=Xn(e));const s=mn(e),i=s.length,o=c=>Ys(r,c,c,c,c),l=new Uint32Array(t+28);l.set(s);for(let c=i;c6&&c%i===4&&(d=o(d)),l[c]=l[c-i]^d}return _n(...n),l}function Ha(e,t,r,n,s,i){return e[r<<8&65280|n>>>8&255]^t[s>>>8&65280|i>>>24&255]}function Ys(e,t,r,n,s){return e[t&255|r&65280]|e[n>>>16&255|s>>>16&65280]<<16}function Zc(e,t,r,n,s){const{sbox2:i,T01:o,T23:l}=H0;let c=0;t^=e[c++],r^=e[c++],n^=e[c++],s^=e[c++];const d=e.length/4-2;for(let x=0;x>>0,l.setUint32(u,m,t),{s0:_,s1:x,s2:f,s3:p}=Zc(e,o[0],o[1],o[2],o[3]);const I=dl*Math.floor(c.length/e_);if(IparseInt(t,16))),Ga}async function u_(){return Ka||(Ka=await crypto.subtle.importKey("raw",K0().buffer,{name:"AES-GCM"},!1,["decrypt"]),Ka)}async function Qc(e){const t=Uint8Array.from(atob(e),o=>o.charCodeAt(0)),r=t.slice(0,12),n=t.slice(12);if(d_){const o=await u_(),l=await crypto.subtle.decrypt({name:"AES-GCM",iv:r},o,n);return new TextDecoder().decode(l)}const i=c_(K0(),r).decrypt(n);return new TextDecoder().decode(i)}function f_(){return V0.length===64}const h_="admin_access_token";class m_{constructor(){Or(this,"client");this.client=At.create({baseURL:"https://admin-api.adfahi.cn/api/v1",timeout:1e4,headers:{"Content-Type":"application/json"}}),this.client.interceptors.request.use(t=>{var n;const r=sessionStorage.getItem(h_);return r&&!((n=t.url)!=null&&n.includes("/admin/auth/login"))&&(t.headers.Authorization=`Bearer ${r}`),f_()&&(t.headers["X-Accept-Encrypted"]="1"),t},t=>Promise.reject(t)),this.client.interceptors.response.use(async t=>{var r;if((r=t.data)!=null&&r._enc)try{const n=await Qc(t.data._enc);return JSON.parse(n)}catch(n){return console.warn("[Crypto] 解密失败,回退原始数据:",n),t.data}return t.data},async t=>{var n,s,i;const r=(n=t.response)==null?void 0:n.data;if(r!=null&&r._enc)try{const o=await Qc(r._enc);t.response.data=JSON.parse(o)}catch(o){console.warn("[Crypto] 错误响应解密失败:",o)}return((s=t.response)==null?void 0:s.status)===401&&this.handleAuthError(),(i=t.response)!=null&&i.data?Promise.reject(t.response.data):Promise.reject({code:-1,message:t.message||"网络错误"})})}handleAuthError(){const{clearAuth:t}=pt.getState();t(),window.location.pathname!=="/login"&&(window.location.href="/login")}async get(t,r){return this.client.get(t,r)}async post(t,r,n){return this.client.post(t,r,n)}async put(t,r,n){return this.client.put(t,r,n)}async delete(t,r){return this.client.delete(t,r)}}const ce=new m_,dn={login:e=>ce.post("/admin/auth/login",e),profile:()=>ce.get("/admin/auth/profile"),getTOTPStatus:()=>ce.get("/admin/auth/totp/status"),setupTOTP:()=>ce.post("/admin/auth/totp/setup"),bindTOTP:e=>ce.post("/admin/auth/totp/bind",e),unbindTOTP:()=>ce.post("/admin/auth/totp/unbind"),changePassword:e=>ce.put("/admin/auth/password",e)},Lt={list:e=>ce.get("/admin/users",{params:e}),detail:e=>ce.get(`/admin/users/${e}`),updateStatus:(e,t)=>ce.put(`/admin/users/${e}/status`,{status:t}),batchBan:e=>ce.post("/admin/users/batch-ban",{usernames:e}),banByIP:(e,t)=>ce.post("/admin/users/ban-by-ip",{ip:e,tenant_id:t},{timeout:3e5}),updateUsername:(e,t)=>ce.put(`/admin/users/${e}/username`,{number_suffix:t}),delete:e=>ce.delete(`/admin/users/${e}`),create:e=>ce.post("/admin/users",e),resetPassword:(e,t)=>ce.post(`/admin/users/${e}/reset_password`,{password:t}),updateSecurityPerm:(e,t)=>ce.put(`/admin/users/${e}/security-perm`,{can_view_security_info:t}),updateFriendPrivilege:(e,t)=>ce.put(`/admin/users/${e}/friend-privilege`,{friend_privilege:t}),updateIPWhitelist:(e,t)=>ce.put(`/admin/users/${e}/ip-whitelist`,{login_ip_whitelist:t}),kick:e=>ce.post(`/admin/users/${e}/kick`),forceDeactivate:e=>ce.post(`/admin/users/${e}/deactivate`),batchCreate:e=>ce.post("/admin/users/batch",e),importExcel:e=>ce.post("/admin/users/import-xlsx",e,{headers:{"Content-Type":"multipart/form-data"}})},Wn={list:e=>ce.get("/admin/groups",{params:e}),detail:e=>ce.get(`/admin/groups/${e}`),dismiss:e=>ce.delete(`/admin/groups/${e}`),ban:(e,t)=>ce.post(`/admin/groups/${e}/ban`,{reason:t}),unban:e=>ce.post(`/admin/groups/${e}/unban`),quickCreate:e=>ce.post("/admin/groups/quick-create",e,{timeout:3e5})},ed={search:e=>ce.get("/admin/messages/search",{params:e}),delete:e=>ce.delete(`/admin/messages/${e}`)},x_={get:e=>ce.get("/admin/stats",{params:e?{tenant_id:e}:void 0})},td={list:e=>ce.get("/admin/audit/logs",{params:e}),exportCsv:async e=>{const t="https://admin-api.adfahi.cn/api/v1",r=sessionStorage.getItem("admin_access_token"),n=new URLSearchParams(Object.entries(e).filter(([,c])=>c!=null)).toString(),s=`${t}/admin/audit/logs/export${n?"?"+n:""}`,i=await fetch(s,{headers:{Authorization:`Bearer ${r}`}});if(!i.ok)throw new Error("导出失败");const o=await i.blob(),l=document.createElement("a");l.href=URL.createObjectURL(o),l.download=`audit_logs_${new Date().toISOString().slice(0,10)}.csv`,l.click(),URL.revokeObjectURL(l.href)}},hn={list:e=>ce.get("/admin/tenants",{params:e}),create:e=>ce.post("/admin/tenants",e),detail:e=>ce.get(`/admin/tenants/${e}`),update:(e,t)=>ce.put(`/admin/tenants/${e}`,t),updateStatus:(e,t,r)=>ce.put(`/admin/tenants/${e}/status`,{status:t,ban_reason:r}),autoBind:()=>ce.post("/admin/tenants/auto-bind")},os={list:e=>ce.get("/admin/admins",{params:e}),create:e=>ce.post("/admin/admins",e),detail:e=>ce.get(`/admin/admins/${e}`),update:(e,t)=>ce.put(`/admin/admins/${e}`,t),updateStatus:(e,t)=>ce.put(`/admin/admins/${e}/status`,{status:t}),resetPassword:(e,t)=>ce.post(`/admin/admins/${e}/reset_password`,{password:t}),delete:e=>ce.delete(`/admin/admins/${e}`)},Ya={list:e=>ce.get("/admin/roles",{params:e}),create:e=>ce.post("/admin/roles",e),update:(e,t)=>ce.put(`/admin/roles/${e}`,t),delete:e=>ce.delete(`/admin/roles/${e}`)},qa={list:e=>ce.get("/admin/invite-codes",{params:e}),create:e=>ce.post("/admin/invite-codes",e),listUsages:(e,t)=>ce.get(`/admin/invite-codes/${e}/usages`,{params:t}),delete:e=>ce.delete(`/admin/invite-codes/${e}`)},zs={list:e=>ce.get("/admin/announcements",{params:e}),create:e=>ce.post("/admin/announcements",e),update:(e,t)=>ce.put(`/admin/announcements/${e}`,t),publish:e=>ce.post(`/admin/announcements/${e}/publish`),delete:e=>ce.delete(`/admin/announcements/${e}`)},ls={list:e=>ce.get("/admin/sensitive-words",{params:e}),create:e=>ce.post("/admin/sensitive-words",e),update:(e,t)=>ce.put(`/admin/sensitive-words/${e}`,t),delete:e=>ce.delete(`/admin/sensitive-words/${e}`),import:e=>ce.post("/admin/sensitive-words/import",e),export:e=>{const t=new URLSearchParams;e!=null&&e.tenant_id&&t.set("tenant_id",String(e.tenant_id)),e!=null&&e.status&&t.set("status",e.status),e!=null&&e.level&&t.set("level",e.level),e!=null&&e.keyword&&t.set("keyword",e.keyword);const r=t.toString(),n=`/admin/sensitive-words/export${r?`?${r}`:""}`;return ce.get(n,{responseType:"blob"}).then(s=>{const i=new Blob([s],{type:"text/csv;charset=utf-8"}),o=document.createElement("a");o.href=URL.createObjectURL(i),o.download="sensitive_words.csv",o.click(),URL.revokeObjectURL(o.href)})}},Xa={list:(e,t)=>ce.get(`/admin/groups/${e}/members`,{params:t}),kick:(e,t)=>ce.post(`/admin/groups/${e}/members/kick`,{user_id:t}),mute:(e,t,r)=>ce.post(`/admin/groups/${e}/members/mute`,{user_id:t,muted_until:r}),unmute:(e,t)=>ce.post(`/admin/groups/${e}/members/unmute`,{user_id:t})},On={list:e=>ce.get("/admin/nodes",{params:e}),create:e=>ce.post("/admin/nodes",e),update:(e,t)=>ce.put(`/admin/nodes/${e}`,t),delete:e=>ce.delete(`/admin/nodes/${e}`),bindTenant:(e,t)=>ce.post(`/admin/tenants/${e}/bind-node`,{node_id:t}),unbindTenant:e=>ce.post(`/admin/tenants/${e}/unbind-node`),getTenantBinding:e=>ce.get(`/admin/tenants/${e}/binding`),cpAuditLogs:e=>ce.get("/admin/control/audit-logs",{params:e})},p_={list:e=>ce.get("/admin/groups/events",{params:e})},Ao={get:()=>ce.get("/admin/avatar-pool"),update:e=>ce.put("/admin/avatar-pool",e),backfill:()=>ce.post("/admin/avatar-pool/backfill")},$s={list:e=>ce.get("/admin/system-conversations",{params:e}),create:e=>ce.post("/admin/system-conversations",e),update:(e,t)=>ce.put(`/admin/system-conversations/${e}`,t),delete:e=>ce.delete(`/admin/system-conversations/${e}`),send:e=>ce.post("/admin/system-conversations/send",e)},ko={list:()=>ce.get("/admin/conversation-notices"),update:e=>ce.put("/admin/conversation-notices",e),delete:()=>ce.delete("/admin/conversation-notices")},Fo={list:e=>ce.get("/admin/reports",{params:e}),detail:e=>ce.get(`/admin/reports/${e}`),handle:(e,t)=>ce.put(`/admin/reports/${e}`,t)},cs={list:e=>ce.get("/admin/tenant-admins",{params:e}),create:e=>ce.post("/admin/tenant-admins",e),update:(e,t)=>ce.put(`/admin/tenant-admins/${e}`,t),updateStatus:(e,t)=>ce.put(`/admin/tenant-admins/${e}/status`,{status:t}),resetPassword:(e,t)=>ce.post(`/admin/tenant-admins/${e}/reset_password`,{password:t}),delete:e=>ce.delete(`/admin/tenant-admins/${e}`)},g_={list:e=>ce.get("/admin/admin-login-history",{params:e})},__={list:e=>ce.get("/admin/user-login-history",{params:e})},rd={list:e=>ce.get("/admin/audit/ip-user-stats",{params:e}),users:e=>ce.get("/admin/audit/ip-user-stats/users",{params:e})},v_={list:e=>ce.get("/admin/audit/user-account-logs",{params:e})},y_={list:e=>ce.get("/admin/login-streak/rank",{params:e})},w_={list:e=>ce.get("/admin/private-msg/rank",{params:e})},S_={lookup:e=>ce.get("/admin/user-password",{params:e})},ps={listAlerts:e=>ce.get("/admin/keyword-alerts",{params:e}),listKeywords:e=>ce.get("/admin/alert-keywords",{params:e}),createKeyword:e=>ce.post("/admin/alert-keywords",e),updateKeyword:(e,t)=>ce.put(`/admin/alert-keywords/${e}`,t),deleteKeyword:e=>ce.delete(`/admin/alert-keywords/${e}`)},nd={get:()=>ce.get("/admin/alert-bot-config"),update:e=>ce.put("/admin/alert-bot-config",e)},T_={getAllNodesStatus:()=>ce.get("/admin/system/nodes-status")},sd={get:e=>ce.get("/admin/tenant-settings",{params:e}),update:e=>ce.put("/admin/tenant-settings",e)},ad={list:(e,t)=>ce.get(`/admin/groups/${e}/files`,{params:t}),delete:(e,t)=>ce.delete(`/admin/groups/${e}/files/${t}`)},pa={getSettings:e=>ce.get("/admin/security-settings",{params:e}),updateSettings:e=>ce.put("/admin/security-settings",e),unlockAccount:e=>ce.post("/admin/security/unlock",e),listFailureLogs:e=>ce.get("/admin/login-failure-logs",{params:e})},Un={encrypt:e=>ce.post("/admin/domain/encrypt",e),decrypt:e=>ce.post("/admin/domain/decrypt",e),obfuscate:e=>ce.post("/admin/domain/obfuscate",e),getConfig:()=>ce.get("/admin/domain/config"),saveConfig:e=>ce.put("/admin/domain/config",e),pushUpdate:(e,t)=>ce.post("/admin/domain/push-update",{domains:e,key:t}),pushBucketUpdate:(e,t)=>ce.post("/admin/domain/push-bucket-update",{buckets:e,key:t})},ds={list:e=>ce.get("/admin/feedbacks",{params:e}),detail:e=>ce.get(`/admin/feedbacks/${e}`),handle:(e,t)=>ce.put(`/admin/feedbacks/${e}`,t),updatePriority:(e,t)=>ce.put(`/admin/feedbacks/${e}/priority`,t),batchHandle:e=>ce.post("/admin/feedbacks/batch-handle",e),export:e=>ce.get("/admin/feedbacks/export",{params:e,responseType:"blob"})},Ja={key:"/dashboard",label:"数据概览"},Oo=_l()((e,t)=>({tabs:[Ja],activeKey:Ja.key,addTab:r=>{const{tabs:n}=t();n.find(s=>s.key===r.key)?e({activeKey:r.key}):e({tabs:[...n,r],activeKey:r.key})},removeTab:r=>{const{tabs:n,activeKey:s}=t();if(n.length<=1)return s;const i=n.findIndex(c=>c.key===r),o=n.filter(c=>c.key!==r);let l=s;return r===s&&(l=o[Math.min(i,o.length-1)].key),e({tabs:o,activeKey:l}),l},setActiveKey:r=>e({activeKey:r}),reorderTabs:(r,n)=>{const{tabs:s}=t();e({tabs:Il(s,r,n)})},clear:()=>e({tabs:[Ja],activeKey:Ja.key})})),G0=_l((e,t)=>({tenants:[],tenantOptions:[],tenantMap:new Map,fetchTenants:async()=>{try{const r=await hn.list({page:1,page_size:200});if((r.code===0||r.code===200)&&r.data){const s=r.data.items;e({tenants:s,tenantOptions:s.map(i=>({label:`${i.name} (${i.code})`,value:i.id})),tenantMap:new Map(s.map(i=>[i.id,i.name]))})}}catch{}},renderTenantId:r=>{if(!r)return"--";const n=t().tenantMap.get(r);return n?`${r}(${n})`:String(r)}})),{Header:b_,Sider:E_,Content:j_}=Ko,{Text:id}=Cr,Ro={"/dashboard":"数据概览","/tenants":"私域管理","/admins":"管理员管理","/tenant-admins":"租户管理员","/roles":"角色权限","/invite-codes":"邀请码管理","/users":"用户管理","/user-policy-groups":"用户分组","/groups":"群组管理","/group-members":"群成员管理","/quick-create-group":"快速建群","/private-messages":"单聊消息","/group-messages":"群聊消息","/announcements":"公告管理","/sensitive-words":"敏感词库","/audit-logs":"操作日志","/user-account-audit":"用户账号审计","/group-events":"群事件审计","/avatar-pool":"默认头像池","/nodes":"节点管理","/system-conversations":"系统会话","/system-notices":"系统通知","/reports":"举报管理","/admin-login-history":"管理员登录历史","/user-login-history":"用户登录历史","/ip-user-stats":"IP 账号统计","/login-streak-ranking":"连续登录排名","/private-msg-ranking":"单聊消息排名","/user-password-query":"用户密码查询","/keyword-alerts":"关键词预警","/alert-bot-config":"预警机器人配置","/tenant-settings":"私域设置","/file-records":"文件管理","/security-settings":"安全策略","/login-failure-logs":"登录失败日志","/system-status":"系统状态","/domain-encrypt":"域名管理","/feedbacks":"用户反馈"},I_=({id:e,children:t})=>{var d;const{attributes:r,listeners:n,setNodeRef:s,transform:i,transition:o,isDragging:l}=Zp({id:e}),c={transform:ma.Transform.toString(i?{...i,scaleX:1,scaleY:1}:null),transition:o,opacity:l?.5:1};return Gt.cloneElement(t,{ref:s,style:{...c,...(d=t.props)==null?void 0:d.style},...r,...n})},C_=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState(!1),[s]=b.useForm(),[i,o]=g.useState(!1),[l,c]=g.useState(!1),[d,u]=g.useState(!1),[h,m]=g.useState(null),[_,x]=g.useState(null),[f,p]=g.useState(""),[I,S]=g.useState(!1),w=wu(),v=Lh(),y=Mh(),{admin:R,permissions:j,setAdmin:T,clearAuth:C}=pt(),{tabs:F,activeKey:P,addTab:V,removeTab:X,setActiveKey:_e,reorderTabs:B}=Oo(),te=G0(fe=>fe.fetchTenants),J=d1();g.useEffect(()=>{(async()=>{try{const Re=await dn.profile();(Re.code===0||Re.code===200)&&Re.data&&T(Re.data)}catch{}})()},[T]),g.useEffect(()=>{te()},[v.pathname]),g.useEffect(()=>{const fe=v.pathname,Re=Ro[fe];Re&&V({key:fe,label:Re})},[v.pathname,V]);const G=!(R!=null&&R.tenant_id),se=fe=>j?j[fe]:!1,Q=g.useMemo(()=>({"/tenants":"platform","/admins":"platform","/tenant-admins":"platform","/roles":"platform","/nodes":"platform","/avatar-pool":"platform","/system-status":"platform","/quick-create-group":"platform","/users":"user-group","/user-policy-groups":"user-group","/groups":"user-group","/group-members":"user-group","/invite-codes":"user-group","/private-messages":"content","/group-messages":"content","/announcements":"content","/sensitive-words":"content","/file-records":"content","/reports":"content","/feedbacks":"content","/system-conversations":"content","/system-notices":"content","/audit-logs":"logs","/group-events":"logs","/admin-login-history":"logs","/user-login-history":"logs","/login-failure-logs":"logs","/login-streak-ranking":"login-rank","/private-msg-ranking":"login-rank","/user-password-query":"login-rank","/keyword-alerts":"login-rank","/alert-bot-config":"login-rank","/tenant-settings":"settings","/security-settings":"settings","/domain-encrypt":"settings"}),[]),[de,k]=g.useState(()=>{const fe=Q[v.pathname];return fe?[fe]:[]});g.useEffect(()=>{const fe=Q[v.pathname];fe&&!de.includes(fe)&&k(Re=>[...Re,fe])},[v.pathname,Q]);const W=g.useMemo(()=>{const fe=Tt=>a.jsxs("span",{style:{color:"#bbb"},children:[Tt,a.jsx("span",{style:{fontSize:11,marginLeft:4},children:"(开发中)"})]}),Re=se("view_private_chat")||se("view_group_chat"),Ue=[{key:"/dashboard",icon:a.jsx($h,{}),label:"数据概览",show:!0},{key:"platform",icon:a.jsx(sc,{}),label:"平台管理",show:se("tenant_manage")&&G,children:[{key:"/tenants",icon:a.jsx(sc,{}),label:"私域管理",show:!0},{key:"/admins",icon:a.jsx(po,{}),label:"管理员管理",show:!0},{key:"/tenant-admins",icon:a.jsx($n,{}),label:"租户管理员",show:!0},{key:"/roles",icon:a.jsx(Go,{}),label:"角色权限",show:!1},{key:"/nodes",icon:a.jsx(Wh,{}),label:"节点管理",show:!0},{key:"/avatar-pool",icon:a.jsx(Hh,{}),label:"默认头像池",show:!0},{key:"/system-status",icon:a.jsx(Vh,{}),label:"系统状态",show:!0},{key:"/quick-create-group",icon:a.jsx(ac,{}),label:"快速建群",show:G}]},{key:"user-group",icon:a.jsx($n,{}),label:"用户与群组",show:se("user_manage")||se("group_manage")||se("tenant_manage"),children:[{key:"/users",icon:a.jsx(ca,{}),label:"用户管理",show:se("user_manage")},{key:"/user-policy-groups",icon:a.jsx(Ks,{}),label:"用户分组",show:se("user_manage")},{key:"/groups",icon:a.jsx($n,{}),label:"群组管理",show:se("group_manage")},{key:"/group-members",icon:a.jsx(ac,{}),label:"群成员管理",show:se("group_manage")},{key:"/invite-codes",icon:a.jsx(xi,{}),label:"邀请码管理",show:se("user_manage")||se("tenant_manage")}]},{key:"login-rank",icon:a.jsx(bu,{}),label:"运营数据",show:G,children:[{key:"/login-streak-ranking",icon:a.jsx(Kh,{}),label:"连续登录排名",show:G},{key:"/private-msg-ranking",icon:a.jsx(ci,{}),label:"单聊消息排名",show:G},{key:"/user-password-query",icon:a.jsx(xi,{}),label:"用户密码查询",show:G},{key:"/keyword-alerts",icon:a.jsx(Su,{}),label:"关键词预警",show:G},{key:"/alert-bot-config",icon:a.jsx(Tu,{}),label:"预警机器人配置",show:G}]},{key:"content",icon:a.jsx(qh,{}),label:"内容审核",show:Re||se("tenant_manage"),children:[{key:"/private-messages",icon:a.jsx(ci,{}),label:"单聊消息",show:se("view_private_chat")},{key:"/group-messages",icon:a.jsx($n,{}),label:"群聊消息",show:se("view_group_chat")},{key:"/sensitive-words",icon:a.jsx(ic,{}),label:"敏感词库",show:Re},{key:"/file-records",icon:a.jsx(Eu,{}),label:"文件管理",show:Re},{key:"/reports",icon:a.jsx(Gh,{}),label:"举报管理",show:Re&&G},{key:"/feedbacks",icon:a.jsx(Yh,{}),label:"用户反馈",show:Re},{key:"/system-conversations",icon:a.jsx(ci,{}),label:"系统会话",show:se("tenant_manage")},{key:"/system-notices",icon:a.jsx(oc,{}),label:"系统通知",show:G},{key:"/announcements",icon:a.jsx(oc,{}),label:fe("公告管理"),show:!1,disabled:!0}]},{key:"logs",icon:a.jsx(lc,{}),label:"日志审计",show:!0,children:[{key:"/audit-logs",icon:a.jsx(lc,{}),label:"操作日志",show:se("view_audit_log")},{key:"/user-account-audit",icon:a.jsx(po,{}),label:"用户账号审计",show:se("view_audit_log")},{key:"/group-events",icon:a.jsx(Xh,{}),label:"群事件审计",show:se("view_audit_log")},{key:"/admin-login-history",icon:a.jsx(po,{}),label:"管理员登录",show:!0},{key:"/user-login-history",icon:a.jsx($n,{}),label:"用户登录",show:!0},{key:"/ip-user-stats",icon:a.jsx(Yo,{}),label:"IP 账号统计",show:!0},{key:"/login-failure-logs",icon:a.jsx(ic,{}),label:"登录失败日志",show:!0}]},{key:"settings",icon:a.jsx(cc,{}),label:"系统设置",show:!0,children:[{key:"/tenant-settings",icon:a.jsx(cc,{}),label:"私域设置",show:!0},{key:"/security-settings",icon:a.jsx(Go,{}),label:"安全策略",show:!0},{key:"/domain-encrypt",icon:a.jsx(Yo,{}),label:"域名管理",show:G}]}],nt=Tt=>Tt.filter(yt=>yt.show).map(({show:yt,children:De,...Ce})=>({...Ce,...De?{children:nt(De)}:{}})).filter(yt=>!yt.children||yt.children.length>0);return nt(Ue)},[j,R]),z=g.useMemo(()=>Object.keys(Ro).find(fe=>v.pathname===fe),[v.pathname]),D=fe=>{const Re=Ro[fe]||fe;V({key:fe,label:Re}),w(fe)},q=fe=>{_e(fe),w(fe)},K=(fe,Re)=>{var Ue;if(Re==="remove"&&typeof fe=="string"){const nt=X(fe);(Ue=J.current)==null||Ue.destroy(fe),fe===v.pathname&&w(nt)}},Z=Cx(Ix(jl,{activationConstraint:{distance:10}})),me=({active:fe,over:Re})=>{if(Re&&fe.id!==Re.id){const Ue=Oo.getState().tabs,nt=Ue.findIndex(yt=>yt.key===fe.id),Tt=Ue.findIndex(yt=>yt.key===Re.id);nt>=0&&Tt>=0&&B(nt,Tt)}},ie=async fe=>{o(!0);try{const Re=await dn.changePassword({old_password:fe.old_password,new_password:fe.new_password});Re.code===0||Re.code===200?(E.success("密码修改成功,请重新登录"),n(!1),s.resetFields(),he()):E.error(Re.message||"密码修改失败")}catch(Re){E.error(Re.message||"密码修改失败")}finally{o(!1)}},he=()=>{Oo.getState().clear(),C(),w("/login")},we=async()=>{var fe;c(!0),u(!0),x(null),p("");try{const Re=await dn.getTOTPStatus();Re.code===0||Re.code===200?m(((fe=Re.data)==null?void 0:fe.enabled)??!1):E.error(Re.message||"获取验证器状态失败")}catch(Re){E.error(Re.message||"获取验证器状态失败")}finally{u(!1)}},He=async()=>{u(!0);try{const fe=await dn.setupTOTP();(fe.code===0||fe.code===200)&&fe.data?x({secret:fe.data.secret,qr_code_url:fe.data.qr_code_url}):E.error(fe.message||"生成验证器失败")}catch(fe){E.error(fe.message||"生成验证器失败")}finally{u(!1)}},ze=async()=>{if(!_||!/^\d{6}$/.test(f)){E.error("请输入 6 位验证码");return}S(!0);try{const fe=await dn.bindTOTP({secret:_.secret,totp_code:f});if(fe.code===0||fe.code===200){E.success("谷歌验证器绑定成功"),m(!0),x(null),p("");const Re=await dn.profile();Re.data&&T(Re.data)}else E.error(fe.message||"绑定失败")}catch(fe){E.error(fe.message||"绑定失败")}finally{S(!1)}},gt=async()=>{S(!0);try{const fe=await dn.unbindTOTP();if(fe.code===0||fe.code===200){E.success("谷歌验证器已解绑"),m(!1),x(null),p("");const Re=await dn.profile();Re.data&&T(Re.data)}else E.error(fe.message||"解绑失败")}catch(fe){E.error(fe.message||"解绑失败")}finally{S(!1)}},qe={items:[{key:"change-password",icon:a.jsx(pi,{}),label:"修改密码",onClick:()=>n(!0)},{key:"totp",icon:a.jsx(Ks,{}),label:"谷歌验证器",onClick:we},{key:"logout",icon:a.jsx(em,{}),label:"退出登录",onClick:he}]},le=F.map(fe=>({key:fe.key,label:fe.label,closable:F.length>1}));return a.jsxs(Ko,{className:"admin-layout",children:[a.jsxs(E_,{collapsible:!0,collapsed:e,onCollapse:fe=>t(fe),breakpoint:"lg",className:"admin-sider",children:[a.jsx("div",{className:"admin-logo",onClick:()=>D("/dashboard"),children:a.jsx("span",{className:"admin-logo-text",children:e?"鸽达达":"鸽达达管理后台"})}),a.jsx(Jh,{mode:"inline",items:W,selectedKeys:z?[z]:[],openKeys:de,onOpenChange:fe=>k(fe),onClick:fe=>D(fe.key)})]}),a.jsxs(Ko,{children:[a.jsxs(b_,{className:"admin-header",children:[a.jsxs(Ie,{size:12,children:[a.jsx(da,{icon:a.jsx(ca,{})}),a.jsxs("div",{className:"admin-user",children:[a.jsx(id,{strong:!0,children:(R==null?void 0:R.nickname)||(R==null?void 0:R.username)||"管理员"}),a.jsx(id,{type:"secondary",className:"admin-user-sub",children:(R==null?void 0:R.username)||"--"})]})]}),a.jsx(Zh,{menu:qe,placement:"bottomRight",children:a.jsx("a",{className:"admin-logout-link",onClick:fe=>fe.preventDefault(),children:"账户操作"})})]}),a.jsx("div",{className:"admin-tabs",children:a.jsx(Op,{sensors:Z,collisionDetection:Rx,onDragEnd:me,children:a.jsx(Vp,{items:F.map(fe=>fe.key),strategy:Wp,children:a.jsx(zi,{type:"editable-card",hideAdd:!0,activeKey:P,items:le,onChange:q,onEdit:K,size:"small",renderTabBar:(fe,Re)=>a.jsx(Re,{...fe,children:Ue=>a.jsx(I_,{id:String(Ue.key),children:Ue},Ue.key)})})})})}),a.jsx(j_,{className:"admin-content",children:a.jsx(f1,{activeCacheKey:v.pathname,max:15,aliveRef:J,children:y})})]}),a.jsx(Me,{title:"修改密码",open:r,onCancel:()=>{n(!1),s.resetFields()},onOk:()=>s.submit(),confirmLoading:i,children:a.jsxs(b,{form:s,layout:"vertical",onFinish:ie,children:[a.jsx(b.Item,{label:"当前密码",name:"old_password",rules:[{required:!0,message:"请输入当前密码"},{min:6,message:"密码至少 6 个字符"}],children:a.jsx(ve.Password,{placeholder:"请输入当前密码"})}),a.jsx(b.Item,{label:"新密码",name:"new_password",tooltip:"至少 8 位,需包含大小写字母和数字",rules:[{required:!0,message:"请输入新密码"},{min:8,message:"密码至少 8 位"},{pattern:/^[\x21-\x7e]+$/,message:"只能包含英文字母、数字和英文特殊字符"},{pattern:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/,message:"必须包含大小写字母和数字"}],children:a.jsx(ve.Password,{placeholder:"请输入新密码"})}),a.jsx(b.Item,{label:"确认新密码",name:"confirm_password",dependencies:["new_password"],rules:[{required:!0,message:"请再次输入新密码"},({getFieldValue:fe})=>({validator(Re,Ue){return!Ue||fe("new_password")===Ue?Promise.resolve():Promise.reject(new Error("两次输入的密码不一致"))}})],children:a.jsx(ve.Password,{placeholder:"请再次输入新密码"})})]})}),a.jsx(Me,{title:"谷歌验证器",open:l,onCancel:()=>{c(!1),x(null),p("")},footer:null,destroyOnClose:!0,children:a.jsxs(Mn,{spinning:d,children:[h===!0&&!_&&a.jsxs("div",{style:{textAlign:"center",padding:"24px 0"},children:[a.jsx(Ks,{style:{fontSize:48,color:"#52c41a",marginBottom:16}}),a.jsx("p",{children:"您已绑定谷歌验证器"}),a.jsx("p",{style:{color:"#999",fontSize:12},children:"登录时将需要输入谷歌验证码"}),a.jsx(Y,{danger:!0,onClick:gt,loading:I,style:{marginTop:16},children:"解绑验证器"})]}),h===!1&&!_&&a.jsxs("div",{style:{textAlign:"center",padding:"24px 0"},children:[a.jsx(Ks,{style:{fontSize:48,color:"#bfbfbf",marginBottom:16}}),a.jsx("p",{children:"您尚未绑定谷歌验证器"}),a.jsx("p",{style:{color:"#999",fontSize:12},children:"绑定后登录时将需要输入谷歌验证码"}),a.jsx(Y,{type:"primary",onClick:He,style:{marginTop:16},children:"绑定验证器"})]}),_&&a.jsxs("div",{style:{padding:"16px 0"},children:[a.jsx("p",{style:{textAlign:"center",marginBottom:16},children:"请使用 Google Authenticator 或其他验证器 App 扫描下方二维码"}),a.jsx("div",{style:{textAlign:"center",marginBottom:16},children:a.jsx(Qh,{value:_.qr_code_url,size:200})}),a.jsx(je,{size:"small",bordered:!0,column:1,children:a.jsx(je.Item,{label:"密钥",children:_.secret})}),a.jsx("div",{style:{marginTop:16},children:a.jsx(ve,{placeholder:"请输入验证器显示的 6 位验证码",maxLength:6,value:f,onChange:fe=>p(fe.target.value),onPressEnter:ze})}),a.jsxs("div",{style:{textAlign:"center",marginTop:16},children:[a.jsx(Y,{type:"primary",onClick:ze,loading:I,children:"确认绑定"}),a.jsx(Y,{style:{marginLeft:8},onClick:()=>{x(null),p("")},children:"取消"})]})]})]})})]})},{Title:A_,Text:k_}=Cr,F_=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState(!1),[s,i]=g.useState(null),o=wu(),{setAuth:l}=pt(),c=async d=>{t(!0);try{const u={username:d.username.trim(),password:d.password.trim()};r&&d.totp_code&&(u.totp_code=d.totp_code.trim());const h=await dn.login(u);if((h.code===0||h.code===200)&&h.data){if(h.data.totp_required){n(!0),i({username:d.username.trim(),password:d.password.trim()}),E.info("请输入谷歌验证码"),t(!1);return}l(h.data.admin,h.data.token,h.data.permissions),E.success("登录成功"),o("/dashboard")}else E.error(h.message||"登录失败")}catch(u){E.error(u.message||"登录失败,请检查用户名和密码")}finally{t(!1)}};return a.jsx("div",{className:"admin-login",children:a.jsxs(be,{className:"admin-login-card",children:[a.jsxs("div",{className:"admin-login-header",children:[a.jsx(A_,{level:2,children:"管理后台"}),a.jsx(k_,{type:"secondary",children:"鸽达达"})]}),a.jsxs(b,{name:"admin-login",onFinish:c,autoComplete:"off",size:"large",initialValues:s||{},children:[a.jsx(b.Item,{name:"username",rules:[{required:!0,message:"请输入用户名"},{whitespace:!0,message:"用户名不能为空格"},{min:3,message:"用户名至少 3 个字符"}],children:a.jsx(ve,{prefix:a.jsx(ca,{}),placeholder:"用户名",disabled:r})}),a.jsx(b.Item,{name:"password",rules:[{required:!0,message:"请输入密码"},{whitespace:!0,message:"密码不能为空格"},{min:6,message:"密码至少 6 个字符"}],children:a.jsx(ve.Password,{prefix:a.jsx(pi,{}),placeholder:"密码",disabled:r})}),r&&a.jsx(b.Item,{name:"totp_code",rules:[{required:!0,message:"请输入谷歌验证码"},{pattern:/^\d{6}$/,message:"请输入 6 位数字验证码"}],children:a.jsx(ve,{prefix:a.jsx(Go,{}),placeholder:"谷歌验证码",maxLength:6,autoFocus:!0})}),a.jsx(b.Item,{children:a.jsx(Y,{type:"primary",htmlType:"submit",loading:e,block:!0,children:r?"验证并登录":"登录"})}),r&&a.jsx(b.Item,{style:{marginBottom:0},children:a.jsx(Y,{type:"link",block:!0,onClick:()=>{n(!1),i(null)},children:"返回用户名密码登录"})})]})]})})},O_=()=>{const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),[n,s]=g.useState(!1),[i,o]=g.useState(null),[l,c]=g.useState([]),[d,u]=g.useState(!1),h=async()=>{u(!0);try{const f=await hn.list({page:1,page_size:1e3});(f.code===0||f.code===200)&&f.data&&c(f.data.items||[])}catch(f){E.error(f.message||"获取私域列表失败")}finally{u(!1)}},m=async f=>{s(!0);try{const p=await x_.get(f);(p.code===0||p.code===200)&&p.data?o(p.data):E.error(p.message||"获取统计数据失败")}catch(p){E.error(p.message||"获取统计数据失败")}finally{s(!1)}};g.useEffect(()=>{r&&h(),m()},[r]);const _=[{title:"日期",dataIndex:"date"},{title:"数量",dataIndex:"count"}],x=f=>a.jsx(Ye,{rowKey:"date",dataSource:f||[],columns:_,pagination:!1,size:"small"});return a.jsxs("div",{className:"admin-dashboard",children:[r&&a.jsx(be,{className:"admin-dashboard-filter",children:a.jsxs(b,{layout:"inline",onFinish:f=>m(f.tenant_id),children:[a.jsx(b.Item,{label:"选择私域",name:"tenant_id",children:a.jsx($e,{placeholder:"全部私域",allowClear:!0,style:{width:200},loading:d,options:[...l.map(f=>({label:`${f.name} (ID: ${f.id})`,value:f.id}))]})}),a.jsx(b.Item,{children:a.jsx(Y,{type:"primary",htmlType:"submit",loading:n,children:"刷新"})})]})}),a.jsxs(Es,{gutter:[16,16],className:"admin-dashboard-cards",children:[a.jsx(Ct,{xs:24,sm:12,lg:8,children:a.jsx(be,{children:a.jsx(tn,{title:"总用户数",value:(i==null?void 0:i.total_users)??0,loading:n})})}),a.jsx(Ct,{xs:24,sm:12,lg:8,children:a.jsx(be,{children:a.jsx(tn,{title:"活跃用户",value:(i==null?void 0:i.active_users)??0,loading:n})})}),a.jsx(Ct,{xs:24,sm:12,lg:8,children:a.jsx(be,{children:a.jsx(tn,{title:"总群组数",value:(i==null?void 0:i.total_groups)??0,loading:n})})}),a.jsx(Ct,{xs:24,sm:12,lg:8,children:a.jsx(be,{children:a.jsx(tn,{title:"总会话数",value:(i==null?void 0:i.total_conversations)??0,loading:n})})}),a.jsx(Ct,{xs:24,sm:12,lg:8,children:a.jsx(be,{children:a.jsx(tn,{title:"总消息数",value:(i==null?void 0:i.total_messages)??0,loading:n})})}),a.jsx(Ct,{xs:24,sm:12,lg:8,children:a.jsx(be,{children:a.jsx(tn,{title:"今日消息",value:(i==null?void 0:i.today_messages)??0,loading:n})})})]}),a.jsxs(Es,{gutter:[16,16],children:[a.jsx(Ct,{xs:24,lg:12,children:a.jsx(be,{title:"用户增长趋势",loading:n,children:x(i==null?void 0:i.user_growth)})}),a.jsx(Ct,{xs:24,lg:12,children:a.jsx(be,{title:"消息增长趋势",loading:n,children:x(i==null?void 0:i.message_growth)})})]})]})},Fn={list:e=>ce.get("/admin/user-policy-groups",{params:e?{tenant_id:e}:void 0}),create:e=>ce.post("/admin/user-policy-groups",e),update:(e,t)=>ce.put(`/admin/user-policy-groups/${e}`,t),delete:(e,t)=>ce.delete(`/admin/user-policy-groups/${e}`,{params:t?{tenant_id:t}:void 0}),assignUsers:(e,t,r)=>ce.put(`/admin/user-policy-groups/${e}/users`,{tenant_id:t,user_ids:r}),getIPWhitelist:e=>ce.get("/admin/user-policy-groups/ip-whitelist",{params:e?{tenant_id:e}:void 0}),updateIPWhitelist:e=>ce.put("/admin/user-policy-groups/ip-whitelist",e)};function Yr(){const{tenants:e,tenantOptions:t,tenantMap:r,renderTenantId:n,fetchTenants:s}=G0();return g.useEffect(()=>{e.length===0&&s()},[]),{tenants:e,tenantOptions:t,tenantMap:r,renderTenantId:n,fetchTenants:s}}const ot=({showSearch:e=!0,placeholder:t="请选择租户",pageSize:r=50,...n})=>{const[s,i]=g.useState([]),[o,l]=g.useState(!1),c=g.useRef(),d=async h=>{l(!0);try{const m=await hn.list({keyword:(h==null?void 0:h.trim())||void 0,page:1,page_size:r});(m.code===0||m.code===200)&&m.data&&i(m.data.items.map(x=>({label:`${x.name} (${x.code})`,value:x.id})))}catch{}finally{l(!1)}},u=h=>{c.current&&clearTimeout(c.current),c.current=setTimeout(()=>{d(h)},300)};return g.useEffect(()=>(d(),()=>{c.current&&clearTimeout(c.current)}),[]),a.jsx($e,{showSearch:e,placeholder:t,filterOption:!1,loading:o,options:s,onSearch:u,...n})},Ke=e=>e?tm(e).format("YYYY-MM-DD HH:mm:ss"):"--",Y0={minLength:8,requireLetter:!0};function od(e){return`至少 ${e.minLength} 位,需包含数字${e.requireLetter?"和字母":""}`}function ld(e,t="请输入密码"){return[{required:!0,message:t},{min:e.minLength,message:`密码至少 ${e.minLength} 位`},{pattern:/^[\x21-\x7e]+$/,message:"只能包含英文字母、数字和英文特殊字符"},{pattern:/\d/,message:"必须包含数字"},...e.requireLetter?[{pattern:/[a-zA-Z]/,message:"必须包含字母"}]:[]]}async function R_(e){try{const t=await pa.getSettings(e?{tenant_id:e}:void 0);if((t.code===0||t.code===200)&&t.data)return{minLength:t.data.password_min_length||8,requireLetter:t.data.password_require_letter??!0}}catch{}return Y0}function Za(e=12){const t="ABCDEFGHIJKLMNOPQRSTUVWXYZ",r="abcdefghijklmnopqrstuvwxyz",n="0123456789",s=t+r+n,i=Math.max(e,12),o=[t[Math.floor(Math.random()*t.length)],r[Math.floor(Math.random()*r.length)],n[Math.floor(Math.random()*n.length)]];for(;o.length0;l--){const c=Math.floor(Math.random()*(l+1));[o[l],o[c]]=[o[c],o[l]]}return o.join("")}/*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */var ji={};ji.version="0.18.5";var q0=1252,D_=[874,932,936,949,950,1250,1251,1252,1253,1254,1255,1256,1257,1258,1e4],X0=function(e){D_.indexOf(e)!=-1&&(q0=e)};function P_(){X0(1252)}var ga=function(e){X0(e)};function N_(){ga(1200),P_()}var Qa=function(t){return String.fromCharCode(t)},cd=function(t){return String.fromCharCode(t)},Ii,Rn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function _a(e){for(var t="",r=0,n=0,s=0,i=0,o=0,l=0,c=0,d=0;d>2,n=e.charCodeAt(d++),o=(r&3)<<4|n>>4,s=e.charCodeAt(d++),l=(n&15)<<2|s>>6,c=s&63,isNaN(n)?l=c=64:isNaN(s)&&(c=64),t+=Rn.charAt(i)+Rn.charAt(o)+Rn.charAt(l)+Rn.charAt(c);return t}function vn(e){var t="",r=0,n=0,s=0,i=0,o=0,l=0,c=0;e=e.replace(/[^\w\+\/\=]/g,"");for(var d=0;d>4,t+=String.fromCharCode(r),l=Rn.indexOf(e.charAt(d++)),n=(o&15)<<4|l>>2,l!==64&&(t+=String.fromCharCode(n)),c=Rn.indexOf(e.charAt(d++)),s=(l&3)<<6|c,c!==64&&(t+=String.fromCharCode(s));return t}var ct=function(){return typeof Buffer<"u"&&typeof process<"u"&&typeof process.versions<"u"&&!!process.versions.node}(),wn=function(){if(typeof Buffer<"u"){var e=!Buffer.from;if(!e)try{Buffer.from("foo","utf8")}catch{e=!0}return e?function(t,r){return r?new Buffer(t,r):new Buffer(t)}:Buffer.from.bind(Buffer)}return function(){}}();function Jn(e){return ct?Buffer.alloc?Buffer.alloc(e):new Buffer(e):typeof Uint8Array<"u"?new Uint8Array(e):new Array(e)}function dd(e){return ct?Buffer.allocUnsafe?Buffer.allocUnsafe(e):new Buffer(e):typeof Uint8Array<"u"?new Uint8Array(e):new Array(e)}var Wr=function(t){return ct?wn(t,"binary"):t.split("").map(function(r){return r.charCodeAt(0)&255})};function oo(e){if(typeof ArrayBuffer>"u")return Wr(e);for(var t=new ArrayBuffer(e.length),r=new Uint8Array(t),n=0;n!=e.length;++n)r[n]=e.charCodeAt(n)&255;return t}function Da(e){if(Array.isArray(e))return e.map(function(n){return String.fromCharCode(n)}).join("");for(var t=[],r=0;r"u")throw new Error("Unsupported");return new Uint8Array(e)}var Yt=ct?function(e){return Buffer.concat(e.map(function(t){return Buffer.isBuffer(t)?t:wn(t)}))}:function(e){if(typeof Uint8Array<"u"){var t=0,r=0;for(t=0;t>6&31,s[r++]=128|o&63;else if(o>=55296&&o<57344){o=(o&1023)+64;var l=e.charCodeAt(++i)&1023;s[r++]=240|o>>8&7,s[r++]=128|o>>2&63,s[r++]=128|l>>6&15|(o&3)<<4,s[r++]=128|l&63}else s[r++]=224|o>>12&15,s[r++]=128|o>>6&63,s[r++]=128|o&63;r>n&&(t.push(s.slice(0,r)),r=0,s=Jn(65535),n=65530)}return t.push(s.slice(0,r)),Yt(t)}var ra=/\u0000/g,ei=/[\u0001-\u0006]/g;function ws(e){for(var t="",r=e.length-1;r>=0;)t+=e.charAt(r--);return t}function Hr(e,t){var r=""+e;return r.length>=t?r:Et("0",t-r.length)+r}function Pl(e,t){var r=""+e;return r.length>=t?r:Et(" ",t-r.length)+r}function Ci(e,t){var r=""+e;return r.length>=t?r:r+Et(" ",t-r.length)}function B_(e,t){var r=""+Math.round(e);return r.length>=t?r:Et("0",t-r.length)+r}function U_(e,t){var r=""+e;return r.length>=t?r:Et("0",t-r.length)+r}var ud=Math.pow(2,32);function us(e,t){if(e>ud||e<-ud)return B_(e,t);var r=Math.round(e);return U_(r,t)}function Ai(e,t){return t=t||0,e.length>=7+t&&(e.charCodeAt(t)|32)===103&&(e.charCodeAt(t+1)|32)===101&&(e.charCodeAt(t+2)|32)===110&&(e.charCodeAt(t+3)|32)===101&&(e.charCodeAt(t+4)|32)===114&&(e.charCodeAt(t+5)|32)===97&&(e.charCodeAt(t+6)|32)===108}var fd=[["Sun","Sunday"],["Mon","Monday"],["Tue","Tuesday"],["Wed","Wednesday"],["Thu","Thursday"],["Fri","Friday"],["Sat","Saturday"]],Do=[["J","Jan","January"],["F","Feb","February"],["M","Mar","March"],["A","Apr","April"],["M","May","May"],["J","Jun","June"],["J","Jul","July"],["A","Aug","August"],["S","Sep","September"],["O","Oct","October"],["N","Nov","November"],["D","Dec","December"]];function z_(e){return e||(e={}),e[0]="General",e[1]="0",e[2]="0.00",e[3]="#,##0",e[4]="#,##0.00",e[9]="0%",e[10]="0.00%",e[11]="0.00E+00",e[12]="# ?/?",e[13]="# ??/??",e[14]="m/d/yy",e[15]="d-mmm-yy",e[16]="d-mmm",e[17]="mmm-yy",e[18]="h:mm AM/PM",e[19]="h:mm:ss AM/PM",e[20]="h:mm",e[21]="h:mm:ss",e[22]="m/d/yy h:mm",e[37]="#,##0 ;(#,##0)",e[38]="#,##0 ;[Red](#,##0)",e[39]="#,##0.00;(#,##0.00)",e[40]="#,##0.00;[Red](#,##0.00)",e[45]="mm:ss",e[46]="[h]:mm:ss",e[47]="mmss.0",e[48]="##0.0E+0",e[49]="@",e[56]='"上午/下午 "hh"時"mm"分"ss"秒 "',e}var jt={0:"General",1:"0",2:"0.00",3:"#,##0",4:"#,##0.00",9:"0%",10:"0.00%",11:"0.00E+00",12:"# ?/?",13:"# ??/??",14:"m/d/yy",15:"d-mmm-yy",16:"d-mmm",17:"mmm-yy",18:"h:mm AM/PM",19:"h:mm:ss AM/PM",20:"h:mm",21:"h:mm:ss",22:"m/d/yy h:mm",37:"#,##0 ;(#,##0)",38:"#,##0 ;[Red](#,##0)",39:"#,##0.00;(#,##0.00)",40:"#,##0.00;[Red](#,##0.00)",45:"mm:ss",46:"[h]:mm:ss",47:"mmss.0",48:"##0.0E+0",49:"@",56:'"上午/下午 "hh"時"mm"分"ss"秒 "'},hd={5:37,6:38,7:39,8:40,23:0,24:0,25:0,26:0,27:14,28:14,29:14,30:14,31:14,50:14,51:14,52:14,53:14,54:14,55:14,56:14,57:14,58:14,59:1,60:2,61:3,62:4,67:9,68:10,69:12,70:13,71:14,72:14,73:15,74:16,75:17,76:20,77:21,78:22,79:45,80:46,81:47,82:0},$_={5:'"$"#,##0_);\\("$"#,##0\\)',63:'"$"#,##0_);\\("$"#,##0\\)',6:'"$"#,##0_);[Red]\\("$"#,##0\\)',64:'"$"#,##0_);[Red]\\("$"#,##0\\)',7:'"$"#,##0.00_);\\("$"#,##0.00\\)',65:'"$"#,##0.00_);\\("$"#,##0.00\\)',8:'"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',66:'"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',41:'_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)',42:'_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)',43:'_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)',44:'_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'};function ki(e,t,r){for(var n=e<0?-1:1,s=e*n,i=0,o=1,l=0,c=1,d=0,u=0,h=Math.floor(s);dt&&(d>t?(u=c,l=i):(u=d,l=o)),!r)return[0,n*l,u];var m=Math.floor(n*l/u);return[m,n*l-m*u,u]}function ti(e,t,r){if(e>2958465||e<0)return null;var n=e|0,s=Math.floor(86400*(e-n)),i=0,o=[],l={D:n,T:s,u:86400*(e-n)-s,y:0,m:0,d:0,H:0,M:0,S:0,q:0};if(Math.abs(l.u)<1e-6&&(l.u=0),t&&t.date1904&&(n+=1462),l.u>.9999&&(l.u=0,++s==86400&&(l.T=s=0,++n,++l.D)),n===60)o=r?[1317,10,29]:[1900,2,29],i=3;else if(n===0)o=r?[1317,8,29]:[1900,1,0],i=6;else{n>60&&--n;var c=new Date(1900,0,1);c.setDate(c.getDate()+n-1),o=[c.getFullYear(),c.getMonth()+1,c.getDate()],i=c.getDay(),n<60&&(i=(i+6)%7),r&&(i=q_(c,o))}return l.y=o[0],l.m=o[1],l.d=o[2],l.S=s%60,s=Math.floor(s/60),l.M=s%60,s=Math.floor(s/60),l.H=s,l.q=i,l}var J0=new Date(1899,11,31,0,0,0),W_=J0.getTime(),H_=new Date(1900,2,1,0,0,0);function Z0(e,t){var r=e.getTime();return t?r-=1461*24*60*60*1e3:e>=H_&&(r+=24*60*60*1e3),(r-(W_+(e.getTimezoneOffset()-J0.getTimezoneOffset())*6e4))/(24*60*60*1e3)}function Nl(e){return e.indexOf(".")==-1?e:e.replace(/(?:\.0*|(\.\d*[1-9])0+)$/,"$1")}function V_(e){return e.indexOf("E")==-1?e:e.replace(/(?:\.0*|(\.\d*[1-9])0+)[Ee]/,"$1E").replace(/(E[+-])(\d)$/,"$10$2")}function K_(e){var t=e<0?12:11,r=Nl(e.toFixed(12));return r.length<=t||(r=e.toPrecision(10),r.length<=t)?r:e.toExponential(5)}function G_(e){var t=Nl(e.toFixed(11));return t.length>(e<0?12:11)||t==="0"||t==="-0"?e.toPrecision(6):t}function Y_(e){var t=Math.floor(Math.log(Math.abs(e))*Math.LOG10E),r;return t>=-4&&t<=-1?r=e.toPrecision(10+t):Math.abs(t)<=9?r=K_(e):t===10?r=e.toFixed(10).substr(0,12):r=G_(e),Nl(V_(r.toUpperCase()))}function ul(e,t){switch(typeof e){case"string":return e;case"boolean":return e?"TRUE":"FALSE";case"number":return(e|0)===e?e.toString(10):Y_(e);case"undefined":return"";case"object":if(e==null)return"";if(e instanceof Date)return Pn(14,Z0(e,t&&t.date1904),t)}throw new Error("unsupported value in General format: "+e)}function q_(e,t){t[0]-=581;var r=e.getDay();return e<60&&(r=(r+6)%7),r}function X_(e,t,r,n){var s="",i=0,o=0,l=r.y,c,d=0;switch(e){case 98:l=r.y+543;case 121:switch(t.length){case 1:case 2:c=l%100,d=2;break;default:c=l%1e4,d=4;break}break;case 109:switch(t.length){case 1:case 2:c=r.m,d=t.length;break;case 3:return Do[r.m-1][1];case 5:return Do[r.m-1][0];default:return Do[r.m-1][2]}break;case 100:switch(t.length){case 1:case 2:c=r.d,d=t.length;break;case 3:return fd[r.q][0];default:return fd[r.q][1]}break;case 104:switch(t.length){case 1:case 2:c=1+(r.H+11)%12,d=t.length;break;default:throw"bad hour format: "+t}break;case 72:switch(t.length){case 1:case 2:c=r.H,d=t.length;break;default:throw"bad hour format: "+t}break;case 77:switch(t.length){case 1:case 2:c=r.M,d=t.length;break;default:throw"bad minute format: "+t}break;case 115:if(t!="s"&&t!="ss"&&t!=".0"&&t!=".00"&&t!=".000")throw"bad second format: "+t;return r.u===0&&(t=="s"||t=="ss")?Hr(r.S,t.length):(n>=2?o=n===3?1e3:100:o=n===1?10:1,i=Math.round(o*(r.S+r.u)),i>=60*o&&(i=0),t==="s"?i===0?"0":""+i/o:(s=Hr(i,2+n),t==="ss"?s.substr(0,2):"."+s.substr(2,t.length-1)));case 90:switch(t){case"[h]":case"[hh]":c=r.D*24+r.H;break;case"[m]":case"[mm]":c=(r.D*24+r.H)*60+r.M;break;case"[s]":case"[ss]":c=((r.D*24+r.H)*60+r.M)*60+Math.round(r.S+r.u);break;default:throw"bad abstime format: "+t}d=t.length===3?1:2;break;case 101:c=l,d=1;break}var u=d>0?Hr(c,d):"";return u}function Dn(e){var t=3;if(e.length<=t)return e;for(var r=e.length%t,n=e.substr(0,r);r!=e.length;r+=t)n+=(n.length>0?",":"")+e.substr(r,t);return n}var Q0=/%/g;function J_(e,t,r){var n=t.replace(Q0,""),s=t.length-n.length;return xn(e,n,r*Math.pow(10,2*s))+Et("%",s)}function Z_(e,t,r){for(var n=t.length-1;t.charCodeAt(n-1)===44;)--n;return xn(e,t.substr(0,n),r/Math.pow(10,3*(t.length-n)))}function ef(e,t){var r,n=e.indexOf("E")-e.indexOf(".")-1;if(e.match(/^#+0.0E\+0$/)){if(t==0)return"0.0E+0";if(t<0)return"-"+ef(e,-t);var s=e.indexOf(".");s===-1&&(s=e.indexOf("E"));var i=Math.floor(Math.log(t)*Math.LOG10E)%s;if(i<0&&(i+=s),r=(t/Math.pow(10,i)).toPrecision(n+1+(s+i)%s),r.indexOf("e")===-1){var o=Math.floor(Math.log(t)*Math.LOG10E);for(r.indexOf(".")===-1?r=r.charAt(0)+"."+r.substr(1)+"E+"+(o-r.length+i):r+="E+"+(o-i);r.substr(0,2)==="0.";)r=r.charAt(0)+r.substr(2,s)+"."+r.substr(2+s),r=r.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.");r=r.replace(/\+-/,"-")}r=r.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function(l,c,d,u){return c+d+u.substr(0,(s+i)%s)+"."+u.substr(i)+"E"})}else r=t.toExponential(n);return e.match(/E\+00$/)&&r.match(/e[+-]\d$/)&&(r=r.substr(0,r.length-1)+"0"+r.charAt(r.length-1)),e.match(/E\-/)&&r.match(/e\+/)&&(r=r.replace(/e\+/,"e")),r.replace("e","E")}var tf=/# (\?+)( ?)\/( ?)(\d+)/;function Q_(e,t,r){var n=parseInt(e[4],10),s=Math.round(t*n),i=Math.floor(s/n),o=s-i*n,l=n;return r+(i===0?"":""+i)+" "+(o===0?Et(" ",e[1].length+1+e[4].length):Pl(o,e[1].length)+e[2]+"/"+e[3]+Hr(l,e[4].length))}function ev(e,t,r){return r+(t===0?"":""+t)+Et(" ",e[1].length+2+e[4].length)}var rf=/^#*0*\.([0#]+)/,nf=/\).*[0#]/,sf=/\(###\) ###\\?-####/;function ir(e){for(var t="",r,n=0;n!=e.length;++n)switch(r=e.charCodeAt(n)){case 35:break;case 63:t+=" ";break;case 48:t+="0";break;default:t+=String.fromCharCode(r)}return t}function md(e,t){var r=Math.pow(10,t);return""+Math.round(e*r)/r}function xd(e,t){var r=e-Math.floor(e),n=Math.pow(10,t);return t<(""+Math.round(r*n)).length?0:Math.round(r*n)}function tv(e,t){return t<(""+Math.round((e-Math.floor(e))*Math.pow(10,t))).length?1:0}function rv(e){return e<2147483647&&e>-2147483648?""+(e>=0?e|0:e-1|0):""+Math.floor(e)}function Dr(e,t,r){if(e.charCodeAt(0)===40&&!t.match(nf)){var n=t.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");return r>=0?Dr("n",n,r):"("+Dr("n",n,-r)+")"}if(t.charCodeAt(t.length-1)===44)return Z_(e,t,r);if(t.indexOf("%")!==-1)return J_(e,t,r);if(t.indexOf("E")!==-1)return ef(t,r);if(t.charCodeAt(0)===36)return"$"+Dr(e,t.substr(t.charAt(1)==" "?2:1),r);var s,i,o,l,c=Math.abs(r),d=r<0?"-":"";if(t.match(/^00+$/))return d+us(c,t.length);if(t.match(/^[#?]+$/))return s=us(r,0),s==="0"&&(s=""),s.length>t.length?s:ir(t.substr(0,t.length-s.length))+s;if(i=t.match(tf))return Q_(i,c,d);if(t.match(/^#+0+$/))return d+us(c,t.length-t.indexOf("0"));if(i=t.match(rf))return s=md(r,i[1].length).replace(/^([^\.]+)$/,"$1."+ir(i[1])).replace(/\.$/,"."+ir(i[1])).replace(/\.(\d*)$/,function(x,f){return"."+f+Et("0",ir(i[1]).length-f.length)}),t.indexOf("0.")!==-1?s:s.replace(/^0\./,".");if(t=t.replace(/^#+([0.])/,"$1"),i=t.match(/^(0*)\.(#*)$/))return d+md(c,i[2].length).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,i[1].length?"0.":".");if(i=t.match(/^#{1,3},##0(\.?)$/))return d+Dn(us(c,0));if(i=t.match(/^#,##0\.([#0]*0)$/))return r<0?"-"+Dr(e,t,-r):Dn(""+(Math.floor(r)+tv(r,i[1].length)))+"."+Hr(xd(r,i[1].length),i[1].length);if(i=t.match(/^#,#*,#0/))return Dr(e,t.replace(/^#,#*,/,""),r);if(i=t.match(/^([0#]+)(\\?-([0#]+))+$/))return s=ws(Dr(e,t.replace(/[\\-]/g,""),r)),o=0,ws(ws(t.replace(/\\/g,"")).replace(/[0#]/g,function(x){return o=0?Qr("n",n,r):"("+Qr("n",n,-r)+")"}if(t.charCodeAt(t.length-1)===44)return nv(e,t,r);if(t.indexOf("%")!==-1)return sv(e,t,r);if(t.indexOf("E")!==-1)return af(t,r);if(t.charCodeAt(0)===36)return"$"+Qr(e,t.substr(t.charAt(1)==" "?2:1),r);var s,i,o,l,c=Math.abs(r),d=r<0?"-":"";if(t.match(/^00+$/))return d+Hr(c,t.length);if(t.match(/^[#?]+$/))return s=""+r,r===0&&(s=""),s.length>t.length?s:ir(t.substr(0,t.length-s.length))+s;if(i=t.match(tf))return ev(i,c,d);if(t.match(/^#+0+$/))return d+Hr(c,t.length-t.indexOf("0"));if(i=t.match(rf))return s=(""+r).replace(/^([^\.]+)$/,"$1."+ir(i[1])).replace(/\.$/,"."+ir(i[1])),s=s.replace(/\.(\d*)$/,function(x,f){return"."+f+Et("0",ir(i[1]).length-f.length)}),t.indexOf("0.")!==-1?s:s.replace(/^0\./,".");if(t=t.replace(/^#+([0.])/,"$1"),i=t.match(/^(0*)\.(#*)$/))return d+(""+c).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,i[1].length?"0.":".");if(i=t.match(/^#{1,3},##0(\.?)$/))return d+Dn(""+c);if(i=t.match(/^#,##0\.([#0]*0)$/))return r<0?"-"+Qr(e,t,-r):Dn(""+r)+"."+Et("0",i[1].length);if(i=t.match(/^#,#*,#0/))return Qr(e,t.replace(/^#,#*,/,""),r);if(i=t.match(/^([0#]+)(\\?-([0#]+))+$/))return s=ws(Qr(e,t.replace(/[\\-]/g,""),r)),o=0,ws(ws(t.replace(/\\/g,"")).replace(/[0#]/g,function(x){return o-1||r=="\\"&&e.charAt(t+1)=="-"&&"0#".indexOf(e.charAt(t+2))>-1););break;case"?":for(;e.charAt(++t)===r;);break;case"*":++t,(e.charAt(t)==" "||e.charAt(t)=="*")&&++t;break;case"(":case")":++t;break;case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":for(;t-1;);break;case" ":++t;break;default:++t;break}return!1}function iv(e,t,r,n){for(var s=[],i="",o=0,l="",c="t",d,u,h,m="H";o=12?"P":"A"),f.t="T",m="h",o+=3):e.substr(o,5).toUpperCase()==="AM/PM"?(d!=null&&(f.v=d.H>=12?"PM":"AM"),f.t="T",o+=5,m="h"):e.substr(o,5).toUpperCase()==="上午/下午"?(d!=null&&(f.v=d.H>=12?"下午":"上午"),f.t="T",o+=5,m="h"):(f.t="t",++o),d==null&&f.t==="T")return"";s[s.length]=f,c=l;break;case"[":for(i=l;e.charAt(o++)!=="]"&&o-1&&(i=(i.match(/\$([^-\[\]]*)/)||[])[1]||"$",lf(e)||(s[s.length]={t:"t",v:i}));break;case".":if(d!=null){for(i=l;++o-1;)i+=l;s[s.length]={t:"n",v:i};break;case"?":for(i=l;e.charAt(++o)===l;)i+=l;s[s.length]={t:l,v:i},c=l;break;case"*":++o,(e.charAt(o)==" "||e.charAt(o)=="*")&&++o;break;case"(":case")":s[s.length]={t:n===1?"t":l,v:l},++o;break;case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":for(i=l;o-1;)i+=e.charAt(o);s[s.length]={t:"D",v:i};break;case" ":s[s.length]={t:l,v:l},++o;break;case"$":s[s.length]={t:"t",v:"$"},++o;break;default:if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(l)===-1)throw new Error("unrecognized character "+l+" in "+e);s[s.length]={t:"t",v:l},++o;break}var p=0,I=0,S;for(o=s.length-1,c="t";o>=0;--o)switch(s[o].t){case"h":case"H":s[o].t=m,c="h",p<1&&(p=1);break;case"s":(S=s[o].v.match(/\.0+$/))&&(I=Math.max(I,S[0].length-1)),p<3&&(p=3);case"d":case"y":case"M":case"e":c=s[o].t;break;case"m":c==="s"&&(s[o].t="M",p<2&&(p=2));break;case"X":break;case"Z":p<1&&s[o].v.match(/[Hh]/)&&(p=1),p<2&&s[o].v.match(/[Mm]/)&&(p=2),p<3&&s[o].v.match(/[Ss]/)&&(p=3)}switch(p){case 0:break;case 1:d.u>=.5&&(d.u=0,++d.S),d.S>=60&&(d.S=0,++d.M),d.M>=60&&(d.M=0,++d.H);break;case 2:d.u>=.5&&(d.u=0,++d.S),d.S>=60&&(d.S=0,++d.M);break}var w="",v;for(o=0;o0){w.charCodeAt(0)==40?(R=t<0&&w.charCodeAt(0)===45?-t:t,j=xn("n",w,R)):(R=t<0&&n>1?-t:t,j=xn("n",w,R),R<0&&s[0]&&s[0].t=="t"&&(j=j.substr(1),s[0].v="-"+s[0].v)),v=j.length-1;var T=s.length;for(o=0;o-1){T=o;break}var C=s.length;if(T===s.length&&j.indexOf("E")===-1){for(o=s.length-1;o>=0;--o)s[o]==null||"n?".indexOf(s[o].t)===-1||(v>=s[o].v.length-1?(v-=s[o].v.length,s[o].v=j.substr(v+1,s[o].v.length)):v<0?s[o].v="":(s[o].v=j.substr(0,v+1),v=-1),s[o].t="t",C=o);v>=0&&C=0;--o)if(!(s[o]==null||"n?".indexOf(s[o].t)===-1)){for(u=s[o].v.indexOf(".")>-1&&o===T?s[o].v.indexOf(".")-1:s[o].v.length-1,y=s[o].v.substr(u+1);u>=0;--u)v>=0&&(s[o].v.charAt(u)==="0"||s[o].v.charAt(u)==="#")&&(y=j.charAt(v--)+y);s[o].v=y,s[o].t="t",C=o}for(v>=0&&C-1&&o===T?s[o].v.indexOf(".")+1:0,y=s[o].v.substr(0,u);u-1&&(R=n>1&&t<0&&o>0&&s[o-1].v==="-"?-t:t,s[o].v=xn(s[o].t,s[o].v,R),s[o].t="t");var F="";for(o=0;o!==s.length;++o)s[o]!=null&&(F+=s[o].v);return F}var pd=/\[(=|>[=]?|<[>=]?)(-?\d+(?:\.\d*)?)\]/;function gd(e,t){if(t==null)return!1;var r=parseFloat(t[2]);switch(t[1]){case"=":if(e==r)return!0;break;case">":if(e>r)return!0;break;case"<":if(e":if(e!=r)return!0;break;case">=":if(e>=r)return!0;break;case"<=":if(e<=r)return!0;break}return!1}function ov(e,t){var r=av(e),n=r.length,s=r[n-1].indexOf("@");if(n<4&&s>-1&&--n,r.length>4)throw new Error("cannot find right format for |"+r.join("|")+"|");if(typeof t!="number")return[4,r.length===4||s>-1?r[r.length-1]:"@"];switch(r.length){case 1:r=s>-1?["General","General","General",r[0]]:[r[0],r[0],r[0],"@"];break;case 2:r=s>-1?[r[0],r[0],r[0],r[1]]:[r[0],r[1],r[0],"@"];break;case 3:r=s>-1?[r[0],r[1],r[0],r[2]]:[r[0],r[1],r[2],"@"];break}var i=t>0?r[0]:t<0?r[1]:r[2];if(r[0].indexOf("[")===-1&&r[1].indexOf("[")===-1)return[n,i];if(r[0].match(/\[[=<>]/)!=null||r[1].match(/\[[=<>]/)!=null){var o=r[0].match(pd),l=r[1].match(pd);return gd(t,o)?[n,r[0]]:gd(t,l)?[n,r[1]]:[n,r[o!=null&&l!=null?2:1]]}return[n,i]}function Pn(e,t,r){r==null&&(r={});var n="";switch(typeof e){case"string":e=="m/d/yy"&&r.dateNF?n=r.dateNF:n=e;break;case"number":e==14&&r.dateNF?n=r.dateNF:n=(r.table!=null?r.table:jt)[e],n==null&&(n=r.table&&r.table[hd[e]]||jt[hd[e]]),n==null&&(n=$_[e]||"General");break}if(Ai(n,0))return ul(t,r);t instanceof Date&&(t=Z0(t,r.date1904));var s=ov(n,t);if(Ai(s[1]))return ul(t,r);if(t===!0)t="TRUE";else if(t===!1)t="FALSE";else if(t===""||t==null)return"";return iv(s[1],t,r,s[0])}function cf(e,t){if(typeof t!="number"){t=+t||-1;for(var r=0;r<392;++r){if(jt[r]==null){t<0&&(t=r);continue}if(jt[r]==e){t=r;break}}t<0&&(t=391)}return jt[t]=e,t}function lo(e){for(var t=0;t!=392;++t)e[t]!==void 0&&cf(e[t],t)}function co(){jt=z_()}var df=/[dD]+|[mM]+|[yYeE]+|[Hh]+|[Ss]+/g;function lv(e){var t=typeof e=="number"?jt[e]:e;return t=t.replace(df,"(\\d+)"),new RegExp("^"+t+"$")}function cv(e,t,r){var n=-1,s=-1,i=-1,o=-1,l=-1,c=-1;(t.match(df)||[]).forEach(function(h,m){var _=parseInt(r[m+1],10);switch(h.toLowerCase().charAt(0)){case"y":n=_;break;case"d":i=_;break;case"h":o=_;break;case"s":c=_;break;case"m":o>=0?l=_:s=_;break}}),c>=0&&l==-1&&s>=0&&(l=s,s=-1);var d=(""+(n>=0?n:new Date().getFullYear())).slice(-4)+"-"+("00"+(s>=1?s:1)).slice(-2)+"-"+("00"+(i>=1?i:1)).slice(-2);d.length==7&&(d="0"+d),d.length==8&&(d="20"+d);var u=("00"+(o>=0?o:0)).slice(-2)+":"+("00"+(l>=0?l:0)).slice(-2)+":"+("00"+(c>=0?c:0)).slice(-2);return o==-1&&l==-1&&c==-1?d:n==-1&&s==-1&&i==-1?u:d+"T"+u}var dv=function(){var e={};e.version="1.2.0";function t(){for(var j=0,T=new Array(256),C=0;C!=256;++C)j=C,j=j&1?-306674912^j>>>1:j>>>1,j=j&1?-306674912^j>>>1:j>>>1,j=j&1?-306674912^j>>>1:j>>>1,j=j&1?-306674912^j>>>1:j>>>1,j=j&1?-306674912^j>>>1:j>>>1,j=j&1?-306674912^j>>>1:j>>>1,j=j&1?-306674912^j>>>1:j>>>1,j=j&1?-306674912^j>>>1:j>>>1,T[C]=j;return typeof Int32Array<"u"?new Int32Array(T):T}var r=t();function n(j){var T=0,C=0,F=0,P=typeof Int32Array<"u"?new Int32Array(4096):new Array(4096);for(F=0;F!=256;++F)P[F]=j[F];for(F=0;F!=256;++F)for(C=j[F],T=256+F;T<4096;T+=256)C=P[T]=C>>>8^j[C&255];var V=[];for(F=1;F!=16;++F)V[F-1]=typeof Int32Array<"u"?P.subarray(F*256,F*256+256):P.slice(F*256,F*256+256);return V}var s=n(r),i=s[0],o=s[1],l=s[2],c=s[3],d=s[4],u=s[5],h=s[6],m=s[7],_=s[8],x=s[9],f=s[10],p=s[11],I=s[12],S=s[13],w=s[14];function v(j,T){for(var C=T^-1,F=0,P=j.length;F>>8^r[(C^j.charCodeAt(F++))&255];return~C}function y(j,T){for(var C=T^-1,F=j.length-15,P=0;P>8&255]^I[j[P++]^C>>16&255]^p[j[P++]^C>>>24]^f[j[P++]]^x[j[P++]]^_[j[P++]]^m[j[P++]]^h[j[P++]]^u[j[P++]]^d[j[P++]]^c[j[P++]]^l[j[P++]]^o[j[P++]]^i[j[P++]]^r[j[P++]];for(F+=15;P>>8^r[(C^j[P++])&255];return~C}function R(j,T){for(var C=T^-1,F=0,P=j.length,V=0,X=0;F>>8^r[(C^V)&255]:V<2048?(C=C>>>8^r[(C^(192|V>>6&31))&255],C=C>>>8^r[(C^(128|V&63))&255]):V>=55296&&V<57344?(V=(V&1023)+64,X=j.charCodeAt(F++)&1023,C=C>>>8^r[(C^(240|V>>8&7))&255],C=C>>>8^r[(C^(128|V>>2&63))&255],C=C>>>8^r[(C^(128|X>>6&15|(V&3)<<4))&255],C=C>>>8^r[(C^(128|X&63))&255]):(C=C>>>8^r[(C^(224|V>>12&15))&255],C=C>>>8^r[(C^(128|V>>6&63))&255],C=C>>>8^r[(C^(128|V&63))&255]);return~C}return e.table=r,e.bstr=v,e.buf=y,e.str=R,e}(),xt=function(){var t={};t.version="1.2.1";function r(A,L){for(var O=A.split("/"),N=L.split("/"),M=0,U=0,ne=Math.min(O.length,N.length);M>>1,A.write_shift(2,O);var N=L.getFullYear()-1980;N=N<<4|L.getMonth()+1,N=N<<5|L.getDate(),A.write_shift(2,N)}function o(A){var L=A.read_shift(2)&65535,O=A.read_shift(2)&65535,N=new Date,M=O&31;O>>>=5;var U=O&15;O>>>=4,N.setMilliseconds(0),N.setFullYear(O+1980),N.setMonth(U-1),N.setDate(M);var ne=L&31;L>>>=5;var ge=L&63;return L>>>=6,N.setHours(L),N.setMinutes(ge),N.setSeconds(ne<<1),N}function l(A){Tr(A,0);for(var L={},O=0;A.l<=A.length-4;){var N=A.read_shift(2),M=A.read_shift(2),U=A.l+M,ne={};switch(N){case 21589:O=A.read_shift(1),O&1&&(ne.mtime=A.read_shift(4)),M>5&&(O&2&&(ne.atime=A.read_shift(4)),O&4&&(ne.ctime=A.read_shift(4))),ne.mtime&&(ne.mt=new Date(ne.mtime*1e3));break}A.l=U,L[N]=ne}return L}var c;function d(){return c||(c={})}function u(A,L){if(A[0]==80&&A[1]==75)return bn(A,L);if((A[0]|32)==109&&(A[1]|32)==105)return Xr(A,L);if(A.length<512)throw new Error("CFB file size "+A.length+" < 512");var O=3,N=512,M=0,U=0,ne=0,ge=0,re=0,ae=[],oe=A.slice(0,512);Tr(oe,0);var Ee=h(oe);switch(O=Ee[0],O){case 3:N=512;break;case 4:N=4096;break;case 0:if(Ee[1]==0)return bn(A,L);default:throw new Error("Major Version: Expected 3 or 4 saw "+O)}N!==512&&(oe=A.slice(0,N),Tr(oe,28));var Pe=A.slice(0,N);m(oe,O);var Be=oe.read_shift(4,"i");if(O===3&&Be!==0)throw new Error("# Directory Sectors: Expected 0 saw "+Be);oe.l+=4,ne=oe.read_shift(4,"i"),oe.l+=4,oe.chk("00100000","Mini Stream Cutoff Size: "),ge=oe.read_shift(4,"i"),M=oe.read_shift(4,"i"),re=oe.read_shift(4,"i"),U=oe.read_shift(4,"i");for(var Ae=-1,Le=0;Le<109&&(Ae=oe.read_shift(4,"i"),!(Ae<0));++Le)ae[Le]=Ae;var H=_(A,N);p(re,U,H,N,ae);var ee=S(H,ne,ae,N);ee[ne].name="!Directory",M>0&&ge!==X&&(ee[ge].name="!MiniFAT"),ee[ae[0]].name="!FAT",ee.fat_addrs=ae,ee.ssz=N;var ye={},Ne=[],We=[],dt=[];w(ne,ee,H,Ne,M,ye,We,ge),x(We,dt,Ne),Ne.shift();var yr={FileIndex:We,FullPaths:dt};return L&&L.raw&&(yr.raw={header:Pe,sectors:H}),yr}function h(A){if(A[A.l]==80&&A[A.l+1]==75)return[0,0];A.chk(_e,"Header Signature: "),A.l+=16;var L=A.read_shift(2,"u");return[A.read_shift(2,"u"),L]}function m(A,L){var O=9;switch(A.l+=2,O=A.read_shift(2)){case 9:if(L!=3)throw new Error("Sector Shift: Expected 9 saw "+O);break;case 12:if(L!=4)throw new Error("Sector Shift: Expected 12 saw "+O);break;default:throw new Error("Sector Shift: Expected 9 or 12 saw "+O)}A.chk("0600","Mini Sector Shift: "),A.chk("000000000000","Reserved: ")}function _(A,L){for(var O=Math.ceil(A.length/L)-1,N=[],M=1;M0&&ne>=0;)U.push(L.slice(ne*V,ne*V+V)),M-=V,ne=Hn(O,ne*4);return U.length===0?pe(0):Yt(U).slice(0,A.size)}function p(A,L,O,N,M){var U=X;if(A===X){if(L!==0)throw new Error("DIFAT chain shorter than expected")}else if(A!==-1){var ne=O[A],ge=(N>>>2)-1;if(!ne)return;for(var re=0;re=0;){M[re]=!0,U[U.length]=re,ne.push(A[re]);var oe=O[Math.floor(re*4/N)];if(ae=re*4&ge,N<4+ae)throw new Error("FAT boundary crossed: "+re+" 4 "+N);if(!A[oe])break;re=Hn(A[oe],ae)}return{nodes:U,data:Ed([ne])}}function S(A,L,O,N){var M=A.length,U=[],ne=[],ge=[],re=[],ae=N-1,oe=0,Ee=0,Pe=0,Be=0;for(oe=0;oe=M&&(Pe-=M),!ne[Pe]){re=[];var Ae=[];for(Ee=Pe;Ee>=0;){Ae[Ee]=!0,ne[Ee]=!0,ge[ge.length]=Ee,re.push(A[Ee]);var Le=O[Math.floor(Ee*4/N)];if(Be=Ee*4&ae,N<4+Be)throw new Error("FAT boundary crossed: "+Ee+" 4 "+N);if(!A[Le]||(Ee=Hn(A[Le],Be),Ae[Ee]))break}U[Pe]={nodes:ge,data:Ed([re])}}return U}function w(A,L,O,N,M,U,ne,ge){for(var re=0,ae=N.length?2:0,oe=L[A].data,Ee=0,Pe=0,Be;Ee0&&re!==X&&(L[re].name="!StreamData")):Le.size>=4096?(Le.storage="fat",L[Le.start]===void 0&&(L[Le.start]=I(O,Le.start,L.fat_addrs,L.ssz)),L[Le.start].name=Le.name,Le.content=L[Le.start].data.slice(0,Le.size)):(Le.storage="minifat",Le.size<0?Le.size=0:re!==X&&Le.start!==X&&L[re]&&(Le.content=f(Le,L[re].data,(L[ge]||{}).data))),Le.content&&Tr(Le.content,0),U[Be]=Le,ne.push(Le)}}function v(A,L){return new Date((Er(A,L+4)/1e7*Math.pow(2,32)+Er(A,L)/1e7-11644473600)*1e3)}function y(A,L){return d(),u(c.readFileSync(A),L)}function R(A,L){var O=L&&L.type;switch(O||ct&&Buffer.isBuffer(A)&&(O="buffer"),O||"base64"){case"file":return y(A,L);case"base64":return u(Wr(vn(A)),L);case"binary":return u(Wr(A),L)}return u(A,L)}function j(A,L){var O=L||{},N=O.root||"Root Entry";if(A.FullPaths||(A.FullPaths=[]),A.FileIndex||(A.FileIndex=[]),A.FullPaths.length!==A.FileIndex.length)throw new Error("inconsistent CFB structure");A.FullPaths.length===0&&(A.FullPaths[0]=N+"/",A.FileIndex[0]={name:N,type:5}),O.CLSID&&(A.FileIndex[0].clsid=O.CLSID),T(A)}function T(A){var L="Sh33tJ5";if(!xt.find(A,"/"+L)){var O=pe(4);O[0]=55,O[1]=O[3]=50,O[2]=54,A.FileIndex.push({name:L,type:2,content:O,size:4,L:69,R:69,C:69}),A.FullPaths.push(A.FullPaths[0]+L),C(A)}}function C(A,L){j(A);for(var O=!1,N=!1,M=A.FullPaths.length-1;M>=0;--M){var U=A.FileIndex[M];switch(U.type){case 0:N?O=!0:(A.FileIndex.pop(),A.FullPaths.pop());break;case 1:case 2:case 5:N=!0,isNaN(U.R*U.L*U.C)&&(O=!0),U.R>-1&&U.L>-1&&U.R==U.L&&(O=!0);break;default:O=!0;break}}if(!(!O&&!L)){var ne=new Date(1987,1,19),ge=0,re=Object.create?Object.create(null):{},ae=[];for(M=0;M1?1:-1,Ee.size=0,Ee.type=5;else if(Pe.slice(-1)=="/"){for(ge=M+1;ge=ae.length?-1:ge,ge=M+1;ge=ae.length?-1:ge,Ee.type=1}else n(A.FullPaths[M+1]||"")==n(Pe)&&(Ee.R=M+1),Ee.type=2}}}function F(A,L){var O=L||{};if(O.fileType=="mad")return It(A,O);switch(C(A),O.fileType){case"zip":return St(A,O)}var N=function(Be){for(var Ae=0,Le=0,H=0;H0&&(ye<4096?Ae+=ye+63>>6:Le+=ye+511>>9)}}for(var Ne=Be.FullPaths.length+3>>2,We=Ae+7>>3,dt=Ae+127>>7,yr=We+Le+Ne+dt,bt=yr+127>>7,tr=bt<=109?0:Math.ceil((bt-109)/127);yr+bt+tr+127>>7>bt;)tr=++bt<=109?0:Math.ceil((bt-109)/127);var wt=[1,tr,bt,dt,Ne,Le,Ae,0];return Be.FileIndex[0].size=Ae<<6,wt[7]=(Be.FileIndex[0].start=wt[0]+wt[1]+wt[2]+wt[3]+wt[4]+wt[5])+(wt[6]+7>>3),wt}(A),M=pe(N[7]<<9),U=0,ne=0;{for(U=0;U<8;++U)M.write_shift(1,B[U]);for(U=0;U<8;++U)M.write_shift(2,0);for(M.write_shift(2,62),M.write_shift(2,3),M.write_shift(2,65534),M.write_shift(2,9),M.write_shift(2,6),U=0;U<3;++U)M.write_shift(2,0);for(M.write_shift(4,0),M.write_shift(4,N[2]),M.write_shift(4,N[0]+N[1]+N[2]+N[3]-1),M.write_shift(4,0),M.write_shift(4,4096),M.write_shift(4,N[3]?N[0]+N[1]+N[2]-1:X),M.write_shift(4,N[3]),M.write_shift(-4,N[1]?N[0]-1:X),M.write_shift(4,N[1]),U=0;U<109;++U)M.write_shift(-4,U>9)));for(ge(N[6]+7>>3);M.l&511;)M.write_shift(-4,J.ENDOFCHAIN);for(ne=U=0,re=0;re=4096)&&(oe.start=ne,ge(ae+63>>6)));for(;M.l&511;)M.write_shift(-4,J.ENDOFCHAIN);for(U=0;U=4096)if(M.l=oe.start+1<<9,ct&&Buffer.isBuffer(oe.content))oe.content.copy(M,M.l,0,oe.size),M.l+=oe.size+511&-512;else{for(re=0;re0&&oe.size<4096)if(ct&&Buffer.isBuffer(oe.content))oe.content.copy(M,M.l,0,oe.size),M.l+=oe.size+63&-64;else{for(re=0;re>16|L>>8|L)&255}for(var me=typeof Uint8Array<"u",ie=me?new Uint8Array(256):[],he=0;he<256;++he)ie[he]=Z(he);function we(A,L){var O=ie[A&255];return L<=8?O>>>8-L:(O=O<<8|ie[A>>8&255],L<=16?O>>>16-L:(O=O<<8|ie[A>>16&255],O>>>24-L))}function He(A,L){var O=L&7,N=L>>>3;return(A[N]|(O<=6?0:A[N+1]<<8))>>>O&3}function ze(A,L){var O=L&7,N=L>>>3;return(A[N]|(O<=5?0:A[N+1]<<8))>>>O&7}function gt(A,L){var O=L&7,N=L>>>3;return(A[N]|(O<=4?0:A[N+1]<<8))>>>O&15}function qe(A,L){var O=L&7,N=L>>>3;return(A[N]|(O<=3?0:A[N+1]<<8))>>>O&31}function le(A,L){var O=L&7,N=L>>>3;return(A[N]|(O<=1?0:A[N+1]<<8))>>>O&127}function fe(A,L,O){var N=L&7,M=L>>>3,U=(1<>>N;return O<8-N||(ne|=A[M+1]<<8-N,O<16-N)||(ne|=A[M+2]<<16-N,O<24-N)||(ne|=A[M+3]<<24-N),ne&U}function Re(A,L,O){var N=L&7,M=L>>>3;return N<=5?A[M]|=(O&7)<>8-N),L+3}function Ue(A,L,O){var N=L&7,M=L>>>3;return O=(O&1)<>>3;return O<<=N,A[M]|=O&255,O>>>=8,A[M+1]=O,L+8}function Tt(A,L,O){var N=L&7,M=L>>>3;return O<<=N,A[M]|=O&255,O>>>=8,A[M+1]=O&255,A[M+2]=O>>>8,L+16}function yt(A,L){var O=A.length,N=2*O>L?2*O:L+5,M=0;if(O>=L)return A;if(ct){var U=dd(N);if(A.copy)A.copy(U);else for(;M>N-Ee,ne=(1<=0;--ne)L[ge|ne<0;)re[re.l++]=ge[ae++]}return re.l}function ne(ge,re){for(var ae=0,oe=0,Ee=me?new Uint16Array(32768):[];oe0;)re[re.l++]=ge[oe++];ae=re.l*8;continue}ae=Re(re,ae,+(oe+Pe==ge.length)+2);for(var Be=0;Pe-- >0;){var Ae=ge[oe];Be=(Be<<5^Ae)&32767;var Le=-1,H=0;if((Le=Ee[Be])&&(Le|=oe&-32768,Le>oe&&(Le-=32768),Le2){Ae=M[H],Ae<=22?ae=nt(re,ae,ie[Ae+1]>>1)-1:(nt(re,ae,3),ae+=5,nt(re,ae,ie[Ae-23]>>5),ae+=3);var ee=Ae<8?0:Ae-4>>2;ee>0&&(Tt(re,ae,H-q[Ae]),ae+=ee),Ae=L[oe-Le],ae=nt(re,ae,ie[Ae]>>3),ae-=3;var ye=Ae<4?0:Ae-2>>1;ye>0&&(Tt(re,ae,oe-Le-K[Ae]),ae+=ye);for(var Ne=0;Ne>8-Ae;for(var Le=(1<<7-Ae)-1;Le>=0;--Le)Wt[Be|Le<>>=3){case 16:for(U=3+He(A,L),L+=2,Be=H[H.length-1];U-- >0;)H.push(Be);break;case 17:for(U=3+ze(A,L),L+=3;U-- >0;)H.push(0);break;case 18:for(U=11+le(A,L),L+=7;U-- >0;)H.push(0);break;default:H.push(Be),re>>0,ge=0,re=0;!(N&1);){if(N=ze(A,O),O+=3,N>>>1)N>>1==1?(ge=9,re=5):(O=as(A,O),ge=Sn,re=cr);else{O&7&&(O+=8-(O&7));var ae=A[O>>>3]|A[(O>>>3)+1]<<8;if(O+=32,ae>0)for(!L&&ne0;)M[U++]=A[O>>>3],O+=8;continue}for(;;){!L&&ne>>1==1?Qe[oe]:et[oe];if(O+=Ee&15,Ee>>>=4,!(Ee>>>8&255))M[U++]=Ee;else{if(Ee==256)break;Ee-=257;var Pe=Ee<8?0:Ee-4>>2;Pe>5&&(Pe=0);var Be=U+q[Ee];Pe>0&&(Be+=fe(A,O,Pe),O+=Pe),oe=fe(A,O,re),Ee=N>>>1==1?Xe[oe]:_t[oe],O+=Ee&15,Ee>>>=4;var Ae=Ee<4?0:Ee-2>>1,Le=K[Ee];for(Ae>0&&(Le+=fe(A,O,Ae),O+=Ae),!L&&ne>>3]:[M.slice(0,U),O+7>>>3]}function kr(A,L){var O=A.slice(A.l||0),N=Tn(O,L);return A.l+=N[1],N[0]}function qr(A,L){if(A)typeof console<"u"&&console.error(L);else throw new Error(L)}function bn(A,L){var O=A;Tr(O,0);var N=[],M=[],U={FileIndex:N,FullPaths:M};j(U,{root:L.root});for(var ne=O.length-4;(O[ne]!=80||O[ne+1]!=75||O[ne+2]!=5||O[ne+3]!=6)&&ne>=0;)--ne;O.l=ne+4,O.l+=4;var ge=O.read_shift(2);O.l+=6;var re=O.read_shift(4);for(O.l=re,ne=0;ne0&&(O=O.slice(0,O.length-1),O=O.slice(0,O.lastIndexOf("/")+1),U.slice(0,O.length)!=O););var ne=(N[1]||"").match(/boundary="(.*?)"/);if(!ne)throw new Error("MAD cannot find boundary");var ge="--"+(ne[1]||""),re=[],ae=[],oe={FileIndex:re,FullPaths:ae};j(oe);var Ee,Pe=0;for(M=0;M=32&&Be<128&&++Ee;var Le=Ee>=Pe*4/5;M.push(N),M.push("Content-Location: "+(O.root||"file:///C:/SheetJS/")+ne),M.push("Content-Transfer-Encoding: "+(Le?"quoted-printable":"base64")),M.push("Content-Type: "+kt(ge,ne)),M.push(""),M.push(Le?Qt(oe):dr(oe))}return M.push(N+`--\r +`),M.join(`\r +`)}function Fr(A){var L={};return j(L,A),L}function er(A,L,O,N){var M=N&&N.unsafe;M||j(A);var U=!M&&xt.find(A,L);if(!U){var ne=A.FullPaths[0];L.slice(0,ne.length)==ne?ne=L:(ne.slice(-1)!="/"&&(ne+="/"),ne=(ne+L).replace("//","/")),U={name:s(L),type:2},A.FileIndex.push(U),A.FullPaths.push(ne),M||xt.utils.cfb_gc(A)}return U.content=O,U.size=O?O.length:0,N&&(N.CLSID&&(U.clsid=N.CLSID),N.mt&&(U.mt=N.mt),N.ct&&(U.ct=N.ct)),U}function vr(A,L){j(A);var O=xt.find(A,L);if(O){for(var N=0;N0?r.setTime(r.getTime()+r.getTimezoneOffset()*60*1e3):t<0&&r.setTime(r.getTime()-r.getTimezoneOffset()*60*1e3),r;if(e instanceof Date)return e;if(hf.getFullYear()==1917&&!isNaN(r.getFullYear())){var n=r.getFullYear();return e.indexOf(""+n)>-1||r.setFullYear(r.getFullYear()+100),r}var s=e.match(/\d+/g)||["2017","2","19","0","0","0"],i=new Date(+s[0],+s[1]-1,+s[2],+s[3]||0,+s[4]||0,+s[5]||0);return e.indexOf("Z")>-1&&(i=new Date(i.getTime()-i.getTimezoneOffset()*60*1e3)),i}function fo(e,t){if(ct&&Buffer.isBuffer(e))return e.toString("binary");if(typeof TextDecoder<"u")try{var r={"€":"€","‚":"‚",ƒ:"ƒ","„":"„","…":"…","†":"†","‡":"‡","ˆ":"ˆ","‰":"‰",Š:"Š","‹":"‹",Œ:"Œ",Ž:"Ž","‘":"‘","’":"’","“":"“","”":"”","•":"•","–":"–","—":"—","˜":"˜","™":"™",š:"š","›":"›",œ:"œ",ž:"ž",Ÿ:"Ÿ"};return Array.isArray(e)&&(e=new Uint8Array(e)),new TextDecoder("latin1").decode(e).replace(/[€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ]/g,function(i){return r[i]||i})}catch{}for(var n=[],s=0;s!=e.length;++s)n.push(String.fromCharCode(e[s]));return n.join("")}function gr(e){if(typeof JSON<"u"&&!Array.isArray(e))return JSON.parse(JSON.stringify(e));if(typeof e!="object"||e==null)return e;if(e instanceof Date)return new Date(e.getTime());var t={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=gr(e[r]));return t}function Et(e,t){for(var r="";r.length3&&xv.indexOf(o)==-1)return r}else if(o.match(/[a-z]/))return r;return n<0||n>8099?r:(s>0||i>1)&&n!=101?t:e.match(/[^-0-9:,\/\\]/)?r:t}function Ze(e,t,r){if(e.FullPaths){if(typeof r=="string"){var n;return ct?n=wn(r):n=M_(r),xt.utils.cfb_add(e,t,n)}xt.utils.cfb_add(e,t,r)}else e.file(t,r)}function Ml(){return xt.utils.cfb_new()}var Rt=`\r +`,pv={""":'"',"'":"'",">":">","<":"<","&":"&"},Bl=Ll(pv),Ul=/[&<>'"]/g,gv=/[\u0000-\u0008\u000b-\u001f]/g;function ht(e){var t=e+"";return t.replace(Ul,function(r){return Bl[r]}).replace(gv,function(r){return"_x"+("000"+r.charCodeAt(0).toString(16)).slice(-4)+"_"})}function wd(e){return ht(e).replace(/ /g,"_x0020_")}var mf=/[\u0000-\u001f]/g;function _v(e){var t=e+"";return t.replace(Ul,function(r){return Bl[r]}).replace(/\n/g,"
").replace(mf,function(r){return"&#x"+("000"+r.charCodeAt(0).toString(16)).slice(-4)+";"})}function vv(e){var t=e+"";return t.replace(Ul,function(r){return Bl[r]}).replace(mf,function(r){return"&#x"+r.charCodeAt(0).toString(16).toUpperCase()+";"})}function yv(e){return e.replace(/(\r\n|[\r\n])/g," ")}function wv(e){switch(e){case 1:case!0:case"1":case"true":case"TRUE":return!0;default:return!1}}function Po(e){for(var t="",r=0,n=0,s=0,i=0,o=0,l=0;r191&&n<224){o=(n&31)<<6,o|=s&63,t+=String.fromCharCode(o);continue}if(i=e.charCodeAt(r++),n<240){t+=String.fromCharCode((n&15)<<12|(s&63)<<6|i&63);continue}o=e.charCodeAt(r++),l=((n&7)<<18|(s&63)<<12|(i&63)<<6|o&63)-65536,t+=String.fromCharCode(55296+(l>>>10&1023)),t+=String.fromCharCode(56320+(l&1023))}return t}function Sd(e){var t=Jn(2*e.length),r,n,s=1,i=0,o=0,l;for(n=0;n>>10&1023),r=56320+(r&1023)),o!==0&&(t[i++]=o&255,t[i++]=o>>>8,o=0),t[i++]=r%256,t[i++]=r>>>8;return t.slice(0,i).toString("ucs2")}function Td(e){return wn(e,"binary").toString("utf8")}var ri="foo bar baz☃🍣",na=ct&&(Td(ri)==Po(ri)&&Td||Sd(ri)==Po(ri)&&Sd)||Po,ya=ct?function(e){return wn(e,"utf8").toString("binary")}:function(e){for(var t=[],r=0,n=0,s=0;r>6))),t.push(String.fromCharCode(128+(n&63)));break;case(n>=55296&&n<57344):n-=55296,s=e.charCodeAt(r++)-56320+(n<<10),t.push(String.fromCharCode(240+(s>>18&7))),t.push(String.fromCharCode(144+(s>>12&63))),t.push(String.fromCharCode(128+(s>>6&63))),t.push(String.fromCharCode(128+(s&63)));break;default:t.push(String.fromCharCode(224+(n>>12))),t.push(String.fromCharCode(128+(n>>6&63))),t.push(String.fromCharCode(128+(n&63)))}return t.join("")},Sv=function(){var e=[["nbsp"," "],["middot","·"],["quot",'"'],["apos","'"],["gt",">"],["lt","<"],["amp","&"]].map(function(t){return[new RegExp("&"+t[0]+";","ig"),t[1]]});return function(r){for(var n=r.replace(/^[\t\n\r ]+/,"").replace(/[\t\n\r ]+$/,"").replace(/>\s+/g,">").replace(/\s+/g,` +`).replace(/<[^>]*>/g,""),s=0;s"+t+""}function wa(e){return Zt(e).map(function(t){return" "+t+'="'+e[t]+'"'}).join("")}function Fe(e,t,r){return"<"+e+(r!=null?wa(r):"")+(t!=null?(t.match(xf)?' xml:space="preserve"':"")+">"+t+""}function fl(e,t){try{return e.toISOString().replace(/\.\d*/,"")}catch(r){if(t)throw r}return""}function Tv(e,t){switch(typeof e){case"string":var r=Fe("vt:lpwstr",ht(e));return r=r.replace(/"/g,"_x0022_"),r;case"number":return Fe((e|0)==e?"vt:i4":"vt:r8",ht(String(e)));case"boolean":return Fe("vt:bool",e?"true":"false")}if(e instanceof Date)return Fe("vt:filetime",fl(e));throw new Error("Unable to serialize "+e)}var Ut={CORE_PROPS:"http://schemas.openxmlformats.org/package/2006/metadata/core-properties",CUST_PROPS:"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties",EXT_PROPS:"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",CT:"http://schemas.openxmlformats.org/package/2006/content-types",RELS:"http://schemas.openxmlformats.org/package/2006/relationships",TCMNT:"http://schemas.microsoft.com/office/spreadsheetml/2018/threadedcomments",dc:"http://purl.org/dc/elements/1.1/",dcterms:"http://purl.org/dc/terms/",dcmitype:"http://purl.org/dc/dcmitype/",r:"http://schemas.openxmlformats.org/officeDocument/2006/relationships",vt:"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes",xsi:"http://www.w3.org/2001/XMLSchema-instance",xsd:"http://www.w3.org/2001/XMLSchema"},Ns=["http://schemas.openxmlformats.org/spreadsheetml/2006/main","http://purl.oclc.org/ooxml/spreadsheetml/main","http://schemas.microsoft.com/office/excel/2006/main","http://schemas.microsoft.com/office/excel/2006/2"],br={o:"urn:schemas-microsoft-com:office:office",x:"urn:schemas-microsoft-com:office:excel",ss:"urn:schemas-microsoft-com:office:spreadsheet",dt:"uuid:C2F41010-65B3-11d1-A29F-00AA00C14882",mv:"http://macVmlSchemaUri",v:"urn:schemas-microsoft-com:vml",html:"http://www.w3.org/TR/REC-html40"};function bv(e,t){for(var r=1-2*(e[t+7]>>>7),n=((e[t+7]&127)<<4)+(e[t+6]>>>4&15),s=e[t+6]&15,i=5;i>=0;--i)s=s*256+e[t+i];return n==2047?s==0?r*(1/0):NaN:(n==0?n=-1022:(n-=1023,s+=Math.pow(2,52)),r*Math.pow(2,n-52)*s)}function Ev(e,t,r){var n=(t<0||1/t==-1/0?1:0)<<7,s=0,i=0,o=n?-t:t;isFinite(o)?o==0?s=i=0:(s=Math.floor(Math.log(o)/Math.LN2),i=o*Math.pow(2,52-s),s<=-1023&&(!isFinite(i)||i>4|n}var bd=function(e){for(var t=[],r=10240,n=0;n0&&Buffer.isBuffer(e[0][0])?Buffer.concat(e[0].map(function(t){return Buffer.isBuffer(t)?t:wn(t)})):bd(e)}:bd,jd=function(e,t,r){for(var n=[],s=t;s0?Na(e,t+4,t+4+r-1):""},_f=gf,vf=function(e,t){var r=Er(e,t);return r>0?Na(e,t+4,t+4+r-1):""},yf=vf,wf=function(e,t){var r=2*Er(e,t);return r>0?Na(e,t+4,t+4+r-1):""},Sf=wf,Tf=function(t,r){var n=Er(t,r);return n>0?zl(t,r+4,r+4+n):""},bf=Tf,Ef=function(e,t){var r=Er(e,t);return r>0?Na(e,t+4,t+4+r):""},jf=Ef,If=function(e,t){return bv(e,t)},Oi=If,$l=function(t){return Array.isArray(t)||typeof Uint8Array<"u"&&t instanceof Uint8Array};ct&&(_f=function(t,r){if(!Buffer.isBuffer(t))return gf(t,r);var n=t.readUInt32LE(r);return n>0?t.toString("utf8",r+4,r+4+n-1):""},yf=function(t,r){if(!Buffer.isBuffer(t))return vf(t,r);var n=t.readUInt32LE(r);return n>0?t.toString("utf8",r+4,r+4+n-1):""},Sf=function(t,r){if(!Buffer.isBuffer(t))return wf(t,r);var n=2*t.readUInt32LE(r);return t.toString("utf16le",r+4,r+4+n-1)},bf=function(t,r){if(!Buffer.isBuffer(t))return Tf(t,r);var n=t.readUInt32LE(r);return t.toString("utf16le",r+4,r+4+n)},jf=function(t,r){if(!Buffer.isBuffer(t))return Ef(t,r);var n=t.readUInt32LE(r);return t.toString("utf8",r+4,r+4+n)},Oi=function(t,r){return Buffer.isBuffer(t)?t.readDoubleLE(r):If(t,r)},$l=function(t){return Buffer.isBuffer(t)||Array.isArray(t)||typeof Uint8Array<"u"&&t instanceof Uint8Array});var gs=function(e,t){return e[t]},qs=function(e,t){return e[t+1]*256+e[t]},jv=function(e,t){var r=e[t+1]*256+e[t];return r<32768?r:(65535-r+1)*-1},Er=function(e,t){return e[t+3]*(1<<24)+(e[t+2]<<16)+(e[t+1]<<8)+e[t]},Hn=function(e,t){return e[t+3]<<24|e[t+2]<<16|e[t+1]<<8|e[t]},Iv=function(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]};function sa(e,t){var r="",n,s,i=[],o,l,c,d;switch(t){case"dbcs":if(d=this.l,ct&&Buffer.isBuffer(this))r=this.slice(this.l,this.l+2*e).toString("utf16le");else for(c=0;c0?Hn:Iv)(this,this.l),this.l+=4,n):(s=Er(this,this.l),this.l+=4,s);case 8:case-8:if(t==="f")return e==8?s=Oi(this,this.l):s=Oi([this[this.l+7],this[this.l+6],this[this.l+5],this[this.l+4],this[this.l+3],this[this.l+2],this[this.l+1],this[this.l+0]],0),this.l+=8,s;e=8;case 16:r=pf(this,this.l,e);break}}return this.l+=e,r}var Cv=function(e,t,r){e[r]=t&255,e[r+1]=t>>>8&255,e[r+2]=t>>>16&255,e[r+3]=t>>>24&255},Av=function(e,t,r){e[r]=t&255,e[r+1]=t>>8&255,e[r+2]=t>>16&255,e[r+3]=t>>24&255},kv=function(e,t,r){e[r]=t&255,e[r+1]=t>>>8&255};function Fv(e,t,r){var n=0,s=0;if(r==="dbcs"){for(s=0;s!=t.length;++s)kv(this,t.charCodeAt(s),this.l+2*s);n=2*t.length}else if(r==="sbcs"){for(t=t.replace(/[^\x00-\x7F]/g,"_"),s=0;s!=t.length;++s)this[this.l+s]=t.charCodeAt(s)&255;n=t.length}else if(r==="hex"){for(;s>8}for(;this.l>>=8,this[this.l+1]=t&255;break;case 3:n=3,this[this.l]=t&255,t>>>=8,this[this.l+1]=t&255,t>>>=8,this[this.l+2]=t&255;break;case 4:n=4,Cv(this,t,this.l);break;case 8:if(n=8,r==="f"){Ev(this,t,this.l);break}case 16:break;case-4:n=4,Av(this,t,this.l);break}return this.l+=n,this}function Cf(e,t){var r=pf(this,this.l,e.length>>1);if(r!==e)throw new Error(t+"Expected "+e+" saw "+r);this.l+=e.length>>1}function Tr(e,t){e.l=t,e.read_shift=sa,e.chk=Cf,e.write_shift=Fv}function an(e,t){e.l+=t}function pe(e){var t=Jn(e);return Tr(t,0),t}function xr(){var e=[],t=ct?256:2048,r=function(d){var u=pe(d);return Tr(u,0),u},n=r(t),s=function(){n&&(n.length>n.l&&(n=n.slice(0,n.l),n.l=n.length),n.length>0&&e.push(n),n=null)},i=function(d){return n&&d=128?1:0)+1,n>=128&&++i,n>=16384&&++i,n>=2097152&&++i;var o=e.next(i);s<=127?o.write_shift(1,s):(o.write_shift(1,(s&127)+128),o.write_shift(1,s>>7));for(var l=0;l!=4;++l)if(n>=128)o.write_shift(1,(n&127)+128),n>>=7;else{o.write_shift(1,n);break}n>0&&$l(r)&&e.push(r)}}function aa(e,t,r){var n=gr(e);if(t.s?(n.cRel&&(n.c+=t.s.c),n.rRel&&(n.r+=t.s.r)):(n.cRel&&(n.c+=t.c),n.rRel&&(n.r+=t.r)),!r||r.biff<12){for(;n.c>=256;)n.c-=256;for(;n.r>=65536;)n.r-=65536}return n}function Ad(e,t,r){var n=gr(e);return n.s=aa(n.s,t.s,r),n.e=aa(n.e,t.s,r),n}function ia(e,t){if(e.cRel&&e.c<0)for(e=gr(e);e.c<0;)e.c+=t>8?16384:256;if(e.rRel&&e.r<0)for(e=gr(e);e.r<0;)e.r+=t>8?1048576:t>5?65536:16384;var r=mt(e);return!e.cRel&&e.cRel!=null&&(r=Dv(r)),!e.rRel&&e.rRel!=null&&(r=Ov(r)),r}function No(e,t){return e.s.r==0&&!e.s.rRel&&e.e.r==(t.biff>=12?1048575:t.biff>=8?65536:16384)&&!e.e.rRel?(e.s.cRel?"":"$")+sr(e.s.c)+":"+(e.e.cRel?"":"$")+sr(e.e.c):e.s.c==0&&!e.s.cRel&&e.e.c==(t.biff>=12?16383:255)&&!e.e.cRel?(e.s.rRel?"":"$")+Jt(e.s.r)+":"+(e.e.rRel?"":"$")+Jt(e.e.r):ia(e.s,t.biff)+":"+ia(e.e,t.biff)}function Wl(e){return parseInt(Rv(e),10)-1}function Jt(e){return""+(e+1)}function Ov(e){return e.replace(/([A-Z]|^)(\d+)$/,"$1$$$2")}function Rv(e){return e.replace(/\$(\d+)$/,"$1")}function Hl(e){for(var t=Pv(e),r=0,n=0;n!==t.length;++n)r=26*r+t.charCodeAt(n)-64;return r-1}function sr(e){if(e<0)throw new Error("invalid column "+e);var t="";for(++e;e;e=Math.floor((e-1)/26))t=String.fromCharCode((e-1)%26+65)+t;return t}function Dv(e){return e.replace(/^([A-Z])/,"$$$1")}function Pv(e){return e.replace(/^\$([A-Z])/,"$1")}function Nv(e){return e.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(",")}function zt(e){for(var t=0,r=0,n=0;n=48&&s<=57?t=10*t+(s-48):s>=65&&s<=90&&(r=26*r+(s-64))}return{c:r-1,r:t-1}}function mt(e){for(var t=e.c+1,r="";t;t=(t-1)/26|0)r=String.fromCharCode((t-1)%26+65)+r;return r+(e.r+1)}function Ir(e){var t=e.indexOf(":");return t==-1?{s:zt(e),e:zt(e)}:{s:zt(e.slice(0,t)),e:zt(e.slice(t+1))}}function Ot(e,t){return typeof t>"u"||typeof t=="number"?Ot(e.s,e.e):(typeof e!="string"&&(e=mt(e)),typeof t!="string"&&(t=mt(t)),e==t?e:e+":"+t)}function vt(e){var t={s:{c:0,r:0},e:{c:0,r:0}},r=0,n=0,s=0,i=e.length;for(r=0;n26);++n)r=26*r+s;for(t.s.c=--r,r=0;n9);++n)r=10*r+s;if(t.s.r=--r,n===i||s!=10)return t.e.c=t.s.c,t.e.r=t.s.r,t;for(++n,r=0;n!=i&&!((s=e.charCodeAt(n)-64)<1||s>26);++n)r=26*r+s;for(t.e.c=--r,r=0;n!=i&&!((s=e.charCodeAt(n)-48)<0||s>9);++n)r=10*r+s;return t.e.r=--r,t}function kd(e,t){var r=e.t=="d"&&t instanceof Date;if(e.z!=null)try{return e.w=Pn(e.z,r?pr(t):t)}catch{}try{return e.w=Pn((e.XF||{}).numFmtId||(r?14:0),r?pr(t):t)}catch{return""+t}}function yn(e,t,r){return e==null||e.t==null||e.t=="z"?"":e.w!==void 0?e.w:(e.t=="d"&&!e.z&&r&&r.dateNF&&(e.z=r.dateNF),e.t=="e"?La[e.v]||e.v:t==null?kd(e,e.v):kd(e,t))}function es(e,t){var r=t&&t.sheet?t.sheet:"Sheet1",n={};return n[r]=e,{SheetNames:[r],Sheets:n}}function Af(e,t,r){var n=r||{},s=e?Array.isArray(e):n.dense,i=e||(s?[]:{}),o=0,l=0;if(i&&n.origin!=null){if(typeof n.origin=="number")o=n.origin;else{var c=typeof n.origin=="string"?zt(n.origin):n.origin;o=c.r,l=c.c}i["!ref"]||(i["!ref"]="A1:A1")}var d={s:{c:1e7,r:1e7},e:{c:0,r:0}};if(i["!ref"]){var u=vt(i["!ref"]);d.s.c=u.s.c,d.s.r=u.s.r,d.e.c=Math.max(d.e.c,u.e.c),d.e.r=Math.max(d.e.r,u.e.r),o==-1&&(d.e.r=o=u.e.r+1)}for(var h=0;h!=t.length;++h)if(t[h]){if(!Array.isArray(t[h]))throw new Error("aoa_to_sheet expects an array of arrays");for(var m=0;m!=t[h].length;++m)if(!(typeof t[h][m]>"u")){var _={v:t[h][m]},x=o+h,f=l+m;if(d.s.r>x&&(d.s.r=x),d.s.c>f&&(d.s.c=f),d.e.r0&&t.write_shift(0,e,"dbcs"),r?t.slice(0,t.l):t}function Mv(e){return{ich:e.read_shift(2),ifnt:e.read_shift(2)}}function Bv(e,t){return t||(t=pe(4)),t.write_shift(2,0),t.write_shift(2,0),t}function Vl(e,t){var r=e.l,n=e.read_shift(1),s=ar(e),i=[],o={t:s,h:s};if(n&1){for(var l=e.read_shift(4),c=0;c!=l;++c)i.push(Mv(e));o.r=i}else o.r=[{ich:0,ifnt:0}];return e.l=r+t,o}function Uv(e,t){var r=!1;return t==null&&(r=!0,t=pe(15+4*e.t.length)),t.write_shift(1,0),$t(e.t,t),r?t.slice(0,t.l):t}var zv=Vl;function $v(e,t){var r=!1;return t==null&&(r=!0,t=pe(23+4*e.t.length)),t.write_shift(1,1),$t(e.t,t),t.write_shift(4,1),Bv({},t),r?t.slice(0,t.l):t}function Br(e){var t=e.read_shift(4),r=e.read_shift(2);return r+=e.read_shift(1)<<16,e.l++,{c:t,iStyleRef:r}}function ts(e,t){return t==null&&(t=pe(8)),t.write_shift(-4,e.c),t.write_shift(3,e.iStyleRef||e.s),t.write_shift(1,0),t}function rs(e){var t=e.read_shift(2);return t+=e.read_shift(1)<<16,e.l++,{c:-1,iStyleRef:t}}function ns(e,t){return t==null&&(t=pe(4)),t.write_shift(3,e.iStyleRef||e.s),t.write_shift(1,0),t}var Wv=ar,kf=$t;function Kl(e){var t=e.read_shift(4);return t===0||t===4294967295?"":e.read_shift(t,"dbcs")}function Ri(e,t){var r=!1;return t==null&&(r=!0,t=pe(127)),t.write_shift(4,e.length>0?e.length:4294967295),e.length>0&&t.write_shift(0,e,"dbcs"),r?t.slice(0,t.l):t}var Hv=ar,hl=Kl,Gl=Ri;function Ff(e){var t=e.slice(e.l,e.l+4),r=t[0]&1,n=t[0]&2;e.l+=4;var s=n===0?Oi([0,0,0,0,t[0]&252,t[1],t[2],t[3]],0):Hn(t,0)>>2;return r?s/100:s}function Of(e,t){t==null&&(t=pe(4));var r=0,n=0,s=e*100;if(e==(e|0)&&e>=-536870912&&e<1<<29?n=1:s==(s|0)&&s>=-536870912&&s<1<<29&&(n=1,r=1),n)t.write_shift(-4,((r?s:e)<<2)+(r+2));else throw new Error("unsupported RkNumber "+e)}function Rf(e){var t={s:{},e:{}};return t.s.r=e.read_shift(4),t.e.r=e.read_shift(4),t.s.c=e.read_shift(4),t.e.c=e.read_shift(4),t}function Vv(e,t){return t||(t=pe(16)),t.write_shift(4,e.s.r),t.write_shift(4,e.e.r),t.write_shift(4,e.s.c),t.write_shift(4,e.e.c),t}var ss=Rf,Ms=Vv;function Bs(e){if(e.length-e.l<8)throw"XLS Xnum Buffer underflow";return e.read_shift(8,"f")}function Zn(e,t){return(t||pe(8)).write_shift(8,e,"f")}function Kv(e){var t={},r=e.read_shift(1),n=r>>>1,s=e.read_shift(1),i=e.read_shift(2,"i"),o=e.read_shift(1),l=e.read_shift(1),c=e.read_shift(1);switch(e.l++,n){case 0:t.auto=1;break;case 1:t.index=s;var d=ty[s];d&&(t.rgb=zd(d));break;case 2:t.rgb=zd([o,l,c]);break;case 3:t.theme=s;break}return i!=0&&(t.tint=i>0?i/32767:i/32768),t}function Di(e,t){if(t||(t=pe(8)),!e||e.auto)return t.write_shift(4,0),t.write_shift(4,0),t;e.index!=null?(t.write_shift(1,2),t.write_shift(1,e.index)):e.theme!=null?(t.write_shift(1,6),t.write_shift(1,e.theme)):(t.write_shift(1,5),t.write_shift(1,0));var r=e.tint||0;if(r>0?r*=32767:r<0&&(r*=32768),t.write_shift(2,r),!e.rgb||e.theme!=null)t.write_shift(2,0),t.write_shift(1,0),t.write_shift(1,0);else{var n=e.rgb||"FFFFFF";typeof n=="number"&&(n=("000000"+n.toString(16)).slice(-6)),t.write_shift(1,parseInt(n.slice(0,2),16)),t.write_shift(1,parseInt(n.slice(2,4),16)),t.write_shift(1,parseInt(n.slice(4,6),16)),t.write_shift(1,255)}return t}function Gv(e){var t=e.read_shift(1);e.l++;var r={fBold:t&1,fItalic:t&2,fUnderline:t&4,fStrikeout:t&8,fOutline:t&16,fShadow:t&32,fCondense:t&64,fExtend:t&128};return r}function Yv(e,t){t||(t=pe(2));var r=(e.italic?2:0)|(e.strike?8:0)|(e.outline?16:0)|(e.shadow?32:0)|(e.condense?64:0)|(e.extend?128:0);return t.write_shift(1,r),t.write_shift(1,0),t}var Df=2,Sr=3,ni=11,Pi=19,si=64,qv=65,Xv=71,Jv=4108,Zv=4126,Kt=80,Fd={1:{n:"CodePage",t:Df},2:{n:"Category",t:Kt},3:{n:"PresentationFormat",t:Kt},4:{n:"ByteCount",t:Sr},5:{n:"LineCount",t:Sr},6:{n:"ParagraphCount",t:Sr},7:{n:"SlideCount",t:Sr},8:{n:"NoteCount",t:Sr},9:{n:"HiddenCount",t:Sr},10:{n:"MultimediaClipCount",t:Sr},11:{n:"ScaleCrop",t:ni},12:{n:"HeadingPairs",t:Jv},13:{n:"TitlesOfParts",t:Zv},14:{n:"Manager",t:Kt},15:{n:"Company",t:Kt},16:{n:"LinksUpToDate",t:ni},17:{n:"CharacterCount",t:Sr},19:{n:"SharedDoc",t:ni},22:{n:"HyperlinksChanged",t:ni},23:{n:"AppVersion",t:Sr,p:"version"},24:{n:"DigSig",t:qv},26:{n:"ContentType",t:Kt},27:{n:"ContentStatus",t:Kt},28:{n:"Language",t:Kt},29:{n:"Version",t:Kt},255:{},2147483648:{n:"Locale",t:Pi},2147483651:{n:"Behavior",t:Pi},1919054434:{}},Od={1:{n:"CodePage",t:Df},2:{n:"Title",t:Kt},3:{n:"Subject",t:Kt},4:{n:"Author",t:Kt},5:{n:"Keywords",t:Kt},6:{n:"Comments",t:Kt},7:{n:"Template",t:Kt},8:{n:"LastAuthor",t:Kt},9:{n:"RevNumber",t:Kt},10:{n:"EditTime",t:si},11:{n:"LastPrinted",t:si},12:{n:"CreatedDate",t:si},13:{n:"ModifiedDate",t:si},14:{n:"PageCount",t:Sr},15:{n:"WordCount",t:Sr},16:{n:"CharCount",t:Sr},17:{n:"Thumbnail",t:Xv},18:{n:"Application",t:Kt},19:{n:"DocSecurity",t:Sr},255:{},2147483648:{n:"Locale",t:Pi},2147483651:{n:"Behavior",t:Pi},1919054434:{}};function Qv(e){return e.map(function(t){return[t>>16&255,t>>8&255,t&255]})}var ey=Qv([0,16777215,16711680,65280,255,16776960,16711935,65535,0,16777215,16711680,65280,255,16776960,16711935,65535,8388608,32768,128,8421376,8388736,32896,12632256,8421504,10066431,10040166,16777164,13434879,6684774,16744576,26316,13421823,128,16711935,16776960,65535,8388736,8388608,32896,255,52479,13434879,13434828,16777113,10079487,16751052,13408767,16764057,3368703,3394764,10079232,16763904,16750848,16737792,6710937,9868950,13158,3381606,13056,3355392,10040064,10040166,3355545,3355443,16777215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),ty=gr(ey),La={0:"#NULL!",7:"#DIV/0!",15:"#VALUE!",23:"#REF!",29:"#NAME?",36:"#NUM!",42:"#N/A",43:"#GETTING_DATA",255:"#WTF?"},ry={"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":"workbooks","application/vnd.ms-excel.sheet.macroEnabled.main+xml":"workbooks","application/vnd.ms-excel.sheet.binary.macroEnabled.main":"workbooks","application/vnd.ms-excel.addin.macroEnabled.main+xml":"workbooks","application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":"workbooks","application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":"sheets","application/vnd.ms-excel.worksheet":"sheets","application/vnd.ms-excel.binIndexWs":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml":"charts","application/vnd.ms-excel.chartsheet":"charts","application/vnd.ms-excel.macrosheet+xml":"macros","application/vnd.ms-excel.macrosheet":"macros","application/vnd.ms-excel.intlmacrosheet":"TODO","application/vnd.ms-excel.binIndexMs":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml":"dialogs","application/vnd.ms-excel.dialogsheet":"dialogs","application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml":"strs","application/vnd.ms-excel.sharedStrings":"strs","application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":"styles","application/vnd.ms-excel.styles":"styles","application/vnd.openxmlformats-package.core-properties+xml":"coreprops","application/vnd.openxmlformats-officedocument.custom-properties+xml":"custprops","application/vnd.openxmlformats-officedocument.extended-properties+xml":"extprops","application/vnd.openxmlformats-officedocument.customXmlProperties+xml":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.customProperty":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml":"comments","application/vnd.ms-excel.comments":"comments","application/vnd.ms-excel.threadedcomments+xml":"threadedcomments","application/vnd.ms-excel.person+xml":"people","application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml":"metadata","application/vnd.ms-excel.sheetMetadata":"metadata","application/vnd.ms-excel.pivotTable":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml":"TODO","application/vnd.openxmlformats-officedocument.drawingml.chart+xml":"TODO","application/vnd.ms-office.chartcolorstyle+xml":"TODO","application/vnd.ms-office.chartstyle+xml":"TODO","application/vnd.ms-office.chartex+xml":"TODO","application/vnd.ms-excel.calcChain":"calcchains","application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml":"calcchains","application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings":"TODO","application/vnd.ms-office.activeX":"TODO","application/vnd.ms-office.activeX+xml":"TODO","application/vnd.ms-excel.attachedToolbars":"TODO","application/vnd.ms-excel.connections":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml":"TODO","application/vnd.ms-excel.externalLink":"links","application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml":"links","application/vnd.ms-excel.pivotCacheDefinition":"TODO","application/vnd.ms-excel.pivotCacheRecords":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml":"TODO","application/vnd.ms-excel.queryTable":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml":"TODO","application/vnd.ms-excel.userNames":"TODO","application/vnd.ms-excel.revisionHeaders":"TODO","application/vnd.ms-excel.revisionLog":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml":"TODO","application/vnd.ms-excel.tableSingleCells":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml":"TODO","application/vnd.ms-excel.slicer":"TODO","application/vnd.ms-excel.slicerCache":"TODO","application/vnd.ms-excel.slicer+xml":"TODO","application/vnd.ms-excel.slicerCache+xml":"TODO","application/vnd.ms-excel.wsSortMap":"TODO","application/vnd.ms-excel.table":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml":"TODO","application/vnd.openxmlformats-officedocument.theme+xml":"themes","application/vnd.openxmlformats-officedocument.themeOverride+xml":"TODO","application/vnd.ms-excel.Timeline+xml":"TODO","application/vnd.ms-excel.TimelineCache+xml":"TODO","application/vnd.ms-office.vbaProject":"vba","application/vnd.ms-office.vbaProjectSignature":"TODO","application/vnd.ms-office.volatileDependencies":"TODO","application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml":"TODO","application/vnd.ms-excel.controlproperties+xml":"TODO","application/vnd.openxmlformats-officedocument.model+data":"TODO","application/vnd.ms-excel.Survey+xml":"TODO","application/vnd.openxmlformats-officedocument.drawing+xml":"drawings","application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml":"TODO","application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml":"TODO","application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml":"TODO","application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml":"TODO","application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml":"TODO","application/vnd.openxmlformats-officedocument.vmlDrawing":"TODO","application/vnd.openxmlformats-package.relationships+xml":"rels","application/vnd.openxmlformats-officedocument.oleObject":"TODO","image/png":"TODO",sheet:"js"},ai={workbooks:{xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",xlsm:"application/vnd.ms-excel.sheet.macroEnabled.main+xml",xlsb:"application/vnd.ms-excel.sheet.binary.macroEnabled.main",xlam:"application/vnd.ms-excel.addin.macroEnabled.main+xml",xltx:"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml"},strs:{xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",xlsb:"application/vnd.ms-excel.sharedStrings"},comments:{xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",xlsb:"application/vnd.ms-excel.comments"},sheets:{xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",xlsb:"application/vnd.ms-excel.worksheet"},charts:{xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",xlsb:"application/vnd.ms-excel.chartsheet"},dialogs:{xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml",xlsb:"application/vnd.ms-excel.dialogsheet"},macros:{xlsx:"application/vnd.ms-excel.macrosheet+xml",xlsb:"application/vnd.ms-excel.macrosheet"},metadata:{xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",xlsb:"application/vnd.ms-excel.sheetMetadata"},styles:{xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",xlsb:"application/vnd.ms-excel.styles"}};function Pf(){return{workbooks:[],sheets:[],charts:[],dialogs:[],macros:[],rels:[],strs:[],comments:[],threadedcomments:[],links:[],coreprops:[],extprops:[],custprops:[],themes:[],styles:[],calcchains:[],vba:[],drawings:[],metadata:[],people:[],TODO:[],xmlns:""}}function Nf(e,t){var r=fv(ry),n=[],s;n[n.length]=Rt,n[n.length]=Fe("Types",null,{xmlns:Ut.CT,"xmlns:xsd":Ut.xsd,"xmlns:xsi":Ut.xsi}),n=n.concat([["xml","application/xml"],["bin","application/vnd.ms-excel.sheet.binary.macroEnabled.main"],["vml","application/vnd.openxmlformats-officedocument.vmlDrawing"],["data","application/vnd.openxmlformats-officedocument.model+data"],["bmp","image/bmp"],["png","image/png"],["gif","image/gif"],["emf","image/x-emf"],["wmf","image/x-wmf"],["jpg","image/jpeg"],["jpeg","image/jpeg"],["tif","image/tiff"],["tiff","image/tiff"],["pdf","application/pdf"],["rels","application/vnd.openxmlformats-package.relationships+xml"]].map(function(c){return Fe("Default",null,{Extension:c[0],ContentType:c[1]})}));var i=function(c){e[c]&&e[c].length>0&&(s=e[c][0],n[n.length]=Fe("Override",null,{PartName:(s[0]=="/"?"":"/")+s,ContentType:ai[c][t.bookType]||ai[c].xlsx}))},o=function(c){(e[c]||[]).forEach(function(d){n[n.length]=Fe("Override",null,{PartName:(d[0]=="/"?"":"/")+d,ContentType:ai[c][t.bookType]||ai[c].xlsx})})},l=function(c){(e[c]||[]).forEach(function(d){n[n.length]=Fe("Override",null,{PartName:(d[0]=="/"?"":"/")+d,ContentType:r[c][0]})})};return i("workbooks"),o("sheets"),o("charts"),l("themes"),["strs","styles"].forEach(i),["coreprops","extprops","custprops"].forEach(l),l("vba"),l("comments"),l("threadedcomments"),l("drawings"),o("metadata"),l("people"),n.length>2&&(n[n.length]="",n[1]=n[1].replace("/>",">")),n.join("")}var it={WB:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",HLINK:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",VML:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",XPATH:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath",XMISS:"http://schemas.microsoft.com/office/2006/relationships/xlExternalLinkPath/xlPathMissing",CMNT:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",CORE_PROPS:"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",EXT_PROPS:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",CUST_PROPS:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties",SST:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",STY:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",THEME:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",WS:["http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet","http://purl.oclc.org/ooxml/officeDocument/relationships/worksheet"],DRAW:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",XLMETA:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",TCMNT:"http://schemas.microsoft.com/office/2017/10/relationships/threadedComment",PEOPLE:"http://schemas.microsoft.com/office/2017/10/relationships/person",VBA:"http://schemas.microsoft.com/office/2006/relationships/vbaProject"};function Lf(e){var t=e.lastIndexOf("/");return e.slice(0,t+1)+"_rels/"+e.slice(t+1)+".rels"}function Ss(e){var t=[Rt,Fe("Relationships",null,{xmlns:Ut.RELS})];return Zt(e["!id"]).forEach(function(r){t[t.length]=Fe("Relationship",null,e["!id"][r])}),t.length>2&&(t[t.length]="",t[1]=t[1].replace("/>",">")),t.join("")}function ft(e,t,r,n,s,i){if(s||(s={}),e["!id"]||(e["!id"]={}),e["!idx"]||(e["!idx"]=1),t<0)for(t=e["!idx"];e["!id"]["rId"+t];++t);if(e["!idx"]=t+1,s.Id="rId"+t,s.Type=n,s.Target=r,[it.HLINK,it.XPATH,it.XMISS].indexOf(s.Type)>-1&&(s.TargetMode="External"),e["!id"][s.Id])throw new Error("Cannot rewrite rId "+t);return e["!id"][s.Id]=s,e[("/"+s.Target).replace("//","/")]=s,t}function ny(e){var t=[Rt];t.push(` +`),t.push(` +`);for(var r=0;r +`);return t.push(""),t.join("")}function Rd(e,t,r){return[' +`,' +`,` +`].join("")}function sy(e,t){return[' +`,' +`,` +`].join("")}function ay(e){var t=[Rt];t.push(` +`);for(var r=0;r!=e.length;++r)t.push(Rd(e[r][0],e[r][1])),t.push(sy("",e[r][0]));return t.push(Rd("","Document","pkg")),t.push(""),t.join("")}function Mf(){return'SheetJS '+ji.version+""}var Yn=[["cp:category","Category"],["cp:contentStatus","ContentStatus"],["cp:keywords","Keywords"],["cp:lastModifiedBy","LastAuthor"],["cp:lastPrinted","LastPrinted"],["cp:revision","RevNumber"],["cp:version","Version"],["dc:creator","Author"],["dc:description","Comments"],["dc:identifier","Identifier"],["dc:language","Language"],["dc:subject","Subject"],["dc:title","Title"],["dcterms:created","CreatedDate","date"],["dcterms:modified","ModifiedDate","date"]];function Lo(e,t,r,n,s){s[e]!=null||t==null||t===""||(s[e]=t,t=ht(t),n[n.length]=r?Fe(e,t,r):qt(e,t))}function Bf(e,t){var r=t||{},n=[Rt,Fe("cp:coreProperties",null,{"xmlns:cp":Ut.CORE_PROPS,"xmlns:dc":Ut.dc,"xmlns:dcterms":Ut.dcterms,"xmlns:dcmitype":Ut.dcmitype,"xmlns:xsi":Ut.xsi})],s={};if(!e&&!r.Props)return n.join("");e&&(e.CreatedDate!=null&&Lo("dcterms:created",typeof e.CreatedDate=="string"?e.CreatedDate:fl(e.CreatedDate,r.WTF),{"xsi:type":"dcterms:W3CDTF"},n,s),e.ModifiedDate!=null&&Lo("dcterms:modified",typeof e.ModifiedDate=="string"?e.ModifiedDate:fl(e.ModifiedDate,r.WTF),{"xsi:type":"dcterms:W3CDTF"},n,s));for(var i=0;i!=Yn.length;++i){var o=Yn[i],l=r.Props&&r.Props[o[1]]!=null?r.Props[o[1]]:e?e[o[1]]:null;l===!0?l="1":l===!1?l="0":typeof l=="number"&&(l=String(l)),l!=null&&Lo(o[0],l,null,n,s)}return n.length>2&&(n[n.length]="",n[1]=n[1].replace("/>",">")),n.join("")}var Ts=[["Application","Application","string"],["AppVersion","AppVersion","string"],["Company","Company","string"],["DocSecurity","DocSecurity","string"],["Manager","Manager","string"],["HyperlinksChanged","HyperlinksChanged","bool"],["SharedDoc","SharedDoc","bool"],["LinksUpToDate","LinksUpToDate","bool"],["ScaleCrop","ScaleCrop","bool"],["HeadingPairs","HeadingPairs","raw"],["TitlesOfParts","TitlesOfParts","raw"]],Uf=["Worksheets","SheetNames","NamedRanges","DefinedNames","Chartsheets","ChartNames"];function zf(e){var t=[],r=Fe;return e||(e={}),e.Application="SheetJS",t[t.length]=Rt,t[t.length]=Fe("Properties",null,{xmlns:Ut.EXT_PROPS,"xmlns:vt":Ut.vt}),Ts.forEach(function(n){if(e[n[1]]!==void 0){var s;switch(n[2]){case"string":s=ht(String(e[n[1]]));break;case"bool":s=e[n[1]]?"true":"false";break}s!==void 0&&(t[t.length]=r(n[0],s))}}),t[t.length]=r("HeadingPairs",r("vt:vector",r("vt:variant","Worksheets")+r("vt:variant",r("vt:i4",String(e.Worksheets))),{size:2,baseType:"variant"})),t[t.length]=r("TitlesOfParts",r("vt:vector",e.SheetNames.map(function(n){return""+ht(n)+""}).join(""),{size:e.Worksheets,baseType:"lpstr"})),t.length>2&&(t[t.length]="",t[1]=t[1].replace("/>",">")),t.join("")}function $f(e){var t=[Rt,Fe("Properties",null,{xmlns:Ut.CUST_PROPS,"xmlns:vt":Ut.vt})];if(!e)return t.join("");var r=1;return Zt(e).forEach(function(s){++r,t[t.length]=Fe("property",Tv(e[s]),{fmtid:"{D5CDD505-2E9C-101B-9397-08002B2CF9AE}",pid:r,name:ht(s)})}),t.length>2&&(t[t.length]="",t[1]=t[1].replace("/>",">")),t.join("")}var Dd={Title:"Title",Subject:"Subject",Author:"Author",Keywords:"Keywords",Comments:"Description",LastAuthor:"LastAuthor",RevNumber:"Revision",Application:"AppName",LastPrinted:"LastPrinted",CreatedDate:"Created",ModifiedDate:"LastSaved",Category:"Category",Manager:"Manager",Company:"Company",AppVersion:"Version",ContentStatus:"ContentStatus",Identifier:"Identifier",Language:"Language"};function iy(e,t){var r=[];return Zt(Dd).map(function(n){for(var s=0;s'+s.join("")+""}function ly(e){var t=typeof e=="string"?new Date(Date.parse(e)):e,r=t.getTime()/1e3+11644473600,n=r%Math.pow(2,32),s=(r-n)/Math.pow(2,32);n*=1e7,s*=1e7;var i=n/Math.pow(2,32)|0;i>0&&(n=n%Math.pow(2,32),s+=i);var o=pe(8);return o.write_shift(4,n),o.write_shift(4,s),o}function Pd(e,t){var r=pe(4),n=pe(4);switch(r.write_shift(4,e==80?31:e),e){case 3:n.write_shift(-4,t);break;case 5:n=pe(8),n.write_shift(8,t,"f");break;case 11:n.write_shift(4,t?1:0);break;case 64:n=ly(t);break;case 31:case 80:for(n=pe(4+2*(t.length+1)+(t.length%2?0:2)),n.write_shift(4,t.length+1),n.write_shift(0,t,"dbcs");n.l!=n.length;)n.write_shift(1,0);break;default:throw new Error("TypedPropertyValue unrecognized type "+e+" "+t)}return Yt([r,n])}var Wf=["CodePage","Thumbnail","_PID_LINKBASE","_PID_HLINKS","SystemIdentifier","FMTID"];function cy(e){switch(typeof e){case"boolean":return 11;case"number":return(e|0)==e?3:5;case"string":return 31;case"object":if(e instanceof Date)return 64;break}return-1}function Nd(e,t,r){var n=pe(8),s=[],i=[],o=8,l=0,c=pe(8),d=pe(8);if(c.write_shift(4,2),c.write_shift(4,1200),d.write_shift(4,1),i.push(c),s.push(d),o+=8+c.length,!t){d=pe(8),d.write_shift(4,0),s.unshift(d);var u=[pe(4)];for(u[0].write_shift(4,e.length),l=0;l-1||Uf.indexOf(e[l][0])>-1)&&e[l][1]!=null){var m=e[l][1],_=0;if(t){_=+t[e[l][0]];var x=r[_];if(x.p=="version"&&typeof m=="string"){var f=m.split(".");m=(+f[0]<<16)+(+f[1]||0)}c=Pd(x.t,m)}else{var p=cy(m);p==-1&&(p=31,m=String(m)),c=Pd(p,m)}i.push(c),d=pe(8),d.write_shift(4,t?_:2+l),s.push(d),o+=8+c.length}var I=8*(i.length+1);for(l=0;l=12?2:1),s="sbcs-cont";if(r&&r.biff>=8,!r||r.biff==8){var i=e.read_shift(1);i&&(s="dbcs-cont")}else r.biff==12&&(s="wstr");r.biff>=2&&r.biff<=5&&(s="cpstr");var o=n?e.read_shift(n,s):"";return o}function fy(e){var t=e.t||"",r=pe(3);r.write_shift(2,t.length),r.write_shift(1,1);var n=pe(2*t.length);n.write_shift(2*t.length,t,"utf16le");var s=[r,n];return Yt(s)}function hy(e,t,r){var n;if(r){if(r.biff>=2&&r.biff<=5)return e.read_shift(t,"cpstr");if(r.biff>=12)return e.read_shift(t,"dbcs-cont")}var s=e.read_shift(1);return s===0?n=e.read_shift(t,"sbcs-cont"):n=e.read_shift(t,"dbcs-cont"),n}function my(e,t,r){var n=e.read_shift(r&&r.biff==2?1:2);return n===0?(e.l++,""):hy(e,n,r)}function xy(e,t,r){if(r.biff>5)return my(e,t,r);var n=e.read_shift(1);return n===0?(e.l++,""):e.read_shift(n,r.biff<=4||!e.lens?"cpstr":"sbcs-cont")}function Gf(e,t,r){return r||(r=pe(3+2*e.length)),r.write_shift(2,e.length),r.write_shift(1,1),r.write_shift(31,e,"utf16le"),r}function Md(e,t){t||(t=pe(6+e.length*2)),t.write_shift(4,1+e.length);for(var r=0;r-1?31:23;switch(n.charAt(0)){case"#":i=28;break;case".":i&=-3;break}t.write_shift(4,2),t.write_shift(4,i);var o=[8,6815827,6619237,4849780,83];for(r=0;r-1?n.slice(0,s):n;for(t.write_shift(4,2*(l.length+1)),r=0;r-1?n.slice(s+1):"",t)}else{for(o="03 03 00 00 00 00 00 00 c0 00 00 00 00 00 00 46".split(" "),r=0;r8?4:2,s=e.read_shift(n),i=e.read_shift(n,"i"),o=e.read_shift(n,"i");return[s,i,o]}function _y(e){var t=e.read_shift(2),r=e.read_shift(2),n=e.read_shift(2),s=e.read_shift(2);return{s:{c:n,r:t},e:{c:s,r}}}function Yf(e,t){return t||(t=pe(8)),t.write_shift(2,e.s.r),t.write_shift(2,e.e.r),t.write_shift(2,e.s.c),t.write_shift(2,e.e.c),t}function Yl(e,t,r){var n=1536,s=16;switch(r.bookType){case"biff8":break;case"biff5":n=1280,s=8;break;case"biff4":n=4,s=6;break;case"biff3":n=3,s=6;break;case"biff2":n=2,s=4;break;case"xla":break;default:throw new Error("unsupported BIFF version")}var i=pe(s);return i.write_shift(2,n),i.write_shift(2,t),s>4&&i.write_shift(2,29282),s>6&&i.write_shift(2,1997),s>8&&(i.write_shift(2,49161),i.write_shift(2,1),i.write_shift(2,1798),i.write_shift(2,0)),i}function vy(e,t){var r=!t||t.biff==8,n=pe(r?112:54);for(n.write_shift(t.biff==8?2:1,7),r&&n.write_shift(1,0),n.write_shift(4,859007059),n.write_shift(4,5458548|(r?0:536870912));n.l=8?2:1,n=pe(8+r*e.name.length);n.write_shift(4,e.pos),n.write_shift(1,e.hs||0),n.write_shift(1,e.dt),n.write_shift(1,e.name.length),t.biff>=8&&n.write_shift(1,1),n.write_shift(r*e.name.length,e.name,t.biff<8?"sbcs":"utf16le");var s=n.slice(0,n.l);return s.l=n.l,s}function wy(e,t){var r=pe(8);r.write_shift(4,e.Count),r.write_shift(4,e.Unique);for(var n=[],s=0;sn.l?n.slice(0,n.l):n;return i.l==null&&(i.l=i.length),i}function Cy(e,t){var r=t.biff==8||!t.biff?4:2,n=pe(2*r+6);return n.write_shift(r,e.s.r),n.write_shift(r,e.e.r+1),n.write_shift(2,e.s.c),n.write_shift(2,e.e.c+1),n.write_shift(2,0),n}function Bd(e,t,r,n){var s=r&&r.biff==5;n||(n=pe(s?16:20)),n.write_shift(2,0),e.style?(n.write_shift(2,e.numFmtId||0),n.write_shift(2,65524)):(n.write_shift(2,e.numFmtId||0),n.write_shift(2,t<<4));var i=0;return e.numFmtId>0&&s&&(i|=1024),n.write_shift(4,i),n.write_shift(4,0),s||n.write_shift(4,0),n.write_shift(2,0),n}function Ay(e){var t=pe(8);return t.write_shift(4,0),t.write_shift(2,0),t.write_shift(2,0),t}function ky(e,t,r,n,s,i){var o=pe(8);return Qn(e,t,n,o),Vf(r,i,o),o}function Fy(e,t,r,n){var s=pe(14);return Qn(e,t,n,s),Zn(r,s),s}function Oy(e,t,r){if(r.biff<8)return Ry(e,t,r);for(var n=[],s=e.l+t,i=e.read_shift(r.biff>8?4:2);i--!==0;)n.push(gy(e,r.biff>8?12:6,r));if(e.l!=s)throw new Error("Bad ExternSheet: "+e.l+" != "+s);return n}function Ry(e,t,r){e[e.l+1]==3&&e[e.l]++;var n=Kf(e,t,r);return n.charCodeAt(0)==3?n.slice(1):n}function Dy(e){var t=pe(2+e.length*8);t.write_shift(2,e.length);for(var r=0;r=12?4:2,s=e.read_shift(n),i=e.read_shift(n),o=e.read_shift(n),l=e.read_shift(n),c=e.read_shift(2);n==2&&(e.l+=2);var d={s,e:i,w:o,ixfe:l,flags:c};return(r.biff>=5||!r.biff)&&(d.level=c>>8&7),d}function By(e,t){var r=pe(12);r.write_shift(2,t),r.write_shift(2,t),r.write_shift(2,e.width*256),r.write_shift(2,0);var n=0;return e.hidden&&(n|=1),r.write_shift(1,n),n=e.level||0,r.write_shift(1,n),r.write_shift(2,0),r}function Uy(e){for(var t=pe(2*e),r=0;r1048576&&(f=1e6),h!=2&&(p=u.read_shift(2));var I=u.read_shift(2),S=c.codepage||1252;h!=2&&(u.l+=16,u.read_shift(1),u[u.l]!==0&&(S=e[u[u.l]]),u.l+=1,u.l+=2),x&&(u.l+=36);for(var w=[],v={},y=Math.min(u.length,h==2?521:p-10-(_?264:0)),R=x?32:11;u.l0;){if(u[u.l]===42){u.l+=I;continue}for(++u.l,d[++j]=[],T=0,T=0;T!=w.length;++T){var C=u.slice(u.l,u.l+w[T].len);u.l+=w[T].len,Tr(C,0);var F=Ii.utils.decode(S,C);switch(w[T].type){case"C":F.trim().length&&(d[j][T]=F.replace(/\s+$/,""));break;case"D":F.length===8?d[j][T]=new Date(+F.slice(0,4),+F.slice(4,6)-1,+F.slice(6,8)):d[j][T]=F;break;case"F":d[j][T]=parseFloat(F.trim());break;case"+":case"I":d[j][T]=x?C.read_shift(-4,"i")^2147483648:C.read_shift(4,"i");break;case"L":switch(F.trim().toUpperCase()){case"Y":case"T":d[j][T]=!0;break;case"N":case"F":d[j][T]=!1;break;case"":case"?":break;default:throw new Error("DBF Unrecognized L:|"+F+"|")}break;case"M":if(!m)throw new Error("DBF Unexpected MEMO for type "+h.toString(16));d[j][T]="##MEMO##"+(x?parseInt(F.trim(),10):C.read_shift(4));break;case"N":F=F.replace(/\u0000/g,"").trim(),F&&F!="."&&(d[j][T]=+F||0);break;case"@":d[j][T]=new Date(C.read_shift(-8,"f")-621356832e5);break;case"T":d[j][T]=new Date((C.read_shift(4)-2440588)*864e5+C.read_shift(4));break;case"Y":d[j][T]=C.read_shift(4,"i")/1e4+C.read_shift(4,"i")/1e4*Math.pow(2,32);break;case"O":d[j][T]=-C.read_shift(-8,"f");break;case"B":if(_&&w[T].len==8){d[j][T]=C.read_shift(8,"f");break}case"G":case"P":C.l+=w[T].len;break;case"0":if(w[T].name==="_NullFlags")break;default:throw new Error("DBF Unsupported data type "+w[T].type)}}}if(h!=2&&u.l=0&&ga(+d.codepage),d.type=="string")throw new Error("Cannot write DBF to JS string");var u=xr(),h=Ui(l,{header:1,raw:!0,cellDates:!0}),m=h[0],_=h.slice(1),x=l["!cols"]||[],f=0,p=0,I=0,S=1;for(f=0;f250&&(C=250),T=((x[f]||{}).DBF||{}).type,T=="C"&&x[f].DBF.len>C&&(C=x[f].DBF.len),j=="B"&&T=="N"&&(j="N",R[f]=x[f].DBF.dec,C=x[f].DBF.len),y[f]=j=="C"||T=="N"?C:i[j]||0,S+=y[f],v[f]=j}var P=u.next(32);for(P.write_shift(4,318902576),P.write_shift(4,_.length),P.write_shift(2,296+32*I),P.write_shift(2,S),f=0;f<4;++f)P.write_shift(4,0);for(P.write_shift(4,0|(+t[q0]||3)<<8),f=0,p=0;f":190,"?":191,"{":223},t=new RegExp("\x1BN("+Zt(e).join("|").replace(/\|\|\|/,"|\\||").replace(/([?()+])/g,"\\$1")+"|\\|)","gm"),r=function(m,_){var x=e[_];return typeof x=="number"?cd(x):x},n=function(m,_,x){var f=_.charCodeAt(0)-32<<4|x.charCodeAt(0)-48;return f==59?m:cd(f)};e["|"]=254;function s(m,_){switch(_.type){case"base64":return i(vn(m),_);case"binary":return i(m,_);case"buffer":return i(ct&&Buffer.isBuffer(m)?m.toString("binary"):Da(m),_);case"array":return i(fo(m),_)}throw new Error("Unrecognized type "+_.type)}function i(m,_){var x=m.split(/[\n\r]+/),f=-1,p=-1,I=0,S=0,w=[],v=[],y=null,R={},j=[],T=[],C=[],F=0,P;for(+_.codepage>=0&&ga(+_.codepage);I!==x.length;++I){F=0;var V=x[I].trim().replace(/\x1B([\x20-\x2F])([\x30-\x3F])/g,n).replace(t,r),X=V.replace(/;;/g,"\0").split(";").map(function(D){return D.replace(/\u0000/g,";")}),_e=X[0],B;if(V.length>0)switch(_e){case"ID":break;case"E":break;case"B":break;case"O":break;case"W":break;case"P":X[1].charAt(0)=="P"&&v.push(V.slice(3).replace(/;;/g,";"));break;case"C":var te=!1,J=!1,G=!1,se=!1,Q=-1,de=-1;for(S=1;S-1&&w[Q][de];if(!W||!W[1])throw new Error("SYLK shared formula cannot find base");w[f][p][1]=Ww(W[1],{r:f-Q,c:p-de})}break;case"F":var z=0;for(S=1;S0?(j[f].hpt=F,j[f].hpx=Qf(F)):F===0&&(j[f].hidden=!0);break;default:if(_&&_.WTF)throw new Error("SYLK bad record "+V)}z<1&&(y=null);break;default:if(_&&_.WTF)throw new Error("SYLK bad record "+V)}}return j.length>0&&(R["!rows"]=j),T.length>0&&(R["!cols"]=T),_&&_.sheetRows&&(w=w.slice(0,_.sheetRows)),[w,R]}function o(m,_){var x=s(m,_),f=x[0],p=x[1],I=Ls(f,_);return Zt(p).forEach(function(S){I[S]=p[S]}),I}function l(m,_){return es(o(m,_),_)}function c(m,_,x,f){var p="C;Y"+(x+1)+";X"+(f+1)+";K";switch(m.t){case"n":p+=m.v||0,m.f&&!m.F&&(p+=";E"+Jl(m.f,{r:x,c:f}));break;case"b":p+=m.v?"TRUE":"FALSE";break;case"e":p+=m.w||m.v;break;case"d":p+='"'+(m.w||m.v)+'"';break;case"s":p+='"'+m.v.replace(/"/g,"").replace(/;/g,";;")+'"';break}return p}function d(m,_){_.forEach(function(x,f){var p="F;W"+(f+1)+" "+(f+1)+" ";x.hidden?p+="0":(typeof x.width=="number"&&!x.wpx&&(x.wpx=Ni(x.width)),typeof x.wpx=="number"&&!x.wch&&(x.wch=Li(x.wpx)),typeof x.wch=="number"&&(p+=Math.round(x.wch))),p.charAt(p.length-1)!=" "&&m.push(p)})}function u(m,_){_.forEach(function(x,f){var p="F;";x.hidden?p+="M0;":x.hpt?p+="M"+20*x.hpt+";":x.hpx&&(p+="M"+20*Mi(x.hpx)+";"),p.length>2&&m.push(p+"R"+(f+1))})}function h(m,_){var x=["ID;PWXL;N;E"],f=[],p=vt(m["!ref"]),I,S=Array.isArray(m),w=`\r +`;x.push("P;PGeneral"),x.push("F;P0;DG0G8;M255"),m["!cols"]&&d(x,m["!cols"]),m["!rows"]&&u(x,m["!rows"]),x.push("B;Y"+(p.e.r-p.s.r+1)+";X"+(p.e.c-p.s.c+1)+";D"+[p.s.c,p.s.r,p.e.c,p.e.r].join(" "));for(var v=p.s.r;v<=p.e.r;++v)for(var y=p.s.c;y<=p.e.c;++y){var R=mt({r:v,c:y});I=S?(m[v]||[])[y]:m[R],!(!I||I.v==null&&(!I.f||I.F))&&f.push(c(I,m,v,y))}return x.join(w)+w+f.join(w)+w+"E"+w}return{to_workbook:l,to_sheet:o,from_sheet:h}}(),Vy=function(){function e(i,o){switch(o.type){case"base64":return t(vn(i),o);case"binary":return t(i,o);case"buffer":return t(ct&&Buffer.isBuffer(i)?i.toString("binary"):Da(i),o);case"array":return t(fo(i),o)}throw new Error("Unrecognized type "+o.type)}function t(i,o){for(var l=i.split(` +`),c=-1,d=-1,u=0,h=[];u!==l.length;++u){if(l[u].trim()==="BOT"){h[++c]=[],d=0;continue}if(!(c<0)){var m=l[u].trim().split(","),_=m[0],x=m[1];++u;for(var f=l[u]||"";(f.match(/["]/g)||[]).length&1&&u=0&&x[f].length===0;)--f;for(var p=10,I=0,S=0;S<=f;++S)I=x[S].indexOf(" "),I==-1?I=x[S].length:I++,p=Math.max(p,I);for(S=0;S<=f;++S){_[S]=[];var w=0;for(e(x[S].slice(0,p).trim(),_,S,w,m),w=1;w<=(x[S].length-p)/10+1;++w)e(x[S].slice(p+(w-1)*10,p+w*10).trim(),_,S,w,m)}return m.sheetRows&&(_=_.slice(0,m.sheetRows)),_}var r={44:",",9:" ",59:";",124:"|"},n={44:3,9:2,59:1,124:0};function s(u){for(var h={},m=!1,_=0,x=0;_0&&F(),x["!ref"]=Ot(f),x}function o(u,h){return!(h&&h.PRN)||h.FS||u.slice(0,4)=="sep="||u.indexOf(" ")>=0||u.indexOf(",")>=0||u.indexOf(";")>=0?i(u,h):Ls(t(u,h),h)}function l(u,h){var m="",_=h.type=="string"?[0,0,0,0]:sE(u,h);switch(h.type){case"base64":m=vn(u);break;case"binary":m=u;break;case"buffer":h.codepage==65001?m=u.toString("utf8"):h.codepage&&typeof Ii<"u"||(m=ct&&Buffer.isBuffer(u)?u.toString("binary"):Da(u));break;case"array":m=fo(u);break;case"string":m=u;break;default:throw new Error("Unrecognized type "+h.type)}return _[0]==239&&_[1]==187&&_[2]==191?m=na(m.slice(3)):h.type!="string"&&h.type!="buffer"&&h.codepage==65001?m=na(m):h.type=="binary"&&typeof Ii<"u",m.slice(0,19)=="socialcalc:version:"?qf.to_sheet(h.type=="string"?m:na(m),h):o(m,h)}function c(u,h){return es(l(u,h),h)}function d(u){for(var h=[],m=vt(u["!ref"]),_,x=Array.isArray(u),f=m.s.r;f<=m.e.r;++f){for(var p=[],I=m.s.c;I<=m.e.c;++I){var S=mt({r:f,c:I});if(_=x?(u[f]||[])[I]:u[S],!_||_.v==null){p.push(" ");continue}for(var w=(_.w||(yn(_),_.w)||"").slice(0,10);w.length<10;)w+=" ";p.push(w+(I===0?" ":""))}h.push(p.join(""))}return h.join(` +`)}return{to_workbook:c,to_sheet:l,from_sheet:d}}(),Ud=function(){function e(k,W,z){if(k){Tr(k,k.l||0);for(var D=z.Enum||Q;k.l=16&&k[14]==5&&k[15]===108)throw new Error("Unsupported Works 3 for Mac file");if(k[2]==2)z.Enum=Q,e(k,function(le,fe,Re){switch(Re){case 0:z.vers=le,le>=4096&&(z.qpro=!0);break;case 6:we=le;break;case 204:le&&(K=le);break;case 222:K=le;break;case 15:case 51:z.qpro||(le[1].v=le[1].v.slice(1));case 13:case 14:case 16:Re==14&&(le[2]&112)==112&&(le[2]&15)>1&&(le[2]&15)<15&&(le[1].z=z.dateNF||jt[14],z.cellDates&&(le[1].t="d",le[1].v=ff(le[1].v))),z.qpro&&le[3]>Z&&(D["!ref"]=Ot(we),me[q]=D,ie.push(q),D=z.dense?[]:{},we={s:{r:0,c:0},e:{r:0,c:0}},Z=le[3],q=K||"Sheet"+(Z+1),K="");var Ue=z.dense?(D[le[0].r]||[])[le[0].c]:D[mt(le[0])];if(Ue){Ue.t=le[1].t,Ue.v=le[1].v,le[1].z!=null&&(Ue.z=le[1].z),le[1].f!=null&&(Ue.f=le[1].f);break}z.dense?(D[le[0].r]||(D[le[0].r]=[]),D[le[0].r][le[0].c]=le[1]):D[mt(le[0])]=le[1];break}},z);else if(k[2]==26||k[2]==14)z.Enum=de,k[2]==14&&(z.qpro=!0,k.l=0),e(k,function(le,fe,Re){switch(Re){case 204:q=le;break;case 22:le[1].v=le[1].v.slice(1);case 23:case 24:case 25:case 37:case 39:case 40:if(le[3]>Z&&(D["!ref"]=Ot(we),me[q]=D,ie.push(q),D=z.dense?[]:{},we={s:{r:0,c:0},e:{r:0,c:0}},Z=le[3],q="Sheet"+(Z+1)),He>0&&le[0].r>=He)break;z.dense?(D[le[0].r]||(D[le[0].r]=[]),D[le[0].r][le[0].c]=le[1]):D[mt(le[0])]=le[1],we.e.c=0&&ga(+z.codepage),z.type=="string")throw new Error("Cannot write WK1 to JS string");var D=xr(),q=vt(k["!ref"]),K=Array.isArray(k),Z=[];Oe(D,0,i(1030)),Oe(D,6,c(q));for(var me=Math.min(q.e.r,8191),ie=q.s.r;ie<=me;++ie)for(var he=Jt(ie),we=q.s.c;we<=q.e.c;++we){ie===q.s.r&&(Z[we]=sr(we));var He=Z[we]+he,ze=K?(k[ie]||[])[we]:k[He];if(!(!ze||ze.t=="z"))if(ze.t=="n")(ze.v|0)==ze.v&&ze.v>=-32768&&ze.v<=32767?Oe(D,13,_(ie,we,ze.v)):Oe(D,14,f(ie,we,ze.v));else{var gt=yn(ze);Oe(D,15,h(ie,we,gt.slice(0,239)))}}return Oe(D,1),D.end()}function s(k,W){var z=W||{};if(+z.codepage>=0&&ga(+z.codepage),z.type=="string")throw new Error("Cannot write WK3 to JS string");var D=xr();Oe(D,0,o(k));for(var q=0,K=0;q8191&&(z=8191),W.write_shift(2,z),W.write_shift(1,q),W.write_shift(1,D),W.write_shift(2,0),W.write_shift(2,0),W.write_shift(1,1),W.write_shift(1,2),W.write_shift(4,0),W.write_shift(4,0),W}function l(k,W,z){var D={s:{c:0,r:0},e:{c:0,r:0}};return W==8&&z.qpro?(D.s.c=k.read_shift(1),k.l++,D.s.r=k.read_shift(2),D.e.c=k.read_shift(1),k.l++,D.e.r=k.read_shift(2),D):(D.s.c=k.read_shift(2),D.s.r=k.read_shift(2),W==12&&z.qpro&&(k.l+=2),D.e.c=k.read_shift(2),D.e.r=k.read_shift(2),W==12&&z.qpro&&(k.l+=2),D.s.c==65535&&(D.s.c=D.e.c=D.s.r=D.e.r=0),D)}function c(k){var W=pe(8);return W.write_shift(2,k.s.c),W.write_shift(2,k.s.r),W.write_shift(2,k.e.c),W.write_shift(2,k.e.r),W}function d(k,W,z){var D=[{c:0,r:0},{t:"n",v:0},0,0];return z.qpro&&z.vers!=20768?(D[0].c=k.read_shift(1),D[3]=k.read_shift(1),D[0].r=k.read_shift(2),k.l+=2):(D[2]=k.read_shift(1),D[0].c=k.read_shift(2),D[0].r=k.read_shift(2)),D}function u(k,W,z){var D=k.l+W,q=d(k,W,z);if(q[1].t="s",z.vers==20768){k.l++;var K=k.read_shift(1);return q[1].v=k.read_shift(K,"utf8"),q}return z.qpro&&k.l++,q[1].v=k.read_shift(D-k.l,"cstr"),q}function h(k,W,z){var D=pe(7+z.length);D.write_shift(1,255),D.write_shift(2,W),D.write_shift(2,k),D.write_shift(1,39);for(var q=0;q=128?95:K)}return D.write_shift(1,0),D}function m(k,W,z){var D=d(k,W,z);return D[1].v=k.read_shift(2,"i"),D}function _(k,W,z){var D=pe(7);return D.write_shift(1,255),D.write_shift(2,W),D.write_shift(2,k),D.write_shift(2,z,"i"),D}function x(k,W,z){var D=d(k,W,z);return D[1].v=k.read_shift(8,"f"),D}function f(k,W,z){var D=pe(13);return D.write_shift(1,255),D.write_shift(2,W),D.write_shift(2,k),D.write_shift(8,z,"f"),D}function p(k,W,z){var D=k.l+W,q=d(k,W,z);if(q[1].v=k.read_shift(8,"f"),z.qpro)k.l=D;else{var K=k.read_shift(2);v(k.slice(k.l,k.l+K),q),k.l+=K}return q}function I(k,W,z){var D=W&32768;return W&=-32769,W=(D?k:0)+(W>=8192?W-16384:W),(D?"":"$")+(z?sr(W):Jt(W))}var S={51:["FALSE",0],52:["TRUE",0],70:["LEN",1],80:["SUM",69],81:["AVERAGEA",69],82:["COUNTA",69],83:["MINA",69],84:["MAXA",69],111:["T",1]},w=["","","","","","","","","","+","-","*","/","^","=","<>","<=",">=","<",">","","","","","&","","","","","","",""];function v(k,W){Tr(k,0);for(var z=[],D=0,q="",K="",Z="",me="";k.lz.length){console.error("WK1 bad formula parse 0x"+ie.toString(16)+":|"+z.join("|")+"|");return}var ze=z.slice(-D);z.length-=D,z.push(S[ie][0]+"("+ze.join(",")+")")}else return ie<=7?console.error("WK1 invalid opcode "+ie.toString(16)):ie<=24?console.error("WK1 unsupported op "+ie.toString(16)):ie<=30?console.error("WK1 invalid opcode "+ie.toString(16)):ie<=115?console.error("WK1 unsupported function opcode "+ie.toString(16)):console.error("WK1 unrecognized opcode "+ie.toString(16))}}z.length==1?W[1].f=""+z[0]:console.error("WK1 bad formula parse |"+z.join("|")+"|")}function y(k){var W=[{c:0,r:0},{t:"n",v:0},0];return W[0].r=k.read_shift(2),W[3]=k[k.l++],W[0].c=k[k.l++],W}function R(k,W){var z=y(k);return z[1].t="s",z[1].v=k.read_shift(W-4,"cstr"),z}function j(k,W,z,D){var q=pe(6+D.length);q.write_shift(2,k),q.write_shift(1,z),q.write_shift(1,W),q.write_shift(1,39);for(var K=0;K=128?95:Z)}return q.write_shift(1,0),q}function T(k,W){var z=y(k);z[1].v=k.read_shift(2);var D=z[1].v>>1;if(z[1].v&1)switch(D&7){case 0:D=(D>>3)*5e3;break;case 1:D=(D>>3)*500;break;case 2:D=(D>>3)/20;break;case 3:D=(D>>3)/200;break;case 4:D=(D>>3)/2e3;break;case 5:D=(D>>3)/2e4;break;case 6:D=(D>>3)/16;break;case 7:D=(D>>3)/64;break}return z[1].v=D,z}function C(k,W){var z=y(k),D=k.read_shift(4),q=k.read_shift(4),K=k.read_shift(2);if(K==65535)return D===0&&q===3221225472?(z[1].t="e",z[1].v=15):D===0&&q===3489660928?(z[1].t="e",z[1].v=42):z[1].v=0,z;var Z=K&32768;return K=(K&32767)-16446,z[1].v=(1-Z*2)*(q*Math.pow(2,K+32)+D*Math.pow(2,K)),z}function F(k,W,z,D){var q=pe(14);if(q.write_shift(2,k),q.write_shift(1,z),q.write_shift(1,W),D==0)return q.write_shift(4,0),q.write_shift(4,0),q.write_shift(2,65535),q;var K=0,Z=0,me=0,ie=0;return D<0&&(K=1,D=-D),Z=Math.log2(D)|0,D/=Math.pow(2,Z-31),ie=D>>>0,ie&2147483648||(D/=2,++Z,ie=D>>>0),D-=ie,ie|=2147483648,ie>>>=0,D*=Math.pow(2,32),me=D>>>0,q.write_shift(4,me),q.write_shift(4,ie),Z+=16383+(K?32768:0),q.write_shift(2,Z),q}function P(k,W){var z=C(k);return k.l+=W-14,z}function V(k,W){var z=y(k),D=k.read_shift(4);return z[1].v=D>>6,z}function X(k,W){var z=y(k),D=k.read_shift(8,"f");return z[1].v=D,z}function _e(k,W){var z=X(k);return k.l+=W-10,z}function B(k,W){return k[k.l+W-1]==0?k.read_shift(W,"cstr"):""}function te(k,W){var z=k[k.l++];z>W-1&&(z=W-1);for(var D="";D.length127?95:q}return z[z.l++]=0,z}var Q={0:{n:"BOF",f:Hf},1:{n:"EOF"},2:{n:"CALCMODE"},3:{n:"CALCORDER"},4:{n:"SPLIT"},5:{n:"SYNC"},6:{n:"RANGE",f:l},7:{n:"WINDOW1"},8:{n:"COLW1"},9:{n:"WINTWO"},10:{n:"COLW2"},11:{n:"NAME"},12:{n:"BLANK"},13:{n:"INTEGER",f:m},14:{n:"NUMBER",f:x},15:{n:"LABEL",f:u},16:{n:"FORMULA",f:p},24:{n:"TABLE"},25:{n:"ORANGE"},26:{n:"PRANGE"},27:{n:"SRANGE"},28:{n:"FRANGE"},29:{n:"KRANGE1"},32:{n:"HRANGE"},35:{n:"KRANGE2"},36:{n:"PROTEC"},37:{n:"FOOTER"},38:{n:"HEADER"},39:{n:"SETUP"},40:{n:"MARGINS"},41:{n:"LABELFMT"},42:{n:"TITLES"},43:{n:"SHEETJS"},45:{n:"GRAPH"},46:{n:"NGRAPH"},47:{n:"CALCCOUNT"},48:{n:"UNFORMATTED"},49:{n:"CURSORW12"},50:{n:"WINDOW"},51:{n:"STRING",f:u},55:{n:"PASSWORD"},56:{n:"LOCKED"},60:{n:"QUERY"},61:{n:"QUERYNAME"},62:{n:"PRINT"},63:{n:"PRINTNAME"},64:{n:"GRAPH2"},65:{n:"GRAPHNAME"},66:{n:"ZOOM"},67:{n:"SYMSPLIT"},68:{n:"NSROWS"},69:{n:"NSCOLS"},70:{n:"RULER"},71:{n:"NNAME"},72:{n:"ACOMM"},73:{n:"AMACRO"},74:{n:"PARSE"},102:{n:"PRANGES??"},103:{n:"RRANGES??"},104:{n:"FNAME??"},105:{n:"MRANGES??"},204:{n:"SHEETNAMECS",f:B},222:{n:"SHEETNAMELP",f:te},65535:{n:""}},de={0:{n:"BOF"},1:{n:"EOF"},2:{n:"PASSWORD"},3:{n:"CALCSET"},4:{n:"WINDOWSET"},5:{n:"SHEETCELLPTR"},6:{n:"SHEETLAYOUT"},7:{n:"COLUMNWIDTH"},8:{n:"HIDDENCOLUMN"},9:{n:"USERRANGE"},10:{n:"SYSTEMRANGE"},11:{n:"ZEROFORCE"},12:{n:"SORTKEYDIR"},13:{n:"FILESEAL"},14:{n:"DATAFILLNUMS"},15:{n:"PRINTMAIN"},16:{n:"PRINTSTRING"},17:{n:"GRAPHMAIN"},18:{n:"GRAPHSTRING"},19:{n:"??"},20:{n:"ERRCELL"},21:{n:"NACELL"},22:{n:"LABEL16",f:R},23:{n:"NUMBER17",f:C},24:{n:"NUMBER18",f:T},25:{n:"FORMULA19",f:P},26:{n:"FORMULA1A"},27:{n:"XFORMAT",f:G},28:{n:"DTLABELMISC"},29:{n:"DTLABELCELL"},30:{n:"GRAPHWINDOW"},31:{n:"CPA"},32:{n:"LPLAUTO"},33:{n:"QUERY"},34:{n:"HIDDENSHEET"},35:{n:"??"},37:{n:"NUMBER25",f:V},38:{n:"??"},39:{n:"NUMBER27",f:X},40:{n:"FORMULA28",f:_e},142:{n:"??"},147:{n:"??"},150:{n:"??"},151:{n:"??"},152:{n:"??"},153:{n:"??"},154:{n:"??"},155:{n:"??"},156:{n:"??"},163:{n:"??"},174:{n:"??"},175:{n:"??"},176:{n:"??"},177:{n:"??"},184:{n:"??"},185:{n:"??"},186:{n:"??"},187:{n:"??"},188:{n:"??"},195:{n:"??"},201:{n:"??"},204:{n:"SHEETNAMECS",f:B},205:{n:"??"},206:{n:"??"},207:{n:"??"},208:{n:"??"},256:{n:"??"},259:{n:"??"},260:{n:"??"},261:{n:"??"},262:{n:"??"},263:{n:"??"},265:{n:"??"},266:{n:"??"},267:{n:"??"},268:{n:"??"},270:{n:"??"},271:{n:"??"},384:{n:"??"},389:{n:"??"},390:{n:"??"},393:{n:"??"},396:{n:"??"},512:{n:"??"},514:{n:"??"},513:{n:"??"},516:{n:"??"},517:{n:"??"},640:{n:"??"},641:{n:"??"},642:{n:"??"},643:{n:"??"},644:{n:"??"},645:{n:"??"},646:{n:"??"},647:{n:"??"},648:{n:"??"},658:{n:"??"},659:{n:"??"},660:{n:"??"},661:{n:"??"},662:{n:"??"},665:{n:"??"},666:{n:"??"},768:{n:"??"},772:{n:"??"},1537:{n:"SHEETINFOQP",f:J},1600:{n:"??"},1602:{n:"??"},1793:{n:"??"},1794:{n:"??"},1795:{n:"??"},1796:{n:"??"},1920:{n:"??"},2048:{n:"??"},2049:{n:"??"},2052:{n:"??"},2688:{n:"??"},10998:{n:"??"},12849:{n:"??"},28233:{n:"??"},28484:{n:"??"},65535:{n:""}};return{sheet_to_wk1:n,book_to_wk3:s,to_workbook:t}}(),Gy=/^\s|\s$|[\t\n\r]/;function Xf(e,t){if(!t.bookSST)return"";var r=[Rt];r[r.length]=Fe("sst",null,{xmlns:Ns[0],count:e.Count,uniqueCount:e.Unique});for(var n=0;n!=e.length;++n)if(e[n]!=null){var s=e[n],i="";s.r?i+=s.r:(i+=""),i+="",r[r.length]=i}return r.length>2&&(r[r.length]="",r[1]=r[1].replace("/>",">")),r.join("")}function Yy(e){return[e.read_shift(4),e.read_shift(4)]}function qy(e,t){return t||(t=pe(8)),t.write_shift(4,e.Count),t.write_shift(4,e.Unique),t}var Xy=Uv;function Jy(e){var t=xr();Se(t,159,qy(e));for(var r=0;r=0;--i)o=r[i],l=t&16384?1:0,c=t<<1&32767,d=l|c,t=d^o;return t^52811}var Qy=function(){function e(s,i){switch(i.type){case"base64":return t(vn(s),i);case"binary":return t(s,i);case"buffer":return t(ct&&Buffer.isBuffer(s)?s.toString("binary"):Da(s),i);case"array":return t(fo(s),i)}throw new Error("Unrecognized type "+i.type)}function t(s,i){var o=i||{},l=o.dense?[]:{},c=s.match(/\\trowd.*?\\row\b/g);if(!c.length)throw new Error("RTF missing table");var d={s:{c:0,r:0},e:{c:0,r:c.length-1}};return c.forEach(function(u,h){Array.isArray(l)&&(l[h]=[]);for(var m=/\\\w+\b/g,_=0,x,f=-1;x=m.exec(u);){switch(x[0]){case"\\cell":var p=u.slice(_,m.lastIndex-x[0].length);if(p[0]==" "&&(p=p.slice(1)),++f,p.length){var I={v:p,t:"s"};Array.isArray(l)?l[h][f]=I:l[mt({r:h,c:f})]=I}break}_=m.lastIndex}f>d.e.c&&(d.e.c=f)}),l["!ref"]=Ot(d),l}function r(s,i){return es(e(s,i),i)}function n(s){for(var i=["{\\rtf1\\ansi"],o=vt(s["!ref"]),l,c=Array.isArray(s),d=o.s.r;d<=o.e.r;++d){i.push("\\trowd\\trautofit1");for(var u=o.s.c;u<=o.e.c;++u)i.push("\\cellx"+(u+1));for(i.push("\\pard\\intbl"),u=o.s.c;u<=o.e.c;++u){var h=mt({r:d,c:u});l=c?(s[d]||[])[u]:s[h],!(!l||l.v==null&&(!l.f||l.F))&&(i.push(" "+(l.w||(yn(l),l.w))),i.push("\\cell"))}i.push("\\pard\\intbl\\row")}return i.join("")+"}"}return{to_workbook:r,to_sheet:e,from_sheet:n}}();function zd(e){for(var t=0,r=1;t!=3;++t)r=r*256+(e[t]>255?255:e[t]<0?0:e[t]);return r.toString(16).toUpperCase().slice(1)}var ew=6,gn=ew;function Ni(e){return Math.floor((e+Math.round(128/gn)/256)*gn)}function Li(e){return Math.floor((e-5)/gn*100+.5)/100}function ml(e){return Math.round((e*gn+5)/gn*256)/256}function ql(e){e.width?(e.wpx=Ni(e.width),e.wch=Li(e.wpx),e.MDW=gn):e.wpx?(e.wch=Li(e.wpx),e.width=ml(e.wch),e.MDW=gn):typeof e.wch=="number"&&(e.width=ml(e.wch),e.wpx=Ni(e.width),e.MDW=gn),e.customWidth&&delete e.customWidth}var tw=96,Zf=tw;function Mi(e){return e*96/Zf}function Qf(e){return e*Zf/96}function rw(e){var t=[""];return[[5,8],[23,26],[41,44],[50,392]].forEach(function(r){for(var n=r[0];n<=r[1];++n)e[n]!=null&&(t[t.length]=Fe("numFmt",null,{numFmtId:n,formatCode:ht(e[n])}))}),t.length===1?"":(t[t.length]="",t[0]=Fe("numFmts",null,{count:t.length-2}).replace("/>",">"),t.join(""))}function nw(e){var t=[];return t[t.length]=Fe("cellXfs",null),e.forEach(function(r){t[t.length]=Fe("xf",null,r)}),t[t.length]="",t.length===2?"":(t[0]=Fe("cellXfs",null,{count:t.length-2}).replace("/>",">"),t.join(""))}function eh(e,t){var r=[Rt,Fe("styleSheet",null,{xmlns:Ns[0],"xmlns:vt":Ut.vt})],n;return e.SSF&&(n=rw(e.SSF))!=null&&(r[r.length]=n),r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',(n=nw(t.cellXfs))&&(r[r.length]=n),r[r.length]='',r[r.length]='',r[r.length]='',r.length>2&&(r[r.length]="",r[1]=r[1].replace("/>",">")),r.join("")}function sw(e,t){var r=e.read_shift(2),n=ar(e);return[r,n]}function aw(e,t,r){r||(r=pe(6+4*t.length)),r.write_shift(2,e),$t(t,r);var n=r.length>r.l?r.slice(0,r.l):r;return r.l==null&&(r.l=r.length),n}function iw(e,t,r){var n={};n.sz=e.read_shift(2)/20;var s=Gv(e);s.fItalic&&(n.italic=1),s.fCondense&&(n.condense=1),s.fExtend&&(n.extend=1),s.fShadow&&(n.shadow=1),s.fOutline&&(n.outline=1),s.fStrikeout&&(n.strike=1);var i=e.read_shift(2);switch(i===700&&(n.bold=1),e.read_shift(2)){case 1:n.vertAlign="superscript";break;case 2:n.vertAlign="subscript";break}var o=e.read_shift(1);o!=0&&(n.underline=o);var l=e.read_shift(1);l>0&&(n.family=l);var c=e.read_shift(1);switch(c>0&&(n.charset=c),e.l++,n.color=Kv(e),e.read_shift(1)){case 1:n.scheme="major";break;case 2:n.scheme="minor";break}return n.name=ar(e),n}function ow(e,t){t||(t=pe(25+4*32)),t.write_shift(2,e.sz*20),Yv(e,t),t.write_shift(2,e.bold?700:400);var r=0;e.vertAlign=="superscript"?r=1:e.vertAlign=="subscript"&&(r=2),t.write_shift(2,r),t.write_shift(1,e.underline||0),t.write_shift(1,e.family||0),t.write_shift(1,e.charset||0),t.write_shift(1,0),Di(e.color,t);var n=0;return n=2,t.write_shift(1,n),$t(e.name,t),t.length>t.l?t.slice(0,t.l):t}var lw=["none","solid","mediumGray","darkGray","lightGray","darkHorizontal","darkVertical","darkDown","darkUp","darkGrid","darkTrellis","lightHorizontal","lightVertical","lightDown","lightUp","lightGrid","lightTrellis","gray125","gray0625"],Mo,cw=an;function $d(e,t){t||(t=pe(4*3+8*7+16*1)),Mo||(Mo=Ll(lw));var r=Mo[e.patternType];r==null&&(r=40),t.write_shift(4,r);var n=0;if(r!=40)for(Di({auto:1},t),Di({auto:1},t);n<12;++n)t.write_shift(4,0);else{for(;n<4;++n)t.write_shift(4,0);for(;n<12;++n)t.write_shift(4,0)}return t.length>t.l?t.slice(0,t.l):t}function dw(e,t){var r=e.l+t,n=e.read_shift(2),s=e.read_shift(2);return e.l=r,{ixfe:n,numFmtId:s}}function th(e,t,r){r||(r=pe(16)),r.write_shift(2,t||0),r.write_shift(2,e.numFmtId||0),r.write_shift(2,0),r.write_shift(2,0),r.write_shift(2,0),r.write_shift(1,0),r.write_shift(1,0);var n=0;return r.write_shift(1,n),r.write_shift(1,0),r.write_shift(1,0),r.write_shift(1,0),r}function Ws(e,t){return t||(t=pe(10)),t.write_shift(1,0),t.write_shift(1,0),t.write_shift(4,0),t.write_shift(4,0),t}var uw=an;function fw(e,t){return t||(t=pe(51)),t.write_shift(1,0),Ws(null,t),Ws(null,t),Ws(null,t),Ws(null,t),Ws(null,t),t.length>t.l?t.slice(0,t.l):t}function hw(e,t){return t||(t=pe(12+4*10)),t.write_shift(4,e.xfId),t.write_shift(2,1),t.write_shift(1,0),t.write_shift(1,0),Ri(e.name||"",t),t.length>t.l?t.slice(0,t.l):t}function mw(e,t,r){var n=pe(2052);return n.write_shift(4,e),Ri(t,n),Ri(r,n),n.length>n.l?n.slice(0,n.l):n}function xw(e,t){if(t){var r=0;[[5,8],[23,26],[41,44],[50,392]].forEach(function(n){for(var s=n[0];s<=n[1];++s)t[s]!=null&&++r}),r!=0&&(Se(e,615,Vr(r)),[[5,8],[23,26],[41,44],[50,392]].forEach(function(n){for(var s=n[0];s<=n[1];++s)t[s]!=null&&Se(e,44,aw(s,t[s]))}),Se(e,616))}}function pw(e){var t=1;Se(e,611,Vr(t)),Se(e,43,ow({sz:12,color:{theme:1},name:"Calibri",family:2})),Se(e,612)}function gw(e){var t=2;Se(e,603,Vr(t)),Se(e,45,$d({patternType:"none"})),Se(e,45,$d({patternType:"gray125"})),Se(e,604)}function _w(e){var t=1;Se(e,613,Vr(t)),Se(e,46,fw()),Se(e,614)}function vw(e){var t=1;Se(e,626,Vr(t)),Se(e,47,th({numFmtId:0},65535)),Se(e,627)}function yw(e,t){Se(e,617,Vr(t.length)),t.forEach(function(r){Se(e,47,th(r,0))}),Se(e,618)}function ww(e){var t=1;Se(e,619,Vr(t)),Se(e,48,hw({xfId:0,name:"Normal"})),Se(e,620)}function Sw(e){var t=0;Se(e,505,Vr(t)),Se(e,506)}function Tw(e){var t=0;Se(e,508,mw(t,"TableStyleMedium9","PivotStyleMedium4")),Se(e,509)}function bw(e,t){var r=xr();return Se(r,278),xw(r,e.SSF),pw(r),gw(r),_w(r),vw(r),yw(r,t.cellXfs),ww(r),Sw(r),Tw(r),Se(r,279),r.end()}function rh(e,t){if(t&&t.themeXLSX)return t.themeXLSX;if(e&&typeof e.raw=="string")return e.raw;var r=[Rt];return r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]='',r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]='',r[r.length]="",r[r.length]="",r[r.length]="",r[r.length]="",r.join("")}function Ew(e,t){return{flags:e.read_shift(4),version:e.read_shift(4),name:ar(e)}}function jw(e){var t=pe(12+2*e.name.length);return t.write_shift(4,e.flags),t.write_shift(4,e.version),$t(e.name,t),t.slice(0,t.l)}function Iw(e){for(var t=[],r=e.read_shift(4);r-- >0;)t.push([e.read_shift(4),e.read_shift(4)]);return t}function Cw(e){var t=pe(4+8*e.length);t.write_shift(4,e.length);for(var r=0;r + + + + + + + + + + + + + + + + + +`),e.join("")}function Rw(e){var t={};t.i=e.read_shift(4);var r={};r.r=e.read_shift(4),r.c=e.read_shift(4),t.r=mt(r);var n=e.read_shift(1);return n&2&&(t.l="1"),n&8&&(t.a="1"),t}var _s=1024;function sh(e,t){for(var r=[21600,21600],n=["m0,0l0",r[1],r[0],r[1],r[0],"0xe"].join(","),s=[Fe("xml",null,{"xmlns:v":br.v,"xmlns:o":br.o,"xmlns:x":br.x,"xmlns:mv":br.mv}).replace(/\/>/,">"),Fe("o:shapelayout",Fe("o:idmap",null,{"v:ext":"edit",data:e}),{"v:ext":"edit"}),Fe("v:shapetype",[Fe("v:stroke",null,{joinstyle:"miter"}),Fe("v:path",null,{gradientshapeok:"t","o:connecttype":"rect"})].join(""),{id:"_x0000_t202","o:spt":202,coordsize:r.join(","),path:n})];_s",d,Fe("v:shadow",null,u),Fe("v:path",null,{"o:connecttype":"none"}),'
','',"","",qt("x:Anchor",[o.c+1,0,o.r+1,0,o.c+3,20,o.r+5,20].join(",")),qt("x:AutoFill","False"),qt("x:Row",String(o.r)),qt("x:Column",String(o.c)),i[1].hidden?"":"","",""])}),s.push(""),s.join("")}function ah(e){var t=[Rt,Fe("comments",null,{xmlns:Ns[0]})],r=[];return t.push(""),e.forEach(function(n){n[1].forEach(function(s){var i=ht(s.a);r.indexOf(i)==-1&&(r.push(i),t.push(""+i+"")),s.T&&s.ID&&r.indexOf("tc="+s.ID)==-1&&(r.push("tc="+s.ID),t.push("tc="+s.ID+""))})}),r.length==0&&(r.push("SheetJ5"),t.push("SheetJ5")),t.push(""),t.push(""),e.forEach(function(n){var s=0,i=[];if(n[1][0]&&n[1][0].T&&n[1][0].ID?s=r.indexOf("tc="+n[1][0].ID):n[1].forEach(function(c){c.a&&(s=r.indexOf(ht(c.a))),i.push(c.t||"")}),t.push(''),i.length<=1)t.push(qt("t",ht(i[0]||"")));else{for(var o=`Comment: + `+i[0]+` +`,l=1;l")}),t.push(""),t.length>2&&(t[t.length]="",t[1]=t[1].replace("/>",">")),t.join("")}function Dw(e,t,r){var n=[Rt,Fe("ThreadedComments",null,{xmlns:Ut.TCMNT}).replace(/[\/]>/,">")];return e.forEach(function(s){var i="";(s[1]||[]).forEach(function(o,l){if(!o.T){delete o.ID;return}o.a&&t.indexOf(o.a)==-1&&t.push(o.a);var c={ref:s[0],id:"{54EE7951-7262-4200-6969-"+("000000000000"+r.tcid++).slice(-12)+"}"};l==0?i=c.id:c.parentId=i,o.ID=c.id,o.a&&(c.personId="{54EE7950-7262-4200-6969-"+("000000000000"+t.indexOf(o.a)).slice(-12)+"}"),n.push(Fe("threadedComment",qt("text",o.t||""),c))})}),n.push(""),n.join("")}function Pw(e){var t=[Rt,Fe("personList",null,{xmlns:Ut.TCMNT,"xmlns:x":Ns[0]}).replace(/[\/]>/,">")];return e.forEach(function(r,n){t.push(Fe("person",null,{displayName:r,id:"{54EE7950-7262-4200-6969-"+("000000000000"+n).slice(-12)+"}",userId:r,providerId:"None"}))}),t.push(""),t.join("")}function Nw(e){var t={};t.iauthor=e.read_shift(4);var r=ss(e);return t.rfx=r.s,t.ref=mt(r.s),e.l+=16,t}function Lw(e,t){return t==null&&(t=pe(36)),t.write_shift(4,e[1].iauthor),Ms(e[0],t),t.write_shift(4,0),t.write_shift(4,0),t.write_shift(4,0),t.write_shift(4,0),t}var Mw=ar;function Bw(e){return $t(e.slice(0,54))}function Uw(e){var t=xr(),r=[];return Se(t,628),Se(t,630),e.forEach(function(n){n[1].forEach(function(s){r.indexOf(s.a)>-1||(r.push(s.a.slice(0,54)),Se(t,632,Bw(s.a)))})}),Se(t,631),Se(t,633),e.forEach(function(n){n[1].forEach(function(s){s.iauthor=r.indexOf(s.a);var i={s:zt(n[0]),e:zt(n[0])};Se(t,635,Lw([i,s])),s.t&&s.t.length>0&&Se(t,637,$v(s)),Se(t,636),delete s.iauthor})}),Se(t,634),Se(t,629),t.end()}function zw(e,t){t.FullPaths.forEach(function(r,n){if(n!=0){var s=r.replace(/[^\/]*[\/]/,"/_VBA_PROJECT_CUR/");s.slice(-1)!=="/"&&xt.utils.cfb_add(e,s,t.FileIndex[n].content)}})}var ih=["xlsb","xlsm","xlam","biff8","xla"],$w=function(){var e=/(^|[^A-Za-z_])R(\[?-?\d+\]|[1-9]\d*|)C(\[?-?\d+\]|[1-9]\d*|)(?![A-Za-z0-9_])/g,t={r:0,c:0};function r(n,s,i,o){var l=!1,c=!1;i.length==0?c=!0:i.charAt(0)=="["&&(c=!0,i=i.slice(1,-1)),o.length==0?l=!0:o.charAt(0)=="["&&(l=!0,o=o.slice(1,-1));var d=i.length>0?parseInt(i,10)|0:0,u=o.length>0?parseInt(o,10)|0:0;return l?u+=t.c:--u,c?d+=t.r:--d,s+(l?"":"$")+sr(u)+(c?"":"$")+Jt(d)}return function(s,i){return t=i,s.replace(e,r)}}(),Xl=/(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)(10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6]|[1-9]\d{0,5})(?![_.\(A-Za-z0-9])/g,Jl=function(){return function(t,r){return t.replace(Xl,function(n,s,i,o,l,c){var d=Hl(o)-(i?0:r.c),u=Wl(c)-(l?0:r.r),h=u==0?"":l?u+1:"["+u+"]",m=d==0?"":i?d+1:"["+d+"]";return s+"R"+h+"C"+m})}}();function Ww(e,t){return e.replace(Xl,function(r,n,s,i,o,l){return n+(s=="$"?s+i:sr(Hl(i)+t.c))+(o=="$"?o+l:Jt(Wl(l)+t.r))})}function Hw(e){return e.length!=1}function Ft(e){e.l+=1}function Nn(e,t){var r=e.read_shift(2);return[r&16383,r>>14&1,r>>15&1]}function oh(e,t,r){var n=2;if(r){if(r.biff>=2&&r.biff<=5)return lh(e);r.biff==12&&(n=4)}var s=e.read_shift(n),i=e.read_shift(n),o=Nn(e),l=Nn(e);return{s:{r:s,c:o[0],cRel:o[1],rRel:o[2]},e:{r:i,c:l[0],cRel:l[1],rRel:l[2]}}}function lh(e){var t=Nn(e),r=Nn(e),n=e.read_shift(1),s=e.read_shift(1);return{s:{r:t[0],c:n,cRel:t[1],rRel:t[2]},e:{r:r[0],c:s,cRel:r[1],rRel:r[2]}}}function Vw(e,t,r){if(r.biff<8)return lh(e);var n=e.read_shift(r.biff==12?4:2),s=e.read_shift(r.biff==12?4:2),i=Nn(e),o=Nn(e);return{s:{r:n,c:i[0],cRel:i[1],rRel:i[2]},e:{r:s,c:o[0],cRel:o[1],rRel:o[2]}}}function ch(e,t,r){if(r&&r.biff>=2&&r.biff<=5)return Kw(e);var n=e.read_shift(r&&r.biff==12?4:2),s=Nn(e);return{r:n,c:s[0],cRel:s[1],rRel:s[2]}}function Kw(e){var t=Nn(e),r=e.read_shift(1);return{r:t[0],c:r,cRel:t[1],rRel:t[2]}}function Gw(e){var t=e.read_shift(2),r=e.read_shift(2);return{r:t,c:r&255,fQuoted:!!(r&16384),cRel:r>>15,rRel:r>>15}}function Yw(e,t,r){var n=r&&r.biff?r.biff:8;if(n>=2&&n<=5)return qw(e);var s=e.read_shift(n>=12?4:2),i=e.read_shift(2),o=(i&16384)>>14,l=(i&32768)>>15;if(i&=16383,l==1)for(;s>524287;)s-=1048576;if(o==1)for(;i>8191;)i=i-16384;return{r:s,c:i,cRel:o,rRel:l}}function qw(e){var t=e.read_shift(2),r=e.read_shift(1),n=(t&32768)>>15,s=(t&16384)>>14;return t&=16383,n==1&&t>=8192&&(t=t-16384),s==1&&r>=128&&(r=r-256),{r:t,c:r,cRel:s,rRel:n}}function Xw(e,t,r){var n=(e[e.l++]&96)>>5,s=oh(e,r.biff>=2&&r.biff<=5?6:8,r);return[n,s]}function Jw(e,t,r){var n=(e[e.l++]&96)>>5,s=e.read_shift(2,"i"),i=8;if(r)switch(r.biff){case 5:e.l+=12,i=6;break;case 12:i=12;break}var o=oh(e,i,r);return[n,s,o]}function Zw(e,t,r){var n=(e[e.l++]&96)>>5;return e.l+=r&&r.biff>8?12:r.biff<8?6:8,[n]}function Qw(e,t,r){var n=(e[e.l++]&96)>>5,s=e.read_shift(2),i=8;if(r)switch(r.biff){case 5:e.l+=12,i=6;break;case 12:i=12;break}return e.l+=i,[n,s]}function e2(e,t,r){var n=(e[e.l++]&96)>>5,s=Vw(e,t-1,r);return[n,s]}function t2(e,t,r){var n=(e[e.l++]&96)>>5;return e.l+=r.biff==2?6:r.biff==12?14:7,[n]}function Wd(e){var t=e[e.l+1]&1,r=1;return e.l+=4,[t,r]}function r2(e,t,r){e.l+=2;for(var n=e.read_shift(r&&r.biff==2?1:2),s=[],i=0;i<=n;++i)s.push(e.read_shift(r&&r.biff==2?1:2));return s}function n2(e,t,r){var n=e[e.l+1]&255?1:0;return e.l+=2,[n,e.read_shift(r&&r.biff==2?1:2)]}function s2(e,t,r){var n=e[e.l+1]&255?1:0;return e.l+=2,[n,e.read_shift(r&&r.biff==2?1:2)]}function a2(e){var t=e[e.l+1]&255?1:0;return e.l+=2,[t,e.read_shift(2)]}function i2(e,t,r){var n=e[e.l+1]&255?1:0;return e.l+=r&&r.biff==2?3:4,[n]}function dh(e){var t=e.read_shift(1),r=e.read_shift(1);return[t,r]}function o2(e){return e.read_shift(2),dh(e)}function l2(e){return e.read_shift(2),dh(e)}function c2(e,t,r){var n=(e[e.l]&96)>>5;e.l+=1;var s=ch(e,0,r);return[n,s]}function d2(e,t,r){var n=(e[e.l]&96)>>5;e.l+=1;var s=Yw(e,0,r);return[n,s]}function u2(e,t,r){var n=(e[e.l]&96)>>5;e.l+=1;var s=e.read_shift(2);r&&r.biff==5&&(e.l+=12);var i=ch(e,0,r);return[n,s,i]}function f2(e,t,r){var n=(e[e.l]&96)>>5;e.l+=1;var s=e.read_shift(r&&r.biff<=3?1:2);return[fS[s],hh[s],n]}function h2(e,t,r){var n=e[e.l++],s=e.read_shift(1),i=r&&r.biff<=3?[n==88?-1:0,e.read_shift(1)]:m2(e);return[s,(i[0]===0?hh:uS)[i[1]]]}function m2(e){return[e[e.l+1]>>7,e.read_shift(2)&32767]}function x2(e,t,r){e.l+=r&&r.biff==2?3:4}function p2(e,t,r){if(e.l++,r&&r.biff==12)return[e.read_shift(4,"i"),0];var n=e.read_shift(2),s=e.read_shift(r&&r.biff==2?1:2);return[n,s]}function g2(e){return e.l++,La[e.read_shift(1)]}function _2(e){return e.l++,e.read_shift(2)}function v2(e){return e.l++,e.read_shift(1)!==0}function y2(e){return e.l++,Bs(e)}function w2(e,t,r){return e.l++,Kf(e,t-1,r)}function S2(e,t){var r=[e.read_shift(1)];if(t==12)switch(r[0]){case 2:r[0]=4;break;case 4:r[0]=16;break;case 0:r[0]=1;break;case 1:r[0]=2;break}switch(r[0]){case 4:r[1]=uy(e,1)?"TRUE":"FALSE",t!=12&&(e.l+=7);break;case 37:case 16:r[1]=La[e[e.l]],e.l+=t==12?4:8;break;case 0:e.l+=8;break;case 1:r[1]=Bs(e);break;case 2:r[1]=xy(e,0,{biff:t>0&&t<8?2:t});break;default:throw new Error("Bad SerAr: "+r[0])}return r}function T2(e,t,r){for(var n=e.read_shift(r.biff==12?4:2),s=[],i=0;i!=n;++i)s.push((r.biff==12?ss:_y)(e));return s}function b2(e,t,r){var n=0,s=0;r.biff==12?(n=e.read_shift(4),s=e.read_shift(4)):(s=1+e.read_shift(1),n=1+e.read_shift(2)),r.biff>=2&&r.biff<8&&(--n,--s==0&&(s=256));for(var i=0,o=[];i!=n&&(o[i]=[]);++i)for(var l=0;l!=s;++l)o[i][l]=S2(e,r.biff);return o}function E2(e,t,r){var n=e.read_shift(1)>>>5&3,s=!r||r.biff>=8?4:2,i=e.read_shift(s);switch(r.biff){case 2:e.l+=5;break;case 3:case 4:e.l+=8;break;case 5:e.l+=12;break}return[n,0,i]}function j2(e,t,r){if(r.biff==5)return I2(e);var n=e.read_shift(1)>>>5&3,s=e.read_shift(2),i=e.read_shift(4);return[n,s,i]}function I2(e){var t=e.read_shift(1)>>>5&3,r=e.read_shift(2,"i");e.l+=8;var n=e.read_shift(2);return e.l+=12,[t,r,n]}function C2(e,t,r){var n=e.read_shift(1)>>>5&3;e.l+=r&&r.biff==2?3:4;var s=e.read_shift(r&&r.biff==2?1:2);return[n,s]}function A2(e,t,r){var n=e.read_shift(1)>>>5&3,s=e.read_shift(r&&r.biff==2?1:2);return[n,s]}function k2(e,t,r){var n=e.read_shift(1)>>>5&3;return e.l+=4,r.biff<8&&e.l--,r.biff==12&&(e.l+=2),[n]}function F2(e,t,r){var n=(e[e.l++]&96)>>5,s=e.read_shift(2),i=4;if(r)switch(r.biff){case 5:i=15;break;case 12:i=6;break}return e.l+=i,[n,s]}var O2=an,R2=an,D2=an;function Ma(e,t,r){return e.l+=2,[Gw(e)]}function Zl(e){return e.l+=6,[]}var P2=Ma,N2=Zl,L2=Zl,M2=Ma;function uh(e){return e.l+=2,[Hf(e),e.read_shift(2)&1]}var B2=Ma,U2=uh,z2=Zl,$2=Ma,W2=Ma,H2=["Data","All","Headers","??","?Data2","??","?DataHeaders","??","Totals","??","??","??","?DataTotals","??","??","??","?Current"];function V2(e){e.l+=2;var t=e.read_shift(2),r=e.read_shift(2),n=e.read_shift(4),s=e.read_shift(2),i=e.read_shift(2),o=H2[r>>2&31];return{ixti:t,coltype:r&3,rt:o,idx:n,c:s,C:i}}function K2(e){return e.l+=2,[e.read_shift(4)]}function G2(e,t,r){return e.l+=5,e.l+=2,e.l+=r.biff==2?1:4,["PTGSHEET"]}function Y2(e,t,r){return e.l+=r.biff==2?4:5,["PTGENDSHEET"]}function q2(e){var t=e.read_shift(1)>>>5&3,r=e.read_shift(2);return[t,r]}function X2(e){var t=e.read_shift(1)>>>5&3,r=e.read_shift(2);return[t,r]}function J2(e){return e.l+=4,[0,0]}var Hd={1:{n:"PtgExp",f:p2},2:{n:"PtgTbl",f:D2},3:{n:"PtgAdd",f:Ft},4:{n:"PtgSub",f:Ft},5:{n:"PtgMul",f:Ft},6:{n:"PtgDiv",f:Ft},7:{n:"PtgPower",f:Ft},8:{n:"PtgConcat",f:Ft},9:{n:"PtgLt",f:Ft},10:{n:"PtgLe",f:Ft},11:{n:"PtgEq",f:Ft},12:{n:"PtgGe",f:Ft},13:{n:"PtgGt",f:Ft},14:{n:"PtgNe",f:Ft},15:{n:"PtgIsect",f:Ft},16:{n:"PtgUnion",f:Ft},17:{n:"PtgRange",f:Ft},18:{n:"PtgUplus",f:Ft},19:{n:"PtgUminus",f:Ft},20:{n:"PtgPercent",f:Ft},21:{n:"PtgParen",f:Ft},22:{n:"PtgMissArg",f:Ft},23:{n:"PtgStr",f:w2},26:{n:"PtgSheet",f:G2},27:{n:"PtgEndSheet",f:Y2},28:{n:"PtgErr",f:g2},29:{n:"PtgBool",f:v2},30:{n:"PtgInt",f:_2},31:{n:"PtgNum",f:y2},32:{n:"PtgArray",f:t2},33:{n:"PtgFunc",f:f2},34:{n:"PtgFuncVar",f:h2},35:{n:"PtgName",f:E2},36:{n:"PtgRef",f:c2},37:{n:"PtgArea",f:Xw},38:{n:"PtgMemArea",f:C2},39:{n:"PtgMemErr",f:O2},40:{n:"PtgMemNoMem",f:R2},41:{n:"PtgMemFunc",f:A2},42:{n:"PtgRefErr",f:k2},43:{n:"PtgAreaErr",f:Zw},44:{n:"PtgRefN",f:d2},45:{n:"PtgAreaN",f:e2},46:{n:"PtgMemAreaN",f:q2},47:{n:"PtgMemNoMemN",f:X2},57:{n:"PtgNameX",f:j2},58:{n:"PtgRef3d",f:u2},59:{n:"PtgArea3d",f:Jw},60:{n:"PtgRefErr3d",f:F2},61:{n:"PtgAreaErr3d",f:Qw},255:{}},Z2={64:32,96:32,65:33,97:33,66:34,98:34,67:35,99:35,68:36,100:36,69:37,101:37,70:38,102:38,71:39,103:39,72:40,104:40,73:41,105:41,74:42,106:42,75:43,107:43,76:44,108:44,77:45,109:45,78:46,110:46,79:47,111:47,88:34,120:34,89:57,121:57,90:58,122:58,91:59,123:59,92:60,124:60,93:61,125:61},Q2={1:{n:"PtgElfLel",f:uh},2:{n:"PtgElfRw",f:$2},3:{n:"PtgElfCol",f:P2},6:{n:"PtgElfRwV",f:W2},7:{n:"PtgElfColV",f:M2},10:{n:"PtgElfRadical",f:B2},11:{n:"PtgElfRadicalS",f:z2},13:{n:"PtgElfColS",f:N2},15:{n:"PtgElfColSV",f:L2},16:{n:"PtgElfRadicalLel",f:U2},25:{n:"PtgList",f:V2},29:{n:"PtgSxName",f:K2},255:{}},eS={0:{n:"PtgAttrNoop",f:J2},1:{n:"PtgAttrSemi",f:i2},2:{n:"PtgAttrIf",f:s2},4:{n:"PtgAttrChoose",f:r2},8:{n:"PtgAttrGoto",f:n2},16:{n:"PtgAttrSum",f:x2},32:{n:"PtgAttrBaxcel",f:Wd},33:{n:"PtgAttrBaxcel",f:Wd},64:{n:"PtgAttrSpace",f:o2},65:{n:"PtgAttrSpaceSemi",f:l2},128:{n:"PtgAttrIfError",f:a2},255:{}};function tS(e,t,r,n){if(n.biff<8)return an(e,t);for(var s=e.l+t,i=[],o=0;o!==r.length;++o)switch(r[o][0]){case"PtgArray":r[o][1]=b2(e,0,n),i.push(r[o][1]);break;case"PtgMemArea":r[o][2]=T2(e,r[o][1],n),i.push(r[o][2]);break;case"PtgExp":n&&n.biff==12&&(r[o][1][1]=e.read_shift(4),i.push(r[o][1]));break;case"PtgList":case"PtgElfRadicalS":case"PtgElfColS":case"PtgElfColSV":throw"Unsupported "+r[o][0]}return t=s-e.l,t!==0&&i.push(an(e,t)),i}function rS(e,t,r){for(var n=e.l+t,s,i,o=[];n!=e.l;)t=n-e.l,i=e[e.l],s=Hd[i]||Hd[Z2[i]],(i===24||i===25)&&(s=(i===24?Q2:eS)[e[e.l+1]]),!s||!s.f?an(e,t):o.push([s.n,s.f(e,t,r)]);return o}function nS(e){for(var t=[],r=0;r=",PtgGt:">",PtgLe:"<=",PtgLt:"<",PtgMul:"*",PtgNe:"<>",PtgPower:"^",PtgSub:"-"};function aS(e,t){if(!e&&!(t&&t.biff<=5&&t.biff>=2))throw new Error("empty sheet name");return/[^\w\u4E00-\u9FFF\u3040-\u30FF]/.test(e)?"'"+e+"'":e}function fh(e,t,r){if(!e)return"SH33TJSERR0";if(r.biff>8&&(!e.XTI||!e.XTI[t]))return e.SheetNames[t];if(!e.XTI)return"SH33TJSERR6";var n=e.XTI[t];if(r.biff<8)return t>1e4&&(t-=65536),t<0&&(t=-t),t==0?"":e.XTI[t-1];if(!n)return"SH33TJSERR1";var s="";if(r.biff>8)switch(e[n[0]][0]){case 357:return s=n[1]==-1?"#REF":e.SheetNames[n[1]],n[1]==n[2]?s:s+":"+e.SheetNames[n[2]];case 358:return r.SID!=null?e.SheetNames[r.SID]:"SH33TJSSAME"+e[n[0]][0];case 355:default:return"SH33TJSSRC"+e[n[0]][0]}switch(e[n[0]][0][0]){case 1025:return s=n[1]==-1?"#REF":e.SheetNames[n[1]]||"SH33TJSERR3",n[1]==n[2]?s:s+":"+e.SheetNames[n[2]];case 14849:return e[n[0]].slice(1).map(function(i){return i.Name}).join(";;");default:return e[n[0]][0][3]?(s=n[1]==-1?"#REF":e[n[0]][0][3][n[1]]||"SH33TJSERR4",n[1]==n[2]?s:s+":"+e[n[0]][0][3][n[2]]):"SH33TJSERR2"}}function Vd(e,t,r){var n=fh(e,t,r);return n=="#REF"?n:aS(n,r)}function As(e,t,r,n,s){var i=s&&s.biff||8,o={s:{c:0,r:0}},l=[],c,d,u,h=0,m=0,_,x="";if(!e[0]||!e[0][0])return"";for(var f=-1,p="",I=0,S=e[0].length;I=0){switch(e[0][f][1][0]){case 0:p=Et(" ",e[0][f][1][1]);break;case 1:p=Et("\r",e[0][f][1][1]);break;default:if(p="",s.WTF)throw new Error("Unexpected PtgAttrSpaceType "+e[0][f][1][0])}d=d+p,f=-1}l.push(d+sS[w[0]]+c);break;case"PtgIsect":c=l.pop(),d=l.pop(),l.push(d+" "+c);break;case"PtgUnion":c=l.pop(),d=l.pop(),l.push(d+","+c);break;case"PtgRange":c=l.pop(),d=l.pop(),l.push(d+":"+c);break;case"PtgAttrChoose":break;case"PtgAttrGoto":break;case"PtgAttrIf":break;case"PtgAttrIfError":break;case"PtgRef":u=aa(w[1][1],o,s),l.push(ia(u,i));break;case"PtgRefN":u=r?aa(w[1][1],r,s):w[1][1],l.push(ia(u,i));break;case"PtgRef3d":h=w[1][1],u=aa(w[1][2],o,s),x=Vd(n,h,s),l.push(x+"!"+ia(u,i));break;case"PtgFunc":case"PtgFuncVar":var v=w[1][0],y=w[1][1];v||(v=0),v&=127;var R=v==0?[]:l.slice(-v);l.length-=v,y==="User"&&(y=R.shift()),l.push(y+"("+R.join(",")+")");break;case"PtgBool":l.push(w[1]?"TRUE":"FALSE");break;case"PtgInt":l.push(w[1]);break;case"PtgNum":l.push(String(w[1]));break;case"PtgStr":l.push('"'+w[1].replace(/"/g,'""')+'"');break;case"PtgErr":l.push(w[1]);break;case"PtgAreaN":_=Ad(w[1][1],r?{s:r}:o,s),l.push(No(_,s));break;case"PtgArea":_=Ad(w[1][1],o,s),l.push(No(_,s));break;case"PtgArea3d":h=w[1][1],_=w[1][2],x=Vd(n,h,s),l.push(x+"!"+No(_,s));break;case"PtgAttrSum":l.push("SUM("+l.pop()+")");break;case"PtgAttrBaxcel":case"PtgAttrSemi":break;case"PtgName":m=w[1][2];var j=(n.names||[])[m-1]||(n[0]||[])[m],T=j?j.Name:"SH33TJSNAME"+String(m);T&&T.slice(0,6)=="_xlfn."&&!s.xlfn&&(T=T.slice(6)),l.push(T);break;case"PtgNameX":var C=w[1][1];m=w[1][2];var F;if(s.biff<=5)C<0&&(C=-C),n[C]&&(F=n[C][m]);else{var P="";if(((n[C]||[])[0]||[])[0]==14849||(((n[C]||[])[0]||[])[0]==1025?n[C][m]&&n[C][m].itab>0&&(P=n.SheetNames[n[C][m].itab-1]+"!"):P=n.SheetNames[m-1]+"!"),n[C]&&n[C][m])P+=n[C][m].Name;else if(n[0]&&n[0][m])P+=n[0][m].Name;else{var V=(fh(n,C,s)||"").split(";;");V[m-1]?P=V[m-1]:P+="SH33TJSERRX"}l.push(P);break}F||(F={Name:"SH33TJSERRY"}),l.push(F.Name);break;case"PtgParen":var X="(",_e=")";if(f>=0){switch(p="",e[0][f][1][0]){case 2:X=Et(" ",e[0][f][1][1])+X;break;case 3:X=Et("\r",e[0][f][1][1])+X;break;case 4:_e=Et(" ",e[0][f][1][1])+_e;break;case 5:_e=Et("\r",e[0][f][1][1])+_e;break;default:if(s.WTF)throw new Error("Unexpected PtgAttrSpaceType "+e[0][f][1][0])}f=-1}l.push(X+l.pop()+_e);break;case"PtgRefErr":l.push("#REF!");break;case"PtgRefErr3d":l.push("#REF!");break;case"PtgExp":u={c:w[1][1],r:w[1][0]};var B={c:r.c,r:r.r};if(n.sharedf[mt(u)]){var te=n.sharedf[mt(u)];l.push(As(te,o,B,n,s))}else{var J=!1;for(c=0;c!=n.arrayf.length;++c)if(d=n.arrayf[c],!(u.cd[0].e.c)&&!(u.rd[0].e.r)){l.push(As(d[1],o,B,n,s)),J=!0;break}J||l.push(w[1])}break;case"PtgArray":l.push("{"+nS(w[1])+"}");break;case"PtgMemArea":break;case"PtgAttrSpace":case"PtgAttrSpaceSemi":f=I;break;case"PtgTbl":break;case"PtgMemErr":break;case"PtgMissArg":l.push("");break;case"PtgAreaErr":l.push("#REF!");break;case"PtgAreaErr3d":l.push("#REF!");break;case"PtgList":l.push("Table"+w[1].idx+"[#"+w[1].rt+"]");break;case"PtgMemAreaN":case"PtgMemNoMemN":case"PtgAttrNoop":case"PtgSheet":case"PtgEndSheet":break;case"PtgMemFunc":break;case"PtgMemNoMem":break;case"PtgElfCol":case"PtgElfColS":case"PtgElfColSV":case"PtgElfColV":case"PtgElfLel":case"PtgElfRadical":case"PtgElfRadicalLel":case"PtgElfRadicalS":case"PtgElfRw":case"PtgElfRwV":throw new Error("Unsupported ELFs");case"PtgSxName":throw new Error("Unrecognized Formula Token: "+String(w));default:throw new Error("Unrecognized Formula Token: "+String(w))}var G=["PtgAttrSpace","PtgAttrSpaceSemi","PtgAttrGoto"];if(s.biff!=3&&f>=0&&G.indexOf(e[0][I][0])==-1){w=e[0][f];var se=!0;switch(w[1][0]){case 4:se=!1;case 0:p=Et(" ",w[1][1]);break;case 5:se=!1;case 1:p=Et("\r",w[1][1]);break;default:if(p="",s.WTF)throw new Error("Unexpected PtgAttrSpaceType "+w[1][0])}l.push((se?p:"")+l.pop()+(se?"":p)),f=-1}}if(l.length>1&&s.WTF)throw new Error("bad formula stack");return l[0]}function iS(e){if(e==null){var t=pe(8);return t.write_shift(1,3),t.write_shift(1,0),t.write_shift(2,0),t.write_shift(2,0),t.write_shift(2,65535),t}else if(typeof e=="number")return Zn(e);return Zn(0)}function oS(e,t,r,n,s){var i=Qn(t,r,s),o=iS(e.v),l=pe(6),c=33;l.write_shift(2,c),l.write_shift(4,0);for(var d=pe(e.bf.length),u=0;u0?tS(e,i,s,r):null;return[s,o]}var lS=ho,mo=ho,cS=ho,dS=ho,uS={0:"BEEP",1:"OPEN",2:"OPEN.LINKS",3:"CLOSE.ALL",4:"SAVE",5:"SAVE.AS",6:"FILE.DELETE",7:"PAGE.SETUP",8:"PRINT",9:"PRINTER.SETUP",10:"QUIT",11:"NEW.WINDOW",12:"ARRANGE.ALL",13:"WINDOW.SIZE",14:"WINDOW.MOVE",15:"FULL",16:"CLOSE",17:"RUN",22:"SET.PRINT.AREA",23:"SET.PRINT.TITLES",24:"SET.PAGE.BREAK",25:"REMOVE.PAGE.BREAK",26:"FONT",27:"DISPLAY",28:"PROTECT.DOCUMENT",29:"PRECISION",30:"A1.R1C1",31:"CALCULATE.NOW",32:"CALCULATION",34:"DATA.FIND",35:"EXTRACT",36:"DATA.DELETE",37:"SET.DATABASE",38:"SET.CRITERIA",39:"SORT",40:"DATA.SERIES",41:"TABLE",42:"FORMAT.NUMBER",43:"ALIGNMENT",44:"STYLE",45:"BORDER",46:"CELL.PROTECTION",47:"COLUMN.WIDTH",48:"UNDO",49:"CUT",50:"COPY",51:"PASTE",52:"CLEAR",53:"PASTE.SPECIAL",54:"EDIT.DELETE",55:"INSERT",56:"FILL.RIGHT",57:"FILL.DOWN",61:"DEFINE.NAME",62:"CREATE.NAMES",63:"FORMULA.GOTO",64:"FORMULA.FIND",65:"SELECT.LAST.CELL",66:"SHOW.ACTIVE.CELL",67:"GALLERY.AREA",68:"GALLERY.BAR",69:"GALLERY.COLUMN",70:"GALLERY.LINE",71:"GALLERY.PIE",72:"GALLERY.SCATTER",73:"COMBINATION",74:"PREFERRED",75:"ADD.OVERLAY",76:"GRIDLINES",77:"SET.PREFERRED",78:"AXES",79:"LEGEND",80:"ATTACH.TEXT",81:"ADD.ARROW",82:"SELECT.CHART",83:"SELECT.PLOT.AREA",84:"PATTERNS",85:"MAIN.CHART",86:"OVERLAY",87:"SCALE",88:"FORMAT.LEGEND",89:"FORMAT.TEXT",90:"EDIT.REPEAT",91:"PARSE",92:"JUSTIFY",93:"HIDE",94:"UNHIDE",95:"WORKSPACE",96:"FORMULA",97:"FORMULA.FILL",98:"FORMULA.ARRAY",99:"DATA.FIND.NEXT",100:"DATA.FIND.PREV",101:"FORMULA.FIND.NEXT",102:"FORMULA.FIND.PREV",103:"ACTIVATE",104:"ACTIVATE.NEXT",105:"ACTIVATE.PREV",106:"UNLOCKED.NEXT",107:"UNLOCKED.PREV",108:"COPY.PICTURE",109:"SELECT",110:"DELETE.NAME",111:"DELETE.FORMAT",112:"VLINE",113:"HLINE",114:"VPAGE",115:"HPAGE",116:"VSCROLL",117:"HSCROLL",118:"ALERT",119:"NEW",120:"CANCEL.COPY",121:"SHOW.CLIPBOARD",122:"MESSAGE",124:"PASTE.LINK",125:"APP.ACTIVATE",126:"DELETE.ARROW",127:"ROW.HEIGHT",128:"FORMAT.MOVE",129:"FORMAT.SIZE",130:"FORMULA.REPLACE",131:"SEND.KEYS",132:"SELECT.SPECIAL",133:"APPLY.NAMES",134:"REPLACE.FONT",135:"FREEZE.PANES",136:"SHOW.INFO",137:"SPLIT",138:"ON.WINDOW",139:"ON.DATA",140:"DISABLE.INPUT",142:"OUTLINE",143:"LIST.NAMES",144:"FILE.CLOSE",145:"SAVE.WORKBOOK",146:"DATA.FORM",147:"COPY.CHART",148:"ON.TIME",149:"WAIT",150:"FORMAT.FONT",151:"FILL.UP",152:"FILL.LEFT",153:"DELETE.OVERLAY",155:"SHORT.MENUS",159:"SET.UPDATE.STATUS",161:"COLOR.PALETTE",162:"DELETE.STYLE",163:"WINDOW.RESTORE",164:"WINDOW.MAXIMIZE",166:"CHANGE.LINK",167:"CALCULATE.DOCUMENT",168:"ON.KEY",169:"APP.RESTORE",170:"APP.MOVE",171:"APP.SIZE",172:"APP.MINIMIZE",173:"APP.MAXIMIZE",174:"BRING.TO.FRONT",175:"SEND.TO.BACK",185:"MAIN.CHART.TYPE",186:"OVERLAY.CHART.TYPE",187:"SELECT.END",188:"OPEN.MAIL",189:"SEND.MAIL",190:"STANDARD.FONT",191:"CONSOLIDATE",192:"SORT.SPECIAL",193:"GALLERY.3D.AREA",194:"GALLERY.3D.COLUMN",195:"GALLERY.3D.LINE",196:"GALLERY.3D.PIE",197:"VIEW.3D",198:"GOAL.SEEK",199:"WORKGROUP",200:"FILL.GROUP",201:"UPDATE.LINK",202:"PROMOTE",203:"DEMOTE",204:"SHOW.DETAIL",206:"UNGROUP",207:"OBJECT.PROPERTIES",208:"SAVE.NEW.OBJECT",209:"SHARE",210:"SHARE.NAME",211:"DUPLICATE",212:"APPLY.STYLE",213:"ASSIGN.TO.OBJECT",214:"OBJECT.PROTECTION",215:"HIDE.OBJECT",216:"SET.EXTRACT",217:"CREATE.PUBLISHER",218:"SUBSCRIBE.TO",219:"ATTRIBUTES",220:"SHOW.TOOLBAR",222:"PRINT.PREVIEW",223:"EDIT.COLOR",224:"SHOW.LEVELS",225:"FORMAT.MAIN",226:"FORMAT.OVERLAY",227:"ON.RECALC",228:"EDIT.SERIES",229:"DEFINE.STYLE",240:"LINE.PRINT",243:"ENTER.DATA",249:"GALLERY.RADAR",250:"MERGE.STYLES",251:"EDITION.OPTIONS",252:"PASTE.PICTURE",253:"PASTE.PICTURE.LINK",254:"SPELLING",256:"ZOOM",259:"INSERT.OBJECT",260:"WINDOW.MINIMIZE",265:"SOUND.NOTE",266:"SOUND.PLAY",267:"FORMAT.SHAPE",268:"EXTEND.POLYGON",269:"FORMAT.AUTO",272:"GALLERY.3D.BAR",273:"GALLERY.3D.SURFACE",274:"FILL.AUTO",276:"CUSTOMIZE.TOOLBAR",277:"ADD.TOOL",278:"EDIT.OBJECT",279:"ON.DOUBLECLICK",280:"ON.ENTRY",281:"WORKBOOK.ADD",282:"WORKBOOK.MOVE",283:"WORKBOOK.COPY",284:"WORKBOOK.OPTIONS",285:"SAVE.WORKSPACE",288:"CHART.WIZARD",289:"DELETE.TOOL",290:"MOVE.TOOL",291:"WORKBOOK.SELECT",292:"WORKBOOK.ACTIVATE",293:"ASSIGN.TO.TOOL",295:"COPY.TOOL",296:"RESET.TOOL",297:"CONSTRAIN.NUMERIC",298:"PASTE.TOOL",302:"WORKBOOK.NEW",305:"SCENARIO.CELLS",306:"SCENARIO.DELETE",307:"SCENARIO.ADD",308:"SCENARIO.EDIT",309:"SCENARIO.SHOW",310:"SCENARIO.SHOW.NEXT",311:"SCENARIO.SUMMARY",312:"PIVOT.TABLE.WIZARD",313:"PIVOT.FIELD.PROPERTIES",314:"PIVOT.FIELD",315:"PIVOT.ITEM",316:"PIVOT.ADD.FIELDS",318:"OPTIONS.CALCULATION",319:"OPTIONS.EDIT",320:"OPTIONS.VIEW",321:"ADDIN.MANAGER",322:"MENU.EDITOR",323:"ATTACH.TOOLBARS",324:"VBAActivate",325:"OPTIONS.CHART",328:"VBA.INSERT.FILE",330:"VBA.PROCEDURE.DEFINITION",336:"ROUTING.SLIP",338:"ROUTE.DOCUMENT",339:"MAIL.LOGON",342:"INSERT.PICTURE",343:"EDIT.TOOL",344:"GALLERY.DOUGHNUT",350:"CHART.TREND",352:"PIVOT.ITEM.PROPERTIES",354:"WORKBOOK.INSERT",355:"OPTIONS.TRANSITION",356:"OPTIONS.GENERAL",370:"FILTER.ADVANCED",373:"MAIL.ADD.MAILER",374:"MAIL.DELETE.MAILER",375:"MAIL.REPLY",376:"MAIL.REPLY.ALL",377:"MAIL.FORWARD",378:"MAIL.NEXT.LETTER",379:"DATA.LABEL",380:"INSERT.TITLE",381:"FONT.PROPERTIES",382:"MACRO.OPTIONS",383:"WORKBOOK.HIDE",384:"WORKBOOK.UNHIDE",385:"WORKBOOK.DELETE",386:"WORKBOOK.NAME",388:"GALLERY.CUSTOM",390:"ADD.CHART.AUTOFORMAT",391:"DELETE.CHART.AUTOFORMAT",392:"CHART.ADD.DATA",393:"AUTO.OUTLINE",394:"TAB.ORDER",395:"SHOW.DIALOG",396:"SELECT.ALL",397:"UNGROUP.SHEETS",398:"SUBTOTAL.CREATE",399:"SUBTOTAL.REMOVE",400:"RENAME.OBJECT",412:"WORKBOOK.SCROLL",413:"WORKBOOK.NEXT",414:"WORKBOOK.PREV",415:"WORKBOOK.TAB.SPLIT",416:"FULL.SCREEN",417:"WORKBOOK.PROTECT",420:"SCROLLBAR.PROPERTIES",421:"PIVOT.SHOW.PAGES",422:"TEXT.TO.COLUMNS",423:"FORMAT.CHARTTYPE",424:"LINK.FORMAT",425:"TRACER.DISPLAY",430:"TRACER.NAVIGATE",431:"TRACER.CLEAR",432:"TRACER.ERROR",433:"PIVOT.FIELD.GROUP",434:"PIVOT.FIELD.UNGROUP",435:"CHECKBOX.PROPERTIES",436:"LABEL.PROPERTIES",437:"LISTBOX.PROPERTIES",438:"EDITBOX.PROPERTIES",439:"PIVOT.REFRESH",440:"LINK.COMBO",441:"OPEN.TEXT",442:"HIDE.DIALOG",443:"SET.DIALOG.FOCUS",444:"ENABLE.OBJECT",445:"PUSHBUTTON.PROPERTIES",446:"SET.DIALOG.DEFAULT",447:"FILTER",448:"FILTER.SHOW.ALL",449:"CLEAR.OUTLINE",450:"FUNCTION.WIZARD",451:"ADD.LIST.ITEM",452:"SET.LIST.ITEM",453:"REMOVE.LIST.ITEM",454:"SELECT.LIST.ITEM",455:"SET.CONTROL.VALUE",456:"SAVE.COPY.AS",458:"OPTIONS.LISTS.ADD",459:"OPTIONS.LISTS.DELETE",460:"SERIES.AXES",461:"SERIES.X",462:"SERIES.Y",463:"ERRORBAR.X",464:"ERRORBAR.Y",465:"FORMAT.CHART",466:"SERIES.ORDER",467:"MAIL.LOGOFF",468:"CLEAR.ROUTING.SLIP",469:"APP.ACTIVATE.MICROSOFT",470:"MAIL.EDIT.MAILER",471:"ON.SHEET",472:"STANDARD.WIDTH",473:"SCENARIO.MERGE",474:"SUMMARY.INFO",475:"FIND.FILE",476:"ACTIVE.CELL.FONT",477:"ENABLE.TIPWIZARD",478:"VBA.MAKE.ADDIN",480:"INSERTDATATABLE",481:"WORKGROUP.OPTIONS",482:"MAIL.SEND.MAILER",485:"AUTOCORRECT",489:"POST.DOCUMENT",491:"PICKLIST",493:"VIEW.SHOW",494:"VIEW.DEFINE",495:"VIEW.DELETE",509:"SHEET.BACKGROUND",510:"INSERT.MAP.OBJECT",511:"OPTIONS.MENONO",517:"MSOCHECKS",518:"NORMAL",519:"LAYOUT",520:"RM.PRINT.AREA",521:"CLEAR.PRINT.AREA",522:"ADD.PRINT.AREA",523:"MOVE.BRK",545:"HIDECURR.NOTE",546:"HIDEALL.NOTES",547:"DELETE.NOTE",548:"TRAVERSE.NOTES",549:"ACTIVATE.NOTES",620:"PROTECT.REVISIONS",621:"UNPROTECT.REVISIONS",647:"OPTIONS.ME",653:"WEB.PUBLISH",667:"NEWWEBQUERY",673:"PIVOT.TABLE.CHART",753:"OPTIONS.SAVE",755:"OPTIONS.SPELL",808:"HIDEALL.INKANNOTS"},hh={0:"COUNT",1:"IF",2:"ISNA",3:"ISERROR",4:"SUM",5:"AVERAGE",6:"MIN",7:"MAX",8:"ROW",9:"COLUMN",10:"NA",11:"NPV",12:"STDEV",13:"DOLLAR",14:"FIXED",15:"SIN",16:"COS",17:"TAN",18:"ATAN",19:"PI",20:"SQRT",21:"EXP",22:"LN",23:"LOG10",24:"ABS",25:"INT",26:"SIGN",27:"ROUND",28:"LOOKUP",29:"INDEX",30:"REPT",31:"MID",32:"LEN",33:"VALUE",34:"TRUE",35:"FALSE",36:"AND",37:"OR",38:"NOT",39:"MOD",40:"DCOUNT",41:"DSUM",42:"DAVERAGE",43:"DMIN",44:"DMAX",45:"DSTDEV",46:"VAR",47:"DVAR",48:"TEXT",49:"LINEST",50:"TREND",51:"LOGEST",52:"GROWTH",53:"GOTO",54:"HALT",55:"RETURN",56:"PV",57:"FV",58:"NPER",59:"PMT",60:"RATE",61:"MIRR",62:"IRR",63:"RAND",64:"MATCH",65:"DATE",66:"TIME",67:"DAY",68:"MONTH",69:"YEAR",70:"WEEKDAY",71:"HOUR",72:"MINUTE",73:"SECOND",74:"NOW",75:"AREAS",76:"ROWS",77:"COLUMNS",78:"OFFSET",79:"ABSREF",80:"RELREF",81:"ARGUMENT",82:"SEARCH",83:"TRANSPOSE",84:"ERROR",85:"STEP",86:"TYPE",87:"ECHO",88:"SET.NAME",89:"CALLER",90:"DEREF",91:"WINDOWS",92:"SERIES",93:"DOCUMENTS",94:"ACTIVE.CELL",95:"SELECTION",96:"RESULT",97:"ATAN2",98:"ASIN",99:"ACOS",100:"CHOOSE",101:"HLOOKUP",102:"VLOOKUP",103:"LINKS",104:"INPUT",105:"ISREF",106:"GET.FORMULA",107:"GET.NAME",108:"SET.VALUE",109:"LOG",110:"EXEC",111:"CHAR",112:"LOWER",113:"UPPER",114:"PROPER",115:"LEFT",116:"RIGHT",117:"EXACT",118:"TRIM",119:"REPLACE",120:"SUBSTITUTE",121:"CODE",122:"NAMES",123:"DIRECTORY",124:"FIND",125:"CELL",126:"ISERR",127:"ISTEXT",128:"ISNUMBER",129:"ISBLANK",130:"T",131:"N",132:"FOPEN",133:"FCLOSE",134:"FSIZE",135:"FREADLN",136:"FREAD",137:"FWRITELN",138:"FWRITE",139:"FPOS",140:"DATEVALUE",141:"TIMEVALUE",142:"SLN",143:"SYD",144:"DDB",145:"GET.DEF",146:"REFTEXT",147:"TEXTREF",148:"INDIRECT",149:"REGISTER",150:"CALL",151:"ADD.BAR",152:"ADD.MENU",153:"ADD.COMMAND",154:"ENABLE.COMMAND",155:"CHECK.COMMAND",156:"RENAME.COMMAND",157:"SHOW.BAR",158:"DELETE.MENU",159:"DELETE.COMMAND",160:"GET.CHART.ITEM",161:"DIALOG.BOX",162:"CLEAN",163:"MDETERM",164:"MINVERSE",165:"MMULT",166:"FILES",167:"IPMT",168:"PPMT",169:"COUNTA",170:"CANCEL.KEY",171:"FOR",172:"WHILE",173:"BREAK",174:"NEXT",175:"INITIATE",176:"REQUEST",177:"POKE",178:"EXECUTE",179:"TERMINATE",180:"RESTART",181:"HELP",182:"GET.BAR",183:"PRODUCT",184:"FACT",185:"GET.CELL",186:"GET.WORKSPACE",187:"GET.WINDOW",188:"GET.DOCUMENT",189:"DPRODUCT",190:"ISNONTEXT",191:"GET.NOTE",192:"NOTE",193:"STDEVP",194:"VARP",195:"DSTDEVP",196:"DVARP",197:"TRUNC",198:"ISLOGICAL",199:"DCOUNTA",200:"DELETE.BAR",201:"UNREGISTER",204:"USDOLLAR",205:"FINDB",206:"SEARCHB",207:"REPLACEB",208:"LEFTB",209:"RIGHTB",210:"MIDB",211:"LENB",212:"ROUNDUP",213:"ROUNDDOWN",214:"ASC",215:"DBCS",216:"RANK",219:"ADDRESS",220:"DAYS360",221:"TODAY",222:"VDB",223:"ELSE",224:"ELSE.IF",225:"END.IF",226:"FOR.CELL",227:"MEDIAN",228:"SUMPRODUCT",229:"SINH",230:"COSH",231:"TANH",232:"ASINH",233:"ACOSH",234:"ATANH",235:"DGET",236:"CREATE.OBJECT",237:"VOLATILE",238:"LAST.ERROR",239:"CUSTOM.UNDO",240:"CUSTOM.REPEAT",241:"FORMULA.CONVERT",242:"GET.LINK.INFO",243:"TEXT.BOX",244:"INFO",245:"GROUP",246:"GET.OBJECT",247:"DB",248:"PAUSE",251:"RESUME",252:"FREQUENCY",253:"ADD.TOOLBAR",254:"DELETE.TOOLBAR",255:"User",256:"RESET.TOOLBAR",257:"EVALUATE",258:"GET.TOOLBAR",259:"GET.TOOL",260:"SPELLING.CHECK",261:"ERROR.TYPE",262:"APP.TITLE",263:"WINDOW.TITLE",264:"SAVE.TOOLBAR",265:"ENABLE.TOOL",266:"PRESS.TOOL",267:"REGISTER.ID",268:"GET.WORKBOOK",269:"AVEDEV",270:"BETADIST",271:"GAMMALN",272:"BETAINV",273:"BINOMDIST",274:"CHIDIST",275:"CHIINV",276:"COMBIN",277:"CONFIDENCE",278:"CRITBINOM",279:"EVEN",280:"EXPONDIST",281:"FDIST",282:"FINV",283:"FISHER",284:"FISHERINV",285:"FLOOR",286:"GAMMADIST",287:"GAMMAINV",288:"CEILING",289:"HYPGEOMDIST",290:"LOGNORMDIST",291:"LOGINV",292:"NEGBINOMDIST",293:"NORMDIST",294:"NORMSDIST",295:"NORMINV",296:"NORMSINV",297:"STANDARDIZE",298:"ODD",299:"PERMUT",300:"POISSON",301:"TDIST",302:"WEIBULL",303:"SUMXMY2",304:"SUMX2MY2",305:"SUMX2PY2",306:"CHITEST",307:"CORREL",308:"COVAR",309:"FORECAST",310:"FTEST",311:"INTERCEPT",312:"PEARSON",313:"RSQ",314:"STEYX",315:"SLOPE",316:"TTEST",317:"PROB",318:"DEVSQ",319:"GEOMEAN",320:"HARMEAN",321:"SUMSQ",322:"KURT",323:"SKEW",324:"ZTEST",325:"LARGE",326:"SMALL",327:"QUARTILE",328:"PERCENTILE",329:"PERCENTRANK",330:"MODE",331:"TRIMMEAN",332:"TINV",334:"MOVIE.COMMAND",335:"GET.MOVIE",336:"CONCATENATE",337:"POWER",338:"PIVOT.ADD.DATA",339:"GET.PIVOT.TABLE",340:"GET.PIVOT.FIELD",341:"GET.PIVOT.ITEM",342:"RADIANS",343:"DEGREES",344:"SUBTOTAL",345:"SUMIF",346:"COUNTIF",347:"COUNTBLANK",348:"SCENARIO.GET",349:"OPTIONS.LISTS.GET",350:"ISPMT",351:"DATEDIF",352:"DATESTRING",353:"NUMBERSTRING",354:"ROMAN",355:"OPEN.DIALOG",356:"SAVE.DIALOG",357:"VIEW.GET",358:"GETPIVOTDATA",359:"HYPERLINK",360:"PHONETIC",361:"AVERAGEA",362:"MAXA",363:"MINA",364:"STDEVPA",365:"VARPA",366:"STDEVA",367:"VARA",368:"BAHTTEXT",369:"THAIDAYOFWEEK",370:"THAIDIGIT",371:"THAIMONTHOFYEAR",372:"THAINUMSOUND",373:"THAINUMSTRING",374:"THAISTRINGLENGTH",375:"ISTHAIDIGIT",376:"ROUNDBAHTDOWN",377:"ROUNDBAHTUP",378:"THAIYEAR",379:"RTD",380:"CUBEVALUE",381:"CUBEMEMBER",382:"CUBEMEMBERPROPERTY",383:"CUBERANKEDMEMBER",384:"HEX2BIN",385:"HEX2DEC",386:"HEX2OCT",387:"DEC2BIN",388:"DEC2HEX",389:"DEC2OCT",390:"OCT2BIN",391:"OCT2HEX",392:"OCT2DEC",393:"BIN2DEC",394:"BIN2OCT",395:"BIN2HEX",396:"IMSUB",397:"IMDIV",398:"IMPOWER",399:"IMABS",400:"IMSQRT",401:"IMLN",402:"IMLOG2",403:"IMLOG10",404:"IMSIN",405:"IMCOS",406:"IMEXP",407:"IMARGUMENT",408:"IMCONJUGATE",409:"IMAGINARY",410:"IMREAL",411:"COMPLEX",412:"IMSUM",413:"IMPRODUCT",414:"SERIESSUM",415:"FACTDOUBLE",416:"SQRTPI",417:"QUOTIENT",418:"DELTA",419:"GESTEP",420:"ISEVEN",421:"ISODD",422:"MROUND",423:"ERF",424:"ERFC",425:"BESSELJ",426:"BESSELK",427:"BESSELY",428:"BESSELI",429:"XIRR",430:"XNPV",431:"PRICEMAT",432:"YIELDMAT",433:"INTRATE",434:"RECEIVED",435:"DISC",436:"PRICEDISC",437:"YIELDDISC",438:"TBILLEQ",439:"TBILLPRICE",440:"TBILLYIELD",441:"PRICE",442:"YIELD",443:"DOLLARDE",444:"DOLLARFR",445:"NOMINAL",446:"EFFECT",447:"CUMPRINC",448:"CUMIPMT",449:"EDATE",450:"EOMONTH",451:"YEARFRAC",452:"COUPDAYBS",453:"COUPDAYS",454:"COUPDAYSNC",455:"COUPNCD",456:"COUPNUM",457:"COUPPCD",458:"DURATION",459:"MDURATION",460:"ODDLPRICE",461:"ODDLYIELD",462:"ODDFPRICE",463:"ODDFYIELD",464:"RANDBETWEEN",465:"WEEKNUM",466:"AMORDEGRC",467:"AMORLINC",468:"CONVERT",724:"SHEETJS",469:"ACCRINT",470:"ACCRINTM",471:"WORKDAY",472:"NETWORKDAYS",473:"GCD",474:"MULTINOMIAL",475:"LCM",476:"FVSCHEDULE",477:"CUBEKPIMEMBER",478:"CUBESET",479:"CUBESETCOUNT",480:"IFERROR",481:"COUNTIFS",482:"SUMIFS",483:"AVERAGEIF",484:"AVERAGEIFS"},fS={2:1,3:1,10:0,15:1,16:1,17:1,18:1,19:0,20:1,21:1,22:1,23:1,24:1,25:1,26:1,27:2,30:2,31:3,32:1,33:1,34:0,35:0,38:1,39:2,40:3,41:3,42:3,43:3,44:3,45:3,47:3,48:2,53:1,61:3,63:0,65:3,66:3,67:1,68:1,69:1,70:1,71:1,72:1,73:1,74:0,75:1,76:1,77:1,79:2,80:2,83:1,85:0,86:1,89:0,90:1,94:0,95:0,97:2,98:1,99:1,101:3,102:3,105:1,106:1,108:2,111:1,112:1,113:1,114:1,117:2,118:1,119:4,121:1,126:1,127:1,128:1,129:1,130:1,131:1,133:1,134:1,135:1,136:2,137:2,138:2,140:1,141:1,142:3,143:4,144:4,161:1,162:1,163:1,164:1,165:2,172:1,175:2,176:2,177:3,178:2,179:1,184:1,186:1,189:3,190:1,195:3,196:3,197:1,198:1,199:3,201:1,207:4,210:3,211:1,212:2,213:2,214:1,215:1,225:0,229:1,230:1,231:1,232:1,233:1,234:1,235:3,244:1,247:4,252:2,257:1,261:1,271:1,273:4,274:2,275:2,276:2,277:3,278:3,279:1,280:3,281:3,282:3,283:1,284:1,285:2,286:4,287:3,288:2,289:4,290:3,291:3,292:3,293:4,294:1,295:3,296:1,297:3,298:1,299:2,300:3,301:3,302:4,303:2,304:2,305:2,306:2,307:2,308:2,309:3,310:2,311:2,312:2,313:2,314:2,315:2,316:4,325:2,326:2,327:2,328:2,331:2,332:2,337:2,342:1,343:1,346:2,347:1,350:4,351:3,352:1,353:2,360:1,368:1,369:1,370:1,371:1,372:1,373:1,374:1,375:1,376:1,377:1,378:1,382:3,385:1,392:1,393:1,396:2,397:2,398:2,399:1,400:1,401:1,402:1,403:1,404:1,405:1,406:1,407:1,408:1,409:1,410:1,414:4,415:1,416:1,417:2,420:1,421:1,422:2,424:1,425:2,426:2,427:2,428:2,430:3,438:3,439:3,440:3,443:2,444:2,445:2,446:2,447:6,448:6,449:2,450:2,464:2,468:3,476:2,479:1,480:2,65535:0};function hS(e){var t="of:="+e.replace(Xl,"$1[.$2$3$4$5]").replace(/\]:\[/g,":");return t.replace(/;/g,"|").replace(/,/g,";")}function mS(e){return e.replace(/\./,"!")}var oa=typeof Map<"u";function Ql(e,t,r){var n=0,s=e.length;if(r){if(oa?r.has(t):Object.prototype.hasOwnProperty.call(r,t)){for(var i=oa?r.get(t):r[t];n-1?(r.width=ml(n),r.customWidth=1):t.width!=null&&(r.width=t.width),t.hidden&&(r.hidden=!0),t.level!=null&&(r.outlineLevel=r.level=t.level),r}function mh(e,t){if(e){var r=[.7,.7,.75,.75,.3,.3];e.left==null&&(e.left=r[0]),e.right==null&&(e.right=r[1]),e.top==null&&(e.top=r[2]),e.bottom==null&&(e.bottom=r[3]),e.header==null&&(e.header=r[4]),e.footer==null&&(e.footer=r[5])}}function Bn(e,t,r){var n=r.revssf[t.z!=null?t.z:"General"],s=60,i=e.length;if(n==null&&r.ssf){for(;s<392;++s)if(r.ssf[s]==null){cf(t.z,s),r.ssf[s]=t.z,r.revssf[t.z]=n=s;break}}for(s=0;s!=i;++s)if(e[s].numFmtId===n)return s;return e[i]={numFmtId:n,fontId:0,fillId:0,borderId:0,xfId:0,applyNumberFormat:1},i}function xS(e,t,r){if(e&&e["!ref"]){var n=vt(e["!ref"]);if(n.e.c',r=0;r!=e.length;++r)t+='';return t+""}function gS(e,t,r,n,s){var i=!1,o={},l=null;if(n.bookType!=="xlsx"&&t.vbaraw){var c=t.SheetNames[r];try{t.Workbook&&(c=t.Workbook.Sheets[r].CodeName||c)}catch{}i=!0,o.codeName=ya(ht(c))}if(e&&e["!outline"]){var d={summaryBelow:1,summaryRight:1};e["!outline"].above&&(d.summaryBelow=0),e["!outline"].left&&(d.summaryRight=0),l=(l||"")+Fe("outlinePr",null,d)}!i&&!l||(s[s.length]=Fe("sheetPr",l,o))}var _S=["objects","scenarios","selectLockedCells","selectUnlockedCells"],vS=["formatColumns","formatRows","formatCells","insertColumns","insertRows","insertHyperlinks","deleteColumns","deleteRows","sort","autoFilter","pivotTables"];function yS(e){var t={sheet:1};return _S.forEach(function(r){e[r]!=null&&e[r]&&(t[r]="1")}),vS.forEach(function(r){e[r]!=null&&!e[r]&&(t[r]="0")}),e.password&&(t.password=Jf(e.password).toString(16).toUpperCase()),Fe("sheetProtection",null,t)}function wS(e){return mh(e),Fe("pageMargins",null,e)}function SS(e,t){for(var r=[""],n,s=0;s!=t.length;++s)(n=t[s])&&(r[r.length]=Fe("col",null,xo(s,n)));return r[r.length]="",r.join("")}function TS(e,t,r,n){var s=typeof e.ref=="string"?e.ref:Ot(e.ref);r.Workbook||(r.Workbook={Sheets:[]}),r.Workbook.Names||(r.Workbook.Names=[]);var i=r.Workbook.Names,o=Ir(s);o.s.r==o.e.r&&(o.e.r=Ir(t["!ref"]).e.r,s=Ot(o));for(var l=0;l"u"&&(e.z=jt[14]);break;default:s=e.v;break}var l=qt("v",ht(s)),c={r:t},d=Bn(n.cellXfs,e,n);switch(d!==0&&(c.s=d),e.t){case"n":break;case"d":c.t="d";break;case"b":c.t="b";break;case"e":c.t="e";break;case"z":break;default:if(e.v==null){delete e.t;break}if(e.v.length>32767)throw new Error("Text length must not exceed 32767 characters");if(n&&n.bookSST){l=qt("v",""+Ql(n.Strings,e.v,n.revStrings)),c.t="s";break}c.t="str";break}if(e.t!=i&&(e.t=i,e.v=o),typeof e.f=="string"&&e.f){var u=e.F&&e.F.slice(0,t.length)==t?{t:"array",ref:e.F}:null;l=Fe("f",ht(e.f),u)+(e.v!=null?l:"")}return e.l&&r["!links"].push([t,e.l]),e.D&&(c.cm=1),Fe("c",l,c)}function jS(e,t,r,n){var s=[],i=[],o=vt(e["!ref"]),l="",c,d="",u=[],h=0,m=0,_=e["!rows"],x=Array.isArray(e),f={r:d},p,I=-1;for(m=o.s.c;m<=o.e.c;++m)u[m]=sr(m);for(h=o.s.r;h<=o.e.r;++h){for(i=[],d=Jt(h),m=o.s.c;m<=o.e.c;++m){c=u[m]+d;var S=x?(e[h]||[])[m]:e[c];S!==void 0&&(l=ES(S,c,e,t))!=null&&i.push(l)}(i.length>0||_&&_[h])&&(f={r:d},_&&_[h]&&(p=_[h],p.hidden&&(f.hidden=1),I=-1,p.hpx?I=Mi(p.hpx):p.hpt&&(I=p.hpt),I>-1&&(f.ht=I,f.customHeight=1),p.level&&(f.outlineLevel=p.level)),s[s.length]=Fe("row",i.join(""),f))}if(_)for(;h<_.length;++h)_&&_[h]&&(f={r:h+1},p=_[h],p.hidden&&(f.hidden=1),I=-1,p.hpx?I=Mi(p.hpx):p.hpt&&(I=p.hpt),I>-1&&(f.ht=I,f.customHeight=1),p.level&&(f.outlineLevel=p.level),s[s.length]=Fe("row","",f));return s.join("")}function xh(e,t,r,n){var s=[Rt,Fe("worksheet",null,{xmlns:Ns[0],"xmlns:r":Ut.r})],i=r.SheetNames[e],o=0,l="",c=r.Sheets[i];c==null&&(c={});var d=c["!ref"]||"A1",u=vt(d);if(u.e.c>16383||u.e.r>1048575){if(t.WTF)throw new Error("Range "+d+" exceeds format limit A1:XFD1048576");u.e.c=Math.min(u.e.c,16383),u.e.r=Math.min(u.e.c,1048575),d=Ot(u)}n||(n={}),c["!comments"]=[];var h=[];gS(c,r,e,t,s),s[s.length]=Fe("dimension",null,{ref:d}),s[s.length]=bS(c,t,e,r),t.sheetFormat&&(s[s.length]=Fe("sheetFormatPr",null,{defaultRowHeight:t.sheetFormat.defaultRowHeight||"16",baseColWidth:t.sheetFormat.baseColWidth||"10",outlineLevelRow:t.sheetFormat.outlineLevelRow||"7"})),c["!cols"]!=null&&c["!cols"].length>0&&(s[s.length]=SS(c,c["!cols"])),s[o=s.length]="",c["!links"]=[],c["!ref"]!=null&&(l=jS(c,t),l.length>0&&(s[s.length]=l)),s.length>o+1&&(s[s.length]="",s[o]=s[o].replace("/>",">")),c["!protect"]&&(s[s.length]=yS(c["!protect"])),c["!autofilter"]!=null&&(s[s.length]=TS(c["!autofilter"],c,r,e)),c["!merges"]!=null&&c["!merges"].length>0&&(s[s.length]=pS(c["!merges"]));var m=-1,_,x=-1;return c["!links"].length>0&&(s[s.length]="",c["!links"].forEach(function(f){f[1].Target&&(_={ref:f[0]},f[1].Target.charAt(0)!="#"&&(x=ft(n,-1,ht(f[1].Target).replace(/#.*$/,""),it.HLINK),_["r:id"]="rId"+x),(m=f[1].Target.indexOf("#"))>-1&&(_.location=ht(f[1].Target.slice(m+1))),f[1].Tooltip&&(_.tooltip=ht(f[1].Tooltip)),s[s.length]=Fe("hyperlink",null,_))}),s[s.length]=""),delete c["!links"],c["!margins"]!=null&&(s[s.length]=wS(c["!margins"])),(!t||t.ignoreEC||t.ignoreEC==null)&&(s[s.length]=qt("ignoredErrors",Fe("ignoredError",null,{numberStoredAsText:1,sqref:d}))),h.length>0&&(x=ft(n,-1,"../drawings/drawing"+(e+1)+".xml",it.DRAW),s[s.length]=Fe("drawing",null,{"r:id":"rId"+x}),c["!drawing"]=h),c["!comments"].length>0&&(x=ft(n,-1,"../drawings/vmlDrawing"+(e+1)+".vml",it.VML),s[s.length]=Fe("legacyDrawing",null,{"r:id":"rId"+x}),c["!legacy"]=x),s.length>1&&(s[s.length]="",s[1]=s[1].replace("/>",">")),s.join("")}function IS(e,t){var r={},n=e.l+t;r.r=e.read_shift(4),e.l+=4;var s=e.read_shift(2);e.l+=1;var i=e.read_shift(1);return e.l=n,i&7&&(r.level=i&7),i&16&&(r.hidden=!0),i&32&&(r.hpt=s/20),r}function CS(e,t,r){var n=pe(145),s=(r["!rows"]||[])[e]||{};n.write_shift(4,e),n.write_shift(4,0);var i=320;s.hpx?i=Mi(s.hpx)*20:s.hpt&&(i=s.hpt*20),n.write_shift(2,i),n.write_shift(1,0);var o=0;s.level&&(o|=s.level),s.hidden&&(o|=16),(s.hpx||s.hpt)&&(o|=32),n.write_shift(1,o),n.write_shift(1,0);var l=0,c=n.l;n.l+=4;for(var d={r:e,c:0},u=0;u<16;++u)if(!(t.s.c>u+1<<10||t.e.cn.l?n.slice(0,n.l):n}function AS(e,t,r,n){var s=CS(n,r,t);(s.length>17||(t["!rows"]||[])[n])&&Se(e,0,s)}var kS=ss,FS=Ms;function OS(){}function RS(e,t){var r={},n=e[e.l];return++e.l,r.above=!(n&64),r.left=!(n&128),e.l+=18,r.name=Wv(e),r}function DS(e,t,r){r==null&&(r=pe(84+4*e.length));var n=192;t&&(t.above&&(n&=-65),t.left&&(n&=-129)),r.write_shift(1,n);for(var s=1;s<3;++s)r.write_shift(1,0);return Di({auto:1},r),r.write_shift(-4,-1),r.write_shift(-4,-1),kf(e,r),r.slice(0,r.l)}function PS(e){var t=Br(e);return[t]}function NS(e,t,r){return r==null&&(r=pe(8)),ts(t,r)}function LS(e){var t=rs(e);return[t]}function MS(e,t,r){return r==null&&(r=pe(4)),ns(t,r)}function BS(e){var t=Br(e),r=e.read_shift(1);return[t,r,"b"]}function US(e,t,r){return r==null&&(r=pe(9)),ts(t,r),r.write_shift(1,e.v?1:0),r}function zS(e){var t=rs(e),r=e.read_shift(1);return[t,r,"b"]}function $S(e,t,r){return r==null&&(r=pe(5)),ns(t,r),r.write_shift(1,e.v?1:0),r}function WS(e){var t=Br(e),r=e.read_shift(1);return[t,r,"e"]}function HS(e,t,r){return r==null&&(r=pe(9)),ts(t,r),r.write_shift(1,e.v),r}function VS(e){var t=rs(e),r=e.read_shift(1);return[t,r,"e"]}function KS(e,t,r){return r==null&&(r=pe(8)),ns(t,r),r.write_shift(1,e.v),r.write_shift(2,0),r.write_shift(1,0),r}function GS(e){var t=Br(e),r=e.read_shift(4);return[t,r,"s"]}function YS(e,t,r){return r==null&&(r=pe(12)),ts(t,r),r.write_shift(4,t.v),r}function qS(e){var t=rs(e),r=e.read_shift(4);return[t,r,"s"]}function XS(e,t,r){return r==null&&(r=pe(8)),ns(t,r),r.write_shift(4,t.v),r}function JS(e){var t=Br(e),r=Bs(e);return[t,r,"n"]}function ZS(e,t,r){return r==null&&(r=pe(16)),ts(t,r),Zn(e.v,r),r}function QS(e){var t=rs(e),r=Bs(e);return[t,r,"n"]}function eT(e,t,r){return r==null&&(r=pe(12)),ns(t,r),Zn(e.v,r),r}function tT(e){var t=Br(e),r=Ff(e);return[t,r,"n"]}function rT(e,t,r){return r==null&&(r=pe(12)),ts(t,r),Of(e.v,r),r}function nT(e){var t=rs(e),r=Ff(e);return[t,r,"n"]}function sT(e,t,r){return r==null&&(r=pe(8)),ns(t,r),Of(e.v,r),r}function aT(e){var t=Br(e),r=Vl(e);return[t,r,"is"]}function iT(e){var t=Br(e),r=ar(e);return[t,r,"str"]}function oT(e,t,r){return r==null&&(r=pe(12+4*e.v.length)),ts(t,r),$t(e.v,r),r.length>r.l?r.slice(0,r.l):r}function lT(e){var t=rs(e),r=ar(e);return[t,r,"str"]}function cT(e,t,r){return r==null&&(r=pe(8+4*e.v.length)),ns(t,r),$t(e.v,r),r.length>r.l?r.slice(0,r.l):r}function dT(e,t,r){var n=e.l+t,s=Br(e);s.r=r["!row"];var i=e.read_shift(1),o=[s,i,"b"];if(r.cellFormula){e.l+=2;var l=mo(e,n-e.l,r);o[3]=As(l,null,s,r.supbooks,r)}else e.l=n;return o}function uT(e,t,r){var n=e.l+t,s=Br(e);s.r=r["!row"];var i=e.read_shift(1),o=[s,i,"e"];if(r.cellFormula){e.l+=2;var l=mo(e,n-e.l,r);o[3]=As(l,null,s,r.supbooks,r)}else e.l=n;return o}function fT(e,t,r){var n=e.l+t,s=Br(e);s.r=r["!row"];var i=Bs(e),o=[s,i,"n"];if(r.cellFormula){e.l+=2;var l=mo(e,n-e.l,r);o[3]=As(l,null,s,r.supbooks,r)}else e.l=n;return o}function hT(e,t,r){var n=e.l+t,s=Br(e);s.r=r["!row"];var i=ar(e),o=[s,i,"str"];if(r.cellFormula){e.l+=2;var l=mo(e,n-e.l,r);o[3]=As(l,null,s,r.supbooks,r)}else e.l=n;return o}var mT=ss,xT=Ms;function pT(e,t){return t==null&&(t=pe(4)),t.write_shift(4,e),t}function gT(e,t){var r=e.l+t,n=ss(e),s=Kl(e),i=ar(e),o=ar(e),l=ar(e);e.l=r;var c={rfx:n,relId:s,loc:i,display:l};return o&&(c.Tooltip=o),c}function _T(e,t){var r=pe(50+4*(e[1].Target.length+(e[1].Tooltip||"").length));Ms({s:zt(e[0]),e:zt(e[0])},r),Gl("rId"+t,r);var n=e[1].Target.indexOf("#"),s=n==-1?"":e[1].Target.slice(n+1);return $t(s||"",r),$t(e[1].Tooltip||"",r),$t("",r),r.slice(0,r.l)}function vT(){}function yT(e,t,r){var n=e.l+t,s=Rf(e),i=e.read_shift(1),o=[s];if(o[2]=i,r.cellFormula){var l=lS(e,n-e.l,r);o[1]=l}else e.l=n;return o}function wT(e,t,r){var n=e.l+t,s=ss(e),i=[s];if(r.cellFormula){var o=dS(e,n-e.l,r);i[1]=o,e.l=n}else e.l=n;return i}function ST(e,t,r){r==null&&(r=pe(18));var n=xo(e,t);r.write_shift(-4,e),r.write_shift(-4,e),r.write_shift(4,(n.width||10)*256),r.write_shift(4,0);var s=0;return t.hidden&&(s|=1),typeof n.width=="number"&&(s|=2),t.level&&(s|=t.level<<8),r.write_shift(2,s),r}var ph=["left","right","top","bottom","header","footer"];function TT(e){var t={};return ph.forEach(function(r){t[r]=Bs(e)}),t}function bT(e,t){return t==null&&(t=pe(6*8)),mh(e),ph.forEach(function(r){Zn(e[r],t)}),t}function ET(e){var t=e.read_shift(2);return e.l+=28,{RTL:t&32}}function jT(e,t,r){r==null&&(r=pe(30));var n=924;return(((t||{}).Views||[])[0]||{}).RTL&&(n|=32),r.write_shift(2,n),r.write_shift(4,0),r.write_shift(4,0),r.write_shift(4,0),r.write_shift(1,0),r.write_shift(1,0),r.write_shift(2,0),r.write_shift(2,100),r.write_shift(2,0),r.write_shift(2,0),r.write_shift(2,0),r.write_shift(4,0),r}function IT(e){var t=pe(24);return t.write_shift(4,4),t.write_shift(4,1),Ms(e,t),t}function CT(e,t){return t==null&&(t=pe(16*4+2)),t.write_shift(2,e.password?Jf(e.password):0),t.write_shift(4,1),[["objects",!1],["scenarios",!1],["formatCells",!0],["formatColumns",!0],["formatRows",!0],["insertColumns",!0],["insertRows",!0],["insertHyperlinks",!0],["deleteColumns",!0],["deleteRows",!0],["selectLockedCells",!1],["sort",!0],["autoFilter",!0],["pivotTables",!0],["selectUnlockedCells",!1]].forEach(function(r){r[1]?t.write_shift(4,e[r[0]]!=null&&!e[r[0]]?1:0):t.write_shift(4,e[r[0]]!=null&&e[r[0]]?0:1)}),t}function AT(){}function kT(){}function FT(e,t,r,n,s,i,o){if(t.v===void 0)return!1;var l="";switch(t.t){case"b":l=t.v?"1":"0";break;case"d":t=gr(t),t.z=t.z||jt[14],t.v=pr(lr(t.v)),t.t="n";break;case"n":case"e":l=""+t.v;break;default:l=t.v;break}var c={r,c:n};switch(c.s=Bn(s.cellXfs,t,s),t.l&&i["!links"].push([mt(c),t.l]),t.c&&i["!comments"].push([mt(c),t.c]),t.t){case"s":case"str":return s.bookSST?(l=Ql(s.Strings,t.v,s.revStrings),c.t="s",c.v=l,o?Se(e,18,XS(t,c)):Se(e,7,YS(t,c))):(c.t="str",o?Se(e,17,cT(t,c)):Se(e,6,oT(t,c))),!0;case"n":return t.v==(t.v|0)&&t.v>-1e3&&t.v<1e3?o?Se(e,13,sT(t,c)):Se(e,2,rT(t,c)):o?Se(e,16,eT(t,c)):Se(e,5,ZS(t,c)),!0;case"b":return c.t="b",o?Se(e,15,$S(t,c)):Se(e,4,US(t,c)),!0;case"e":return c.t="e",o?Se(e,14,KS(t,c)):Se(e,3,HS(t,c)),!0}return o?Se(e,12,MS(t,c)):Se(e,1,NS(t,c)),!0}function OT(e,t,r,n){var s=vt(t["!ref"]||"A1"),i,o="",l=[];Se(e,145);var c=Array.isArray(t),d=s.e.r;t["!rows"]&&(d=Math.max(s.e.r,t["!rows"].length-1));for(var u=s.s.r;u<=d;++u){o=Jt(u),AS(e,t,s,u);var h=!1;if(u<=s.e.r)for(var m=s.s.c;m<=s.e.c;++m){u===s.s.r&&(l[m]=sr(m)),i=l[m]+o;var _=c?(t[u]||[])[m]:t[i];if(!_){h=!1;continue}h=FT(e,_,u,m,n,t,h)}}Se(e,146)}function RT(e,t){!t||!t["!merges"]||(Se(e,177,pT(t["!merges"].length)),t["!merges"].forEach(function(r){Se(e,176,xT(r))}),Se(e,178))}function DT(e,t){!t||!t["!cols"]||(Se(e,390),t["!cols"].forEach(function(r,n){r&&Se(e,60,ST(n,r))}),Se(e,391))}function PT(e,t){!t||!t["!ref"]||(Se(e,648),Se(e,649,IT(vt(t["!ref"]))),Se(e,650))}function NT(e,t,r){t["!links"].forEach(function(n){if(n[1].Target){var s=ft(r,-1,n[1].Target.replace(/#.*$/,""),it.HLINK);Se(e,494,_T(n,s))}}),delete t["!links"]}function LT(e,t,r,n){if(t["!comments"].length>0){var s=ft(n,-1,"../drawings/vmlDrawing"+(r+1)+".vml",it.VML);Se(e,551,Gl("rId"+s)),t["!legacy"]=s}}function MT(e,t,r,n){if(t["!autofilter"]){var s=t["!autofilter"],i=typeof s.ref=="string"?s.ref:Ot(s.ref);r.Workbook||(r.Workbook={Sheets:[]}),r.Workbook.Names||(r.Workbook.Names=[]);var o=r.Workbook.Names,l=Ir(i);l.s.r==l.e.r&&(l.e.r=Ir(t["!ref"]).e.r,i=Ot(l));for(var c=0;c16383||c.e.r>1048575){if(t.WTF)throw new Error("Range "+(o["!ref"]||"A1")+" exceeds format limit A1:XFD1048576");c.e.c=Math.min(c.e.c,16383),c.e.r=Math.min(c.e.c,1048575)}return o["!links"]=[],o["!comments"]=[],Se(s,129),(r.vbaraw||o["!outline"])&&Se(s,147,DS(l,o["!outline"])),Se(s,148,FS(c)),BT(s,o,r.Workbook),DT(s,o),OT(s,o,e,t),UT(s,o),MT(s,o,r,e),RT(s,o),NT(s,o,n),o["!margins"]&&Se(s,476,bT(o["!margins"])),(!t||t.ignoreEC||t.ignoreEC==null)&&PT(s,o),LT(s,o,e,n),Se(s,130),s.end()}function $T(e,t){e.l+=10;var r=ar(e);return{name:r}}var WT=[["allowRefreshQuery",!1,"bool"],["autoCompressPictures",!0,"bool"],["backupFile",!1,"bool"],["checkCompatibility",!1,"bool"],["CodeName",""],["date1904",!1,"bool"],["defaultThemeVersion",0,"int"],["filterPrivacy",!1,"bool"],["hidePivotFieldList",!1,"bool"],["promptedSolutions",!1,"bool"],["publishItems",!1,"bool"],["refreshAllConnections",!1,"bool"],["saveExternalLinkValues",!0,"bool"],["showBorderUnselectedTables",!0,"bool"],["showInkAnnotation",!0,"bool"],["showObjects","all"],["showPivotChartFilter",!1,"bool"],["updateLinks","userSet"]];function HT(e){return!e.Workbook||!e.Workbook.WBProps?"false":wv(e.Workbook.WBProps.date1904)?"true":"false"}var VT="][*?/\\".split("");function gh(e,t){if(e.length>31)throw new Error("Sheet names cannot exceed 31 chars");var r=!0;return VT.forEach(function(n){if(e.indexOf(n)!=-1)throw new Error("Sheet name cannot contain : \\ / ? * [ ]")}),r}function KT(e,t,r){e.forEach(function(n,s){gh(n);for(var i=0;i22)throw new Error("Bad Code Name: Worksheet"+o)}})}function GT(e){if(!e||!e.SheetNames||!e.Sheets)throw new Error("Invalid Workbook");if(!e.SheetNames.length)throw new Error("Workbook is empty");var t=e.Workbook&&e.Workbook.Sheets||[];KT(e.SheetNames,t,!!e.vbaraw);for(var r=0;r0,n={codeName:"ThisWorkbook"};e.Workbook&&e.Workbook.WBProps&&(WT.forEach(function(l){e.Workbook.WBProps[l[0]]!=null&&e.Workbook.WBProps[l[0]]!=l[1]&&(n[l[0]]=e.Workbook.WBProps[l[0]])}),e.Workbook.WBProps.CodeName&&(n.codeName=e.Workbook.WBProps.CodeName,delete n.CodeName)),t[t.length]=Fe("workbookPr",null,n);var s=e.Workbook&&e.Workbook.Sheets||[],i=0;if(s&&s[0]&&s[0].Hidden){for(t[t.length]="",i=0;i!=e.SheetNames.length&&!(!s[i]||!s[i].Hidden);++i);i==e.SheetNames.length&&(i=0),t[t.length]='',t[t.length]=""}for(t[t.length]="",i=0;i!=e.SheetNames.length;++i){var o={name:ht(e.SheetNames[i].slice(0,31))};if(o.sheetId=""+(i+1),o["r:id"]="rId"+(i+1),s[i])switch(s[i].Hidden){case 1:o.state="hidden";break;case 2:o.state="veryHidden";break}t[t.length]=Fe("sheet",null,o)}return t[t.length]="",r&&(t[t.length]="",e.Workbook&&e.Workbook.Names&&e.Workbook.Names.forEach(function(l){var c={name:l.Name};l.Comment&&(c.comment=l.Comment),l.Sheet!=null&&(c.localSheetId=""+l.Sheet),l.Hidden&&(c.hidden="1"),l.Ref&&(t[t.length]=Fe("definedName",ht(l.Ref),c))}),t[t.length]=""),t.length>2&&(t[t.length]="",t[1]=t[1].replace("/>",">")),t.join("")}function YT(e,t){var r={};return r.Hidden=e.read_shift(4),r.iTabID=e.read_shift(4),r.strRelID=hl(e),r.name=ar(e),r}function qT(e,t){return t||(t=pe(127)),t.write_shift(4,e.Hidden),t.write_shift(4,e.iTabID),Gl(e.strRelID,t),$t(e.name.slice(0,31),t),t.length>t.l?t.slice(0,t.l):t}function XT(e,t){var r={},n=e.read_shift(4);r.defaultThemeVersion=e.read_shift(4);var s=t>8?ar(e):"";return s.length>0&&(r.CodeName=s),r.autoCompressPictures=!!(n&65536),r.backupFile=!!(n&64),r.checkCompatibility=!!(n&4096),r.date1904=!!(n&1),r.filterPrivacy=!!(n&8),r.hidePivotFieldList=!!(n&1024),r.promptedSolutions=!!(n&16),r.publishItems=!!(n&2048),r.refreshAllConnections=!!(n&262144),r.saveExternalLinkValues=!!(n&128),r.showBorderUnselectedTables=!!(n&4),r.showInkAnnotation=!!(n&32),r.showObjects=["all","placeholders","none"][n>>13&3],r.showPivotChartFilter=!!(n&32768),r.updateLinks=["userSet","never","always"][n>>8&3],r}function JT(e,t){t||(t=pe(72));var r=0;return e&&e.filterPrivacy&&(r|=8),t.write_shift(4,r),t.write_shift(4,0),kf(e&&e.CodeName||"ThisWorkbook",t),t.slice(0,t.l)}function ZT(e,t,r){var n=e.l+t;e.l+=4,e.l+=1;var s=e.read_shift(4),i=Hv(e),o=cS(e,0,r),l=Kl(e);e.l=n;var c={Name:i,Ptg:o};return s<268435455&&(c.Sheet=s),l&&(c.Comment=l),c}function QT(e,t){Se(e,143);for(var r=0;r!=t.SheetNames.length;++r){var n=t.Workbook&&t.Workbook.Sheets&&t.Workbook.Sheets[r]&&t.Workbook.Sheets[r].Hidden||0,s={Hidden:n,iTabID:r+1,strRelID:"rId"+(r+1),name:t.SheetNames[r]};Se(e,156,qT(s))}Se(e,144)}function eb(e,t){t||(t=pe(127));for(var r=0;r!=4;++r)t.write_shift(4,0);return $t("SheetJS",t),$t(ji.version,t),$t(ji.version,t),$t("7262",t),t.length>t.l?t.slice(0,t.l):t}function tb(e,t){t||(t=pe(29)),t.write_shift(-4,0),t.write_shift(-4,460),t.write_shift(4,28800),t.write_shift(4,17600),t.write_shift(4,500),t.write_shift(4,e),t.write_shift(4,e);var r=120;return t.write_shift(1,r),t.length>t.l?t.slice(0,t.l):t}function rb(e,t){if(!(!t.Workbook||!t.Workbook.Sheets)){for(var r=t.Workbook.Sheets,n=0,s=-1,i=-1;ns||(Se(e,135),Se(e,158,tb(s)),Se(e,136))}}function nb(e,t){var r=xr();return Se(r,131),Se(r,128,eb()),Se(r,153,JT(e.Workbook&&e.Workbook.WBProps||null)),rb(r,e),QT(r,e),Se(r,132),r.end()}function sb(e,t,r){return(t.slice(-4)===".bin"?nb:_h)(e)}function ab(e,t,r,n,s){return(t.slice(-4)===".bin"?zT:xh)(e,r,n,s)}function ib(e,t,r){return(t.slice(-4)===".bin"?bw:eh)(e,r)}function ob(e,t,r){return(t.slice(-4)===".bin"?Jy:Xf)(e,r)}function lb(e,t,r){return(t.slice(-4)===".bin"?Uw:ah)(e)}function cb(e){return(e.slice(-4)===".bin"?Ow:nh)()}function db(e,t){var r=[];return e.Props&&r.push(iy(e.Props,t)),e.Custprops&&r.push(oy(e.Props,e.Custprops)),r.join("")}function ub(){return""}function fb(e,t){var r=[''];return t.cellXfs.forEach(function(n,s){var i=[];i.push(Fe("NumberFormat",null,{"ss:Format":ht(jt[n.numFmtId])}));var o={"ss:ID":"s"+(21+s)};r.push(Fe("Style",i.join(""),o))}),Fe("Styles",r.join(""))}function vh(e){return Fe("NamedRange",null,{"ss:Name":e.Name,"ss:RefersTo":"="+Jl(e.Ref,{r:0,c:0})})}function hb(e){if(!((e||{}).Workbook||{}).Names)return"";for(var t=e.Workbook.Names,r=[],n=0;n"),e["!margins"].header&&s.push(Fe("Header",null,{"x:Margin":e["!margins"].header})),e["!margins"].footer&&s.push(Fe("Footer",null,{"x:Margin":e["!margins"].footer})),s.push(Fe("PageMargins",null,{"x:Bottom":e["!margins"].bottom||"0.75","x:Left":e["!margins"].left||"0.7","x:Right":e["!margins"].right||"0.7","x:Top":e["!margins"].top||"0.75"})),s.push("")),n&&n.Workbook&&n.Workbook.Sheets&&n.Workbook.Sheets[r])if(n.Workbook.Sheets[r].Hidden)s.push(Fe("Visible",n.Workbook.Sheets[r].Hidden==1?"SheetHidden":"SheetVeryHidden",{}));else{for(var i=0;i")}return((((n||{}).Workbook||{}).Views||[])[0]||{}).RTL&&s.push(""),e["!protect"]&&(s.push(qt("ProtectContents","True")),e["!protect"].objects&&s.push(qt("ProtectObjects","True")),e["!protect"].scenarios&&s.push(qt("ProtectScenarios","True")),e["!protect"].selectLockedCells!=null&&!e["!protect"].selectLockedCells?s.push(qt("EnableSelection","NoSelection")):e["!protect"].selectUnlockedCells!=null&&!e["!protect"].selectUnlockedCells&&s.push(qt("EnableSelection","UnlockedCells")),[["formatCells","AllowFormatCells"],["formatColumns","AllowSizeCols"],["formatRows","AllowSizeRows"],["insertColumns","AllowInsertCols"],["insertRows","AllowInsertRows"],["insertHyperlinks","AllowInsertHyperlinks"],["deleteColumns","AllowDeleteCols"],["deleteRows","AllowDeleteRows"],["sort","AllowSort"],["autoFilter","AllowFilter"],["pivotTables","AllowUsePivotTables"]].forEach(function(o){e["!protect"][o[0]]&&s.push("<"+o[1]+"/>")})),s.length==0?"":Fe("WorksheetOptions",s.join(""),{xmlns:br.x})}function pb(e){return e.map(function(t){var r=yv(t.t||""),n=Fe("ss:Data",r,{xmlns:"http://www.w3.org/TR/REC-html40"});return Fe("Comment",n,{"ss:Author":t.a})}).join("")}function gb(e,t,r,n,s,i,o){if(!e||e.v==null&&e.f==null)return"";var l={};if(e.f&&(l["ss:Formula"]="="+ht(Jl(e.f,o))),e.F&&e.F.slice(0,t.length)==t){var c=zt(e.F.slice(t.length+1));l["ss:ArrayRange"]="RC:R"+(c.r==o.r?"":"["+(c.r-o.r)+"]")+"C"+(c.c==o.c?"":"["+(c.c-o.c)+"]")}if(e.l&&e.l.Target&&(l["ss:HRef"]=ht(e.l.Target),e.l.Tooltip&&(l["x:HRefScreenTip"]=ht(e.l.Tooltip))),r["!merges"])for(var d=r["!merges"],u=0;u!=d.length;++u)d[u].s.c!=o.c||d[u].s.r!=o.r||(d[u].e.c>d[u].s.c&&(l["ss:MergeAcross"]=d[u].e.c-d[u].s.c),d[u].e.r>d[u].s.r&&(l["ss:MergeDown"]=d[u].e.r-d[u].s.r));var h="",m="";switch(e.t){case"z":if(!n.sheetStubs)return"";break;case"n":h="Number",m=String(e.v);break;case"b":h="Boolean",m=e.v?"1":"0";break;case"e":h="Error",m=La[e.v];break;case"d":h="DateTime",m=new Date(e.v).toISOString(),e.z==null&&(e.z=e.z||jt[14]);break;case"s":h="String",m=vv(e.v||"");break}var _=Bn(n.cellXfs,e,n);l["ss:StyleID"]="s"+(21+_),l["ss:Index"]=o.c+1;var x=e.v!=null?m:"",f=e.t=="z"?"":''+x+"";return(e.c||[]).length>0&&(f+=pb(e.c)),Fe("Cell",f,l)}function _b(e,t){var r='"}function vb(e,t,r,n){if(!e["!ref"])return"";var s=vt(e["!ref"]),i=e["!merges"]||[],o=0,l=[];e["!cols"]&&e["!cols"].forEach(function(p,I){ql(p);var S=!!p.width,w=xo(I,p),v={"ss:Index":I+1};S&&(v["ss:Width"]=Ni(w.width)),p.hidden&&(v["ss:Hidden"]="1"),l.push(Fe("Column",null,v))});for(var c=Array.isArray(e),d=s.s.r;d<=s.e.r;++d){for(var u=[_b(d,(e["!rows"]||[])[d])],h=s.s.c;h<=s.e.c;++h){var m=!1;for(o=0;o!=i.length;++o)if(!(i[o].s.c>h)&&!(i[o].s.r>d)&&!(i[o].e.c"),u.length>2&&l.push(u.join(""))}return l.join("")}function yb(e,t,r){var n=[],s=r.SheetNames[e],i=r.Sheets[s],o=i?mb(i,t,e,r):"";return o.length>0&&n.push(""+o+""),o=i?vb(i,t,e,r):"",o.length>0&&n.push(""+o+"
"),n.push(xb(i,t,e,r)),n.join("")}function wb(e,t){t||(t={}),e.SSF||(e.SSF=gr(jt)),e.SSF&&(co(),lo(e.SSF),t.revssf=uo(e.SSF),t.revssf[e.SSF[65535]]=0,t.ssf=e.SSF,t.cellXfs=[],Bn(t.cellXfs,{},{revssf:{General:0}}));var r=[];r.push(db(e,t)),r.push(ub()),r.push(""),r.push("");for(var n=0;n-1||Uf.indexOf(s[i][0])>-1||s[i][1]!=null&&d.push(s[i]);n.length&&xt.utils.cfb_add(t,"/SummaryInformation",Ld(n,Bo.SI,c,Od)),(r.length||d.length)&&xt.utils.cfb_add(t,"/DocumentSummaryInformation",Ld(r,Bo.DSI,l,Fd,d.length?d:null,Bo.UDI))}function Tb(e,t){var r=t||{},n=xt.utils.cfb_new({root:"R"}),s="/Workbook";switch(r.bookType||"xls"){case"xls":r.bookType="biff8";case"xla":r.bookType||(r.bookType="xla");case"biff8":s="/Workbook",r.biff=8;break;case"biff5":s="/Book",r.biff=5;break;default:throw new Error("invalid type "+r.bookType+" for XLS CFB")}return xt.utils.cfb_add(n,s,yh(e,r)),r.biff==8&&(e.Props||e.Custprops)&&Sb(e,n),r.biff==8&&e.vbaraw&&zw(n,xt.read(e.vbaraw,{type:typeof e.vbaraw=="string"?"binary":"buffer"})),n}var bb={0:{f:IS},1:{f:PS},2:{f:tT},3:{f:WS},4:{f:BS},5:{f:JS},6:{f:iT},7:{f:GS},8:{f:hT},9:{f:fT},10:{f:dT},11:{f:uT},12:{f:LS},13:{f:nT},14:{f:VS},15:{f:zS},16:{f:QS},17:{f:lT},18:{f:qS},19:{f:Vl},20:{},21:{},22:{},23:{},24:{},25:{},26:{},27:{},28:{},29:{},30:{},31:{},32:{},33:{},34:{},35:{T:1},36:{T:-1},37:{T:1},38:{T:-1},39:{f:ZT},40:{},42:{},43:{f:iw},44:{f:sw},45:{f:cw},46:{f:uw},47:{f:dw},48:{},49:{f:Lv},50:{},51:{f:Iw},52:{T:1},53:{T:-1},54:{T:1},55:{T:-1},56:{T:1},57:{T:-1},58:{},59:{},60:{f:My},62:{f:aT},63:{f:Rw},64:{f:AT},65:{},66:{},67:{},68:{},69:{},70:{},128:{},129:{T:1},130:{T:-1},131:{T:1,f:an,p:0},132:{T:-1},133:{T:1},134:{T:-1},135:{T:1},136:{T:-1},137:{T:1,f:ET},138:{T:-1},139:{T:1},140:{T:-1},141:{T:1},142:{T:-1},143:{T:1},144:{T:-1},145:{T:1},146:{T:-1},147:{f:RS},148:{f:kS,p:16},151:{f:vT},152:{},153:{f:XT},154:{},155:{},156:{f:YT},157:{},158:{},159:{T:1,f:Yy},160:{T:-1},161:{T:1,f:ss},162:{T:-1},163:{T:1},164:{T:-1},165:{T:1},166:{T:-1},167:{},168:{},169:{},170:{},171:{},172:{T:1},173:{T:-1},174:{},175:{},176:{f:mT},177:{T:1},178:{T:-1},179:{T:1},180:{T:-1},181:{T:1},182:{T:-1},183:{T:1},184:{T:-1},185:{T:1},186:{T:-1},187:{T:1},188:{T:-1},189:{T:1},190:{T:-1},191:{T:1},192:{T:-1},193:{T:1},194:{T:-1},195:{T:1},196:{T:-1},197:{T:1},198:{T:-1},199:{T:1},200:{T:-1},201:{T:1},202:{T:-1},203:{T:1},204:{T:-1},205:{T:1},206:{T:-1},207:{T:1},208:{T:-1},209:{T:1},210:{T:-1},211:{T:1},212:{T:-1},213:{T:1},214:{T:-1},215:{T:1},216:{T:-1},217:{T:1},218:{T:-1},219:{T:1},220:{T:-1},221:{T:1},222:{T:-1},223:{T:1},224:{T:-1},225:{T:1},226:{T:-1},227:{T:1},228:{T:-1},229:{T:1},230:{T:-1},231:{T:1},232:{T:-1},233:{T:1},234:{T:-1},235:{T:1},236:{T:-1},237:{T:1},238:{T:-1},239:{T:1},240:{T:-1},241:{T:1},242:{T:-1},243:{T:1},244:{T:-1},245:{T:1},246:{T:-1},247:{T:1},248:{T:-1},249:{T:1},250:{T:-1},251:{T:1},252:{T:-1},253:{T:1},254:{T:-1},255:{T:1},256:{T:-1},257:{T:1},258:{T:-1},259:{T:1},260:{T:-1},261:{T:1},262:{T:-1},263:{T:1},264:{T:-1},265:{T:1},266:{T:-1},267:{T:1},268:{T:-1},269:{T:1},270:{T:-1},271:{T:1},272:{T:-1},273:{T:1},274:{T:-1},275:{T:1},276:{T:-1},277:{},278:{T:1},279:{T:-1},280:{T:1},281:{T:-1},282:{T:1},283:{T:1},284:{T:-1},285:{T:1},286:{T:-1},287:{T:1},288:{T:-1},289:{T:1},290:{T:-1},291:{T:1},292:{T:-1},293:{T:1},294:{T:-1},295:{T:1},296:{T:-1},297:{T:1},298:{T:-1},299:{T:1},300:{T:-1},301:{T:1},302:{T:-1},303:{T:1},304:{T:-1},305:{T:1},306:{T:-1},307:{T:1},308:{T:-1},309:{T:1},310:{T:-1},311:{T:1},312:{T:-1},313:{T:-1},314:{T:1},315:{T:-1},316:{T:1},317:{T:-1},318:{T:1},319:{T:-1},320:{T:1},321:{T:-1},322:{T:1},323:{T:-1},324:{T:1},325:{T:-1},326:{T:1},327:{T:-1},328:{T:1},329:{T:-1},330:{T:1},331:{T:-1},332:{T:1},333:{T:-1},334:{T:1},335:{f:Ew},336:{T:-1},337:{f:kw,T:1},338:{T:-1},339:{T:1},340:{T:-1},341:{T:1},342:{T:-1},343:{T:1},344:{T:-1},345:{T:1},346:{T:-1},347:{T:1},348:{T:-1},349:{T:1},350:{T:-1},351:{},352:{},353:{T:1},354:{T:-1},355:{f:hl},357:{},358:{},359:{},360:{T:1},361:{},362:{f:Oy},363:{},364:{},366:{},367:{},368:{},369:{},370:{},371:{},372:{T:1},373:{T:-1},374:{T:1},375:{T:-1},376:{T:1},377:{T:-1},378:{T:1},379:{T:-1},380:{T:1},381:{T:-1},382:{T:1},383:{T:-1},384:{T:1},385:{T:-1},386:{T:1},387:{T:-1},388:{T:1},389:{T:-1},390:{T:1},391:{T:-1},392:{T:1},393:{T:-1},394:{T:1},395:{T:-1},396:{},397:{},398:{},399:{},400:{},401:{T:1},403:{},404:{},405:{},406:{},407:{},408:{},409:{},410:{},411:{},412:{},413:{},414:{},415:{},416:{},417:{},418:{},419:{},420:{},421:{},422:{T:1},423:{T:1},424:{T:-1},425:{T:-1},426:{f:yT},427:{f:wT},428:{},429:{T:1},430:{T:-1},431:{T:1},432:{T:-1},433:{T:1},434:{T:-1},435:{T:1},436:{T:-1},437:{T:1},438:{T:-1},439:{T:1},440:{T:-1},441:{T:1},442:{T:-1},443:{T:1},444:{T:-1},445:{T:1},446:{T:-1},447:{T:1},448:{T:-1},449:{T:1},450:{T:-1},451:{T:1},452:{T:-1},453:{T:1},454:{T:-1},455:{T:1},456:{T:-1},457:{T:1},458:{T:-1},459:{T:1},460:{T:-1},461:{T:1},462:{T:-1},463:{T:1},464:{T:-1},465:{T:1},466:{T:-1},467:{T:1},468:{T:-1},469:{T:1},470:{T:-1},471:{},472:{},473:{T:1},474:{T:-1},475:{},476:{f:TT},477:{},478:{},479:{T:1},480:{T:-1},481:{T:1},482:{T:-1},483:{T:1},484:{T:-1},485:{f:OS},486:{T:1},487:{T:-1},488:{T:1},489:{T:-1},490:{T:1},491:{T:-1},492:{T:1},493:{T:-1},494:{f:gT},495:{T:1},496:{T:-1},497:{T:1},498:{T:-1},499:{},500:{T:1},501:{T:-1},502:{T:1},503:{T:-1},504:{},505:{T:1},506:{T:-1},507:{},508:{T:1},509:{T:-1},510:{T:1},511:{T:-1},512:{},513:{},514:{T:1},515:{T:-1},516:{T:1},517:{T:-1},518:{T:1},519:{T:-1},520:{T:1},521:{T:-1},522:{},523:{},524:{},525:{},526:{},527:{},528:{T:1},529:{T:-1},530:{T:1},531:{T:-1},532:{T:1},533:{T:-1},534:{},535:{},536:{},537:{},538:{T:1},539:{T:-1},540:{T:1},541:{T:-1},542:{T:1},548:{},549:{},550:{f:hl},551:{},552:{},553:{},554:{T:1},555:{T:-1},556:{T:1},557:{T:-1},558:{T:1},559:{T:-1},560:{T:1},561:{T:-1},562:{},564:{},565:{T:1},566:{T:-1},569:{T:1},570:{T:-1},572:{},573:{T:1},574:{T:-1},577:{},578:{},579:{},580:{},581:{},582:{},583:{},584:{},585:{},586:{},587:{},588:{T:-1},589:{},590:{T:1},591:{T:-1},592:{T:1},593:{T:-1},594:{T:1},595:{T:-1},596:{},597:{T:1},598:{T:-1},599:{T:1},600:{T:-1},601:{T:1},602:{T:-1},603:{T:1},604:{T:-1},605:{T:1},606:{T:-1},607:{},608:{T:1},609:{T:-1},610:{},611:{T:1},612:{T:-1},613:{T:1},614:{T:-1},615:{T:1},616:{T:-1},617:{T:1},618:{T:-1},619:{T:1},620:{T:-1},625:{},626:{T:1},627:{T:-1},628:{T:1},629:{T:-1},630:{T:1},631:{T:-1},632:{f:Mw},633:{T:1},634:{T:-1},635:{T:1,f:Nw},636:{T:-1},637:{f:zv},638:{T:1},639:{},640:{T:-1},641:{T:1},642:{T:-1},643:{T:1},644:{},645:{T:-1},646:{T:1},648:{T:1},649:{},650:{T:-1},651:{f:$T},652:{},653:{T:1},654:{T:-1},655:{T:1},656:{T:-1},657:{T:1},658:{T:-1},659:{},660:{T:1},661:{},662:{T:-1},663:{},664:{T:1},665:{},666:{T:-1},667:{},668:{},669:{},671:{T:1},672:{T:-1},673:{T:1},674:{T:-1},675:{},676:{},677:{},678:{},679:{},680:{},681:{},1024:{},1025:{},1026:{T:1},1027:{T:-1},1028:{T:1},1029:{T:-1},1030:{},1031:{T:1},1032:{T:-1},1033:{T:1},1034:{T:-1},1035:{},1036:{},1037:{},1038:{T:1},1039:{T:-1},1040:{},1041:{T:1},1042:{T:-1},1043:{},1044:{},1045:{},1046:{T:1},1047:{T:-1},1048:{T:1},1049:{T:-1},1050:{},1051:{T:1},1052:{T:1},1053:{f:kT},1054:{T:1},1055:{},1056:{T:1},1057:{T:-1},1058:{T:1},1059:{T:-1},1061:{},1062:{T:1},1063:{T:-1},1064:{T:1},1065:{T:-1},1066:{T:1},1067:{T:-1},1068:{T:1},1069:{T:-1},1070:{T:1},1071:{T:-1},1072:{T:1},1073:{T:-1},1075:{T:1},1076:{T:-1},1077:{T:1},1078:{T:-1},1079:{T:1},1080:{T:-1},1081:{T:1},1082:{T:-1},1083:{T:1},1084:{T:-1},1085:{},1086:{T:1},1087:{T:-1},1088:{T:1},1089:{T:-1},1090:{T:1},1091:{T:-1},1092:{T:1},1093:{T:-1},1094:{T:1},1095:{T:-1},1096:{},1097:{T:1},1098:{},1099:{T:-1},1100:{T:1},1101:{T:-1},1102:{},1103:{},1104:{},1105:{},1111:{},1112:{},1113:{T:1},1114:{T:-1},1115:{T:1},1116:{T:-1},1117:{},1118:{T:1},1119:{T:-1},1120:{T:1},1121:{T:-1},1122:{T:1},1123:{T:-1},1124:{T:1},1125:{T:-1},1126:{},1128:{T:1},1129:{T:-1},1130:{},1131:{T:1},1132:{T:-1},1133:{T:1},1134:{T:-1},1135:{T:1},1136:{T:-1},1137:{T:1},1138:{T:-1},1139:{T:1},1140:{T:-1},1141:{},1142:{T:1},1143:{T:-1},1144:{T:1},1145:{T:-1},1146:{},1147:{T:1},1148:{T:-1},1149:{T:1},1150:{T:-1},1152:{T:1},1153:{T:-1},1154:{T:-1},1155:{T:-1},1156:{T:-1},1157:{T:1},1158:{T:-1},1159:{T:1},1160:{T:-1},1161:{T:1},1162:{T:-1},1163:{T:1},1164:{T:-1},1165:{T:1},1166:{T:-1},1167:{T:1},1168:{T:-1},1169:{T:1},1170:{T:-1},1171:{},1172:{T:1},1173:{T:-1},1177:{},1178:{T:1},1180:{},1181:{},1182:{},2048:{T:1},2049:{T:-1},2050:{},2051:{T:1},2052:{T:-1},2053:{},2054:{},2055:{T:1},2056:{T:-1},2057:{T:1},2058:{T:-1},2060:{},2067:{},2068:{T:1},2069:{T:-1},2070:{},2071:{},2072:{T:1},2073:{T:-1},2075:{},2076:{},2077:{T:1},2078:{T:-1},2079:{},2080:{T:1},2081:{T:-1},2082:{},2083:{T:1},2084:{T:-1},2085:{T:1},2086:{T:-1},2087:{T:1},2088:{T:-1},2089:{T:1},2090:{T:-1},2091:{},2092:{},2093:{T:1},2094:{T:-1},2095:{},2096:{T:1},2097:{T:-1},2098:{T:1},2099:{T:-1},2100:{T:1},2101:{T:-1},2102:{},2103:{T:1},2104:{T:-1},2105:{},2106:{T:1},2107:{T:-1},2108:{},2109:{T:1},2110:{T:-1},2111:{T:1},2112:{T:-1},2113:{T:1},2114:{T:-1},2115:{},2116:{},2117:{},2118:{T:1},2119:{T:-1},2120:{},2121:{T:1},2122:{T:-1},2123:{T:1},2124:{T:-1},2125:{},2126:{T:1},2127:{T:-1},2128:{},2129:{T:1},2130:{T:-1},2131:{T:1},2132:{T:-1},2133:{T:1},2134:{},2135:{},2136:{},2137:{T:1},2138:{T:-1},2139:{T:1},2140:{T:-1},2141:{},3072:{},3073:{},4096:{T:1},4097:{T:-1},5002:{T:1},5003:{T:-1},5081:{T:1},5082:{T:-1},5083:{},5084:{T:1},5085:{T:-1},5086:{T:1},5087:{T:-1},5088:{},5089:{},5090:{},5092:{T:1},5093:{T:-1},5094:{},5095:{T:1},5096:{T:-1},5097:{},5099:{},65535:{n:""}};function Oe(e,t,r,n){var s=t;if(!isNaN(s)){var i=n||(r||[]).length||0,o=e.next(4);o.write_shift(2,s),o.write_shift(2,i),i>0&&$l(r)&&e.push(r)}}function Eb(e,t,r,n){var s=(r||[]).length||0;if(s<=8224)return Oe(e,t,r,s);var i=t;if(!isNaN(i)){for(var o=r.parts||[],l=0,c=0,d=0;d+(o[l]||8224)<=8224;)d+=o[l]||8224,l++;var u=e.next(4);for(u.write_shift(2,i),u.write_shift(2,d),e.push(r.slice(c,c+d)),c+=d;c=0&&s<65536?Oe(e,2,$y(r,n,s)):Oe(e,3,zy(r,n,s));return;case"b":case"e":Oe(e,5,jb(r,n,t.v,t.t));return;case"s":case"str":Oe(e,4,Ib(r,n,(t.v||"").slice(0,255)));return}Oe(e,1,Ba(null,r,n))}function Ab(e,t,r,n){var s=Array.isArray(t),i=vt(t["!ref"]||"A1"),o,l="",c=[];if(i.e.c>255||i.e.r>16383){if(n.WTF)throw new Error("Range "+(t["!ref"]||"A1")+" exceeds format limit A1:IV16384");i.e.c=Math.min(i.e.c,255),i.e.r=Math.min(i.e.c,16383),o=Ot(i)}for(var d=i.s.r;d<=i.e.r;++d){l=Jt(d);for(var u=i.s.c;u<=i.e.c;++u){d===i.s.r&&(c[u]=sr(u)),o=c[u]+l;var h=s?(t[d]||[])[u]:t[o];h&&Cb(e,h,d,u)}}}function kb(e,t){for(var r=t||{},n=xr(),s=0,i=0;i255||_.e.r>=x){if(t.WTF)throw new Error("Range "+(i["!ref"]||"A1")+" exceeds format limit A1:IV16384");_.e.c=Math.min(_.e.c,255),_.e.r=Math.min(_.e.c,x-1)}Oe(n,2057,Yl(r,16,t)),Oe(n,13,Nr(1)),Oe(n,12,Nr(100)),Oe(n,15,or(!0)),Oe(n,17,or(!1)),Oe(n,16,Zn(.001)),Oe(n,95,or(!0)),Oe(n,42,or(!1)),Oe(n,43,or(!1)),Oe(n,130,Nr(1)),Oe(n,128,Ay()),Oe(n,131,or(!1)),Oe(n,132,or(!1)),d&&Nb(n,i["!cols"]),Oe(n,512,Cy(_,t)),d&&(i["!links"]=[]);for(var f=_.s.r;f<=_.e.r;++f){h=Jt(f);for(var p=_.s.c;p<=_.e.c;++p){f===_.s.r&&(m[p]=sr(p)),u=m[p]+h;var I=c?(i[f]||[])[p]:i[u];I&&(Lb(n,I,f,p,t),d&&I.l&&i["!links"].push([u,I.l]))}}var S=l.CodeName||l.name||s;return d&&Oe(n,574,Ty((o.Views||[])[0])),d&&(i["!merges"]||[]).length&&Oe(n,229,Dy(i["!merges"])),d&&Pb(n,i),Oe(n,442,Gf(S)),d&&Rb(n,i),Oe(n,10),n.end()}function Bb(e,t,r){var n=xr(),s=(e||{}).Workbook||{},i=s.Sheets||[],o=s.WBProps||{},l=r.biff==8,c=r.biff==5;if(Oe(n,2057,Yl(e,5,r)),r.bookType=="xla"&&Oe(n,135),Oe(n,225,l?Nr(1200):null),Oe(n,193,dy(2)),c&&Oe(n,191),c&&Oe(n,192),Oe(n,226),Oe(n,92,vy("SheetJS",r)),Oe(n,66,Nr(l?1200:1252)),l&&Oe(n,353,Nr(0)),l&&Oe(n,448),Oe(n,317,Uy(e.SheetNames.length)),l&&e.vbaraw&&Oe(n,211),l&&e.vbaraw){var d=o.CodeName||"ThisWorkbook";Oe(n,442,Gf(d))}Oe(n,156,Nr(17)),Oe(n,25,or(!1)),Oe(n,18,or(!1)),Oe(n,19,Nr(0)),l&&Oe(n,431,or(!1)),l&&Oe(n,444,Nr(0)),Oe(n,61,Sy()),Oe(n,64,or(!1)),Oe(n,141,Nr(0)),Oe(n,34,or(HT(e)=="true")),Oe(n,14,or(!0)),l&&Oe(n,439,or(!1)),Oe(n,218,Nr(0)),Fb(n,e,r),Ob(n,e.SSF,r),Db(n,r),l&&Oe(n,352,or(!1));var u=n.end(),h=xr();l&&Oe(h,140,Ly()),l&&r.Strings&&Eb(h,252,wy(r.Strings)),Oe(h,10);var m=h.end(),_=xr(),x=0,f=0;for(f=0;f255&&typeof console<"u"&&console.error&&console.error("Worksheet '"+e.SheetNames[r]+"' extends beyond column IV (255). Data may be lost.")}}var i=t||{};switch(i.biff||2){case 8:case 5:return Ub(e,t);case 4:case 3:case 2:return kb(e,t)}throw new Error("invalid type "+i.bookType+" for BIFF")}function zb(e,t,r,n){for(var s=e["!merges"]||[],i=[],o=t.s.c;o<=t.e.c;++o){for(var l=0,c=0,d=0;dr||s[d].s.c>o)&&!(s[d].e.r1&&(_.rowspan=l),c>1&&(_.colspan=c),n.editable?m=''+m+"":h&&(_["data-t"]=h&&h.t||"z",h.v!=null&&(_["data-v"]=h.v),h.z!=null&&(_["data-z"]=h.z),h.l&&(h.l.Target||"#").charAt(0)!="#"&&(m=''+m+"")),_.id=(n.id||"sjs")+"-"+u,i.push(Fe("td",m,_))}}var x="";return x+i.join("")+""}var $b='SheetJS Table Export',Wb="";function Hb(e,t,r){var n=[];return n.join("")+""}function wh(e,t){var r=t||{},n=r.header!=null?r.header:$b,s=r.footer!=null?r.footer:Wb,i=[n],o=Ir(e["!ref"]);r.dense=Array.isArray(e),i.push(Hb(e,o,r));for(var l=o.s.r;l<=o.e.r;++l)i.push(zb(e,o,l,r));return i.push(""+s),i.join("")}function Sh(e,t,r){var n=r||{},s=0,i=0;if(n.origin!=null)if(typeof n.origin=="number")s=n.origin;else{var o=typeof n.origin=="string"?zt(n.origin):n.origin;s=o.r,i=o.c}var l=t.getElementsByTagName("tr"),c=Math.min(n.sheetRows||1e7,l.length),d={s:{r:0,c:0},e:{r:s,c:i}};if(e["!ref"]){var u=Ir(e["!ref"]);d.s.r=Math.min(d.s.r,u.s.r),d.s.c=Math.min(d.s.c,u.s.c),d.e.r=Math.max(d.e.r,u.e.r),d.e.c=Math.max(d.e.c,u.e.c),s==-1&&(d.e.r=s=u.e.r+1)}var h=[],m=0,_=e["!rows"]||(e["!rows"]=[]),x=0,f=0,p=0,I=0,S=0,w=0;for(e["!cols"]||(e["!cols"]=[]);x1||w>1)&&h.push({s:{r:f+s,c:I+i},e:{r:f+s+(S||1)-1,c:I+i+(w||1)-1}});var F={t:"s",v:j},P=R.getAttribute("data-t")||R.getAttribute("t")||"";j!=null&&(j.length==0?F.t=P||"z":n.raw||j.trim().length==0||P=="s"||(j==="TRUE"?F={t:"b",v:!0}:j==="FALSE"?F={t:"b",v:!1}:isNaN(pn(j))?isNaN(va(j).getDate())||(F={t:"d",v:lr(j)},n.cellDates||(F={t:"n",v:pr(F.v)}),F.z=n.dateNF||jt[14]):F={t:"n",v:pn(j)})),F.z===void 0&&T!=null&&(F.z=T);var V="",X=R.getElementsByTagName("A");if(X&&X.length)for(var _e=0;_e=c&&(e["!fullref"]=Ot((d.e.r=l.length-x+f-1+s,d))),e}function Th(e,t){var r=t||{},n=r.dense?[]:{};return Sh(n,e,t)}function Vb(e,t){return es(Th(e,t),t)}function Kd(e){var t="",r=Kb(e);return r&&(t=r(e).getPropertyValue("display")),t||(t=e.style&&e.style.display),t==="none"}function Kb(e){return e.ownerDocument.defaultView&&typeof e.ownerDocument.defaultView.getComputedStyle=="function"?e.ownerDocument.defaultView.getComputedStyle:typeof getComputedStyle=="function"?getComputedStyle:null}var Gb=function(){var e=["",'',"",'',"",'',"",""].join(""),t=""+e+"";return function(){return Rt+t}}(),Gd=function(){var e=function(i){return ht(i).replace(/ +/g,function(o){return''}).replace(/\t/g,"").replace(/\n/g,"").replace(/^ /,"").replace(/ $/,"")},t=` +`,r=` +`,n=function(i,o,l){var c=[];c.push(' +`);var d=0,u=0,h=Ir(i["!ref"]||"A1"),m=i["!merges"]||[],_=0,x=Array.isArray(i);if(i["!cols"])for(u=0;u<=h.e.c;++u)c.push(" +`);var f="",p=i["!rows"]||[];for(d=0;d +`);for(;d<=h.e.r;++d){for(f=p[d]?' table:style-name="ro'+p[d].ods+'"':"",c.push(" +`),u=0;uu)&&!(m[_].s.r>d)&&!(m[_].e.c +`)}return c.push(` +`),c.join("")},s=function(i,o){i.push(` +`),i.push(` +`),i.push(` +`),i.push(` / +`),i.push(` +`),i.push(` / +`),i.push(` +`),i.push(` +`);var l=0;o.SheetNames.map(function(d){return o.Sheets[d]}).forEach(function(d){if(d&&d["!cols"]){for(var u=0;u +`),i.push(' +`),i.push(` +`),++l}}});var c=0;o.SheetNames.map(function(d){return o.Sheets[d]}).forEach(function(d){if(d&&d["!rows"]){for(var u=0;u +`),i.push(' +`),i.push(` +`),++c}}}),i.push(` +`),i.push(` +`),i.push(` +`),i.push(` +`),i.push(` +`)};return function(o,l){var c=[Rt],d=wa({"xmlns:office":"urn:oasis:names:tc:opendocument:xmlns:office:1.0","xmlns:table":"urn:oasis:names:tc:opendocument:xmlns:table:1.0","xmlns:style":"urn:oasis:names:tc:opendocument:xmlns:style:1.0","xmlns:text":"urn:oasis:names:tc:opendocument:xmlns:text:1.0","xmlns:draw":"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0","xmlns:fo":"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0","xmlns:xlink":"http://www.w3.org/1999/xlink","xmlns:dc":"http://purl.org/dc/elements/1.1/","xmlns:meta":"urn:oasis:names:tc:opendocument:xmlns:meta:1.0","xmlns:number":"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0","xmlns:presentation":"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0","xmlns:svg":"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0","xmlns:chart":"urn:oasis:names:tc:opendocument:xmlns:chart:1.0","xmlns:dr3d":"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0","xmlns:math":"http://www.w3.org/1998/Math/MathML","xmlns:form":"urn:oasis:names:tc:opendocument:xmlns:form:1.0","xmlns:script":"urn:oasis:names:tc:opendocument:xmlns:script:1.0","xmlns:ooo":"http://openoffice.org/2004/office","xmlns:ooow":"http://openoffice.org/2004/writer","xmlns:oooc":"http://openoffice.org/2004/calc","xmlns:dom":"http://www.w3.org/2001/xml-events","xmlns:xforms":"http://www.w3.org/2002/xforms","xmlns:xsd":"http://www.w3.org/2001/XMLSchema","xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","xmlns:sheet":"urn:oasis:names:tc:opendocument:sh33tjs:1.0","xmlns:rpt":"http://openoffice.org/2005/report","xmlns:of":"urn:oasis:names:tc:opendocument:xmlns:of:1.2","xmlns:xhtml":"http://www.w3.org/1999/xhtml","xmlns:grddl":"http://www.w3.org/2003/g/data-view#","xmlns:tableooo":"http://openoffice.org/2009/table","xmlns:drawooo":"http://openoffice.org/2010/draw","xmlns:calcext":"urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0","xmlns:loext":"urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0","xmlns:field":"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0","xmlns:formx":"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0","xmlns:css3t":"http://www.w3.org/TR/css3-text/","office:version":"1.2"}),u=wa({"xmlns:config":"urn:oasis:names:tc:opendocument:xmlns:config:1.0","office:mimetype":"application/vnd.oasis.opendocument.spreadsheet"});l.bookType=="fods"?(c.push(" +`),c.push(Mf().replace(/office:document-meta/g,"office:meta"))):c.push(" +`),s(c,o),c.push(` +`),c.push(` +`);for(var h=0;h!=o.SheetNames.length;++h)c.push(n(o.Sheets[o.SheetNames[h]],o,h));return c.push(` +`),c.push(` +`),l.bookType=="fods"?c.push(""):c.push(""),c.join("")}}();function bh(e,t){if(t.bookType=="fods")return Gd(e,t);var r=Ml(),n="",s=[],i=[];return n="mimetype",Ze(r,n,"application/vnd.oasis.opendocument.spreadsheet"),n="content.xml",Ze(r,n,Gd(e,t)),s.push([n,"text/xml"]),i.push([n,"ContentFile"]),n="styles.xml",Ze(r,n,Gb(e,t)),s.push([n,"text/xml"]),i.push([n,"StylesFile"]),n="meta.xml",Ze(r,n,Rt+Mf()),s.push([n,"text/xml"]),i.push([n,"MetadataFile"]),n="manifest.rdf",Ze(r,n,ay(i)),s.push([n,"application/rdf+xml"]),n="META-INF/manifest.xml",Ze(r,n,ny(s)),r}/*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */function Bi(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function Yb(e){return typeof TextEncoder<"u"?new TextEncoder().encode(e):Wr(ya(e))}function qb(e,t){e:for(var r=0;r<=e.length-t.length;++r){for(var n=0;n>7,e[t+14]|=(n&127)<<1;for(var i=0;s>=1;++i,s/=256)e[t+i]=s&255;e[t+15]|=r>=0?0:128}function Sa(e,t){var r=t?t[0]:0,n=e[r]&127;e:if(e[r++]>=128&&(n|=(e[r]&127)<<7,e[r++]<128||(n|=(e[r]&127)<<14,e[r++]<128)||(n|=(e[r]&127)<<21,e[r++]<128)||(n+=(e[r]&127)*Math.pow(2,28),++r,e[r++]<128)||(n+=(e[r]&127)*Math.pow(2,35),++r,e[r++]<128)||(n+=(e[r]&127)*Math.pow(2,42),++r,e[r++]<128)))break e;return t&&(t[0]=r),n}function ut(e){var t=new Uint8Array(7);t[0]=e&127;var r=1;e:if(e>127){if(t[r-1]|=128,t[r]=e>>7&127,++r,e<=16383||(t[r-1]|=128,t[r]=e>>14&127,++r,e<=2097151)||(t[r-1]|=128,t[r]=e>>21&127,++r,e<=268435455)||(t[r-1]|=128,t[r]=e/256>>>21&127,++r,e<=34359738367)||(t[r-1]|=128,t[r]=e/65536>>>21&127,++r,e<=4398046511103))break e;t[r-1]|=128,t[r]=e/16777216>>>21&127,++r}return t.slice(0,r)}function bs(e){var t=0,r=e[t]&127;e:if(e[t++]>=128){if(r|=(e[t]&127)<<7,e[t++]<128||(r|=(e[t]&127)<<14,e[t++]<128)||(r|=(e[t]&127)<<21,e[t++]<128))break e;r|=(e[t]&127)<<28}return r}function Nt(e){for(var t=[],r=[0];r[0]=128;);l=e.slice(c,r[0])}break;case 5:o=4,l=e.slice(r[0],r[0]+o),r[0]+=o;break;case 1:o=8,l=e.slice(r[0],r[0]+o),r[0]+=o;break;case 2:o=Sa(e,r),l=e.slice(r[0],r[0]+o),r[0]+=o;break;case 3:case 4:default:throw new Error("PB Type ".concat(i," for Field ").concat(s," at offset ").concat(n))}var d={data:l,type:i};t[s]==null?t[s]=[d]:t[s].push(d)}return t}function Vt(e){var t=[];return e.forEach(function(r,n){r.forEach(function(s){s.data&&(t.push(ut(n*8+s.type)),s.type==2&&t.push(ut(s.data.length)),t.push(s.data))})}),Ln(t)}function Ur(e){for(var t,r=[],n=[0];n[0]>>0>0),r.push(o)}return r}function fs(e){var t=[];return e.forEach(function(r){var n=[];n[1]=[{data:ut(r.id),type:0}],n[2]=[],r.merge!=null&&(n[3]=[{data:ut(+!!r.merge),type:0}]);var s=[];r.messages.forEach(function(o){s.push(o.data),o.meta[3]=[{type:0,data:ut(o.data.length)}],n[2].push({data:Vt(o.meta),type:2})});var i=Vt(n);t.push(ut(i.length)),t.push(i),s.forEach(function(o){return t.push(o)})}),Ln(t)}function Jb(e,t){if(e!=0)throw new Error("Unexpected Snappy chunk type ".concat(e));for(var r=[0],n=Sa(t,r),s=[];r[0]>2;if(o<60)++o;else{var l=o-59;o=t[r[0]],l>1&&(o|=t[r[0]+1]<<8),l>2&&(o|=t[r[0]+2]<<16),l>3&&(o|=t[r[0]+3]<<24),o>>>=0,o++,r[0]+=l}s.push(t.slice(r[0],r[0]+o)),r[0]+=o;continue}else{var c=0,d=0;if(i==1?(d=(t[r[0]]>>2&7)+4,c=(t[r[0]++]&224)<<3,c|=t[r[0]++]):(d=(t[r[0]++]>>2)+1,i==2?(c=t[r[0]]|t[r[0]+1]<<8,r[0]+=2):(c=(t[r[0]]|t[r[0]+1]<<8|t[r[0]+2]<<16|t[r[0]+3]<<24)>>>0,r[0]+=4)),s=[Ln(s)],c==0)throw new Error("Invalid offset 0");if(c>s[0].length)throw new Error("Invalid offset beyond length");if(d>=c)for(s.push(s[0].slice(-c)),d-=c;d>=s[s.length-1].length;)s.push(s[s.length-1]),d-=s[s.length-1].length;s.push(s[0].slice(-c,-c+d))}}var u=Ln(s);if(u.length!=n)throw new Error("Unexpected length: ".concat(u.length," != ").concat(n));return u}function zr(e){for(var t=[],r=0;r>8&255]))):n<=16777216?(o+=4,t.push(new Uint8Array([248,n-1&255,n-1>>8&255,n-1>>16&255]))):n<=4294967296&&(o+=5,t.push(new Uint8Array([252,n-1&255,n-1>>8&255,n-1>>16&255,n-1>>>24&255]))),t.push(e.slice(r,r+n)),o+=n,s[0]=0,s[1]=o&255,s[2]=o>>8&255,s[3]=o>>16&255,r+=n}return Ln(t)}function Uo(e,t){var r=new Uint8Array(32),n=Bi(r),s=12,i=0;switch(r[0]=5,e.t){case"n":r[1]=2,Xb(r,s,e.v),i|=1,s+=16;break;case"b":r[1]=6,n.setFloat64(s,e.v?1:0,!0),i|=2,s+=8;break;case"s":if(t.indexOf(e.v)==-1)throw new Error("Value ".concat(e.v," missing from SST!"));r[1]=3,n.setUint32(s,t.indexOf(e.v),!0),i|=8,s+=4;break;default:throw"unsupported cell type "+e.t}return n.setUint32(8,i,!0),r.slice(0,s)}function zo(e,t){var r=new Uint8Array(32),n=Bi(r),s=12,i=0;switch(r[0]=3,e.t){case"n":r[2]=2,n.setFloat64(s,e.v,!0),i|=32,s+=8;break;case"b":r[2]=6,n.setFloat64(s,e.v?1:0,!0),i|=32,s+=8;break;case"s":if(t.indexOf(e.v)==-1)throw new Error("Value ".concat(e.v," missing from SST!"));r[2]=3,n.setUint32(s,t.indexOf(e.v),!0),i|=16,s+=4;break;default:throw"unsupported cell type "+e.t}return n.setUint32(4,i,!0),r.slice(0,s)}function jn(e){var t=Nt(e);return Sa(t[1][0].data)}function Zb(e,t,r){var n,s,i,o;if(!((n=e[6])!=null&&n[0])||!((s=e[7])!=null&&s[0]))throw"Mutation only works on post-BNC storages!";var l=((o=(i=e[8])==null?void 0:i[0])==null?void 0:o.data)&&bs(e[8][0].data)>0||!1;if(l)throw"Math only works with normal offsets";for(var c=0,d=Bi(e[7][0].data),u=0,h=[],m=Bi(e[4][0].data),_=0,x=[],f=0;f1&&console.error("The Numbers writer currently writes only the first table");var n=Ir(r["!ref"]);n.s.r=n.s.c=0;var s=!1;n.e.c>9&&(s=!0,n.e.c=9),n.e.r>49&&(s=!0,n.e.r=49),s&&console.error("The Numbers writer is currently limited to ".concat(Ot(n)));var i=Ui(r,{range:n,header:1}),o=["~Sh33tJ5~"];i.forEach(function(W){return W.forEach(function(z){typeof z=="string"&&o.push(z)})});var l={},c=[],d=xt.read(t.numbers,{type:"base64"});d.FileIndex.map(function(W,z){return[W,d.FullPaths[z]]}).forEach(function(W){var z=W[0],D=W[1];if(z.type==2&&z.name.match(/\.iwa/)){var q=z.content,K=zr(q),Z=Ur(K);Z.forEach(function(me){c.push(me.id),l[me.id]={deps:[],location:D,type:bs(me.messages[0].meta[1][0].data)}})}}),c.sort(function(W,z){return W-z});var u=c.filter(function(W){return W>1}).map(function(W){return[W,ut(W)]});d.FileIndex.map(function(W,z){return[W,d.FullPaths[z]]}).forEach(function(W){var z=W[0];if(W[1],!!z.name.match(/\.iwa/)){var D=Ur(zr(z.content));D.forEach(function(q){q.messages.forEach(function(K){u.forEach(function(Z){q.messages.some(function(me){return bs(me.meta[1][0].data)!=11006&&qb(me.data,Z[1])})&&l[Z[0]].deps.push(q.id)})})})}});for(var h=xt.find(d,l[1].location),m=Ur(zr(h.content)),_,x=0;x-1,s=Pf();ec(t=t||{});var i=Ml(),o="",l=0;if(t.cellXfs=[],Bn(t.cellXfs,{},{revssf:{General:0}}),e.Props||(e.Props={}),o="docProps/core.xml",Ze(i,o,Bf(e.Props,t)),s.coreprops.push(o),ft(t.rels,2,o,it.CORE_PROPS),o="docProps/app.xml",!(e.Props&&e.Props.SheetNames))if(!e.Workbook||!e.Workbook.Sheets)e.Props.SheetNames=e.SheetNames;else{for(var c=[],d=0;d0&&(o="docProps/custom.xml",Ze(i,o,$f(e.Custprops)),s.custprops.push(o),ft(t.rels,4,o,it.CUST_PROPS)),l=1;l<=e.SheetNames.length;++l){var u={"!id":{}},h=e.Sheets[e.SheetNames[l-1]],m=(h||{})["!type"]||"sheet";switch(m){case"chart":default:o="xl/worksheets/sheet"+l+"."+r,Ze(i,o,ab(l-1,o,t,e,u)),s.sheets.push(o),ft(t.wbrels,-1,"worksheets/sheet"+l+"."+r,it.WS[0])}if(h){var _=h["!comments"],x=!1,f="";_&&_.length>0&&(f="xl/comments"+l+"."+r,Ze(i,f,lb(_,f)),s.comments.push(f),ft(u,-1,"../comments"+l+"."+r,it.CMNT),x=!0),h["!legacy"]&&x&&Ze(i,"xl/drawings/vmlDrawing"+l+".vml",sh(l,h["!comments"])),delete h["!comments"],delete h["!legacy"]}u["!id"].rId1&&Ze(i,Lf(o),Ss(u))}return t.Strings!=null&&t.Strings.length>0&&(o="xl/sharedStrings."+r,Ze(i,o,ob(t.Strings,o,t)),s.strs.push(o),ft(t.wbrels,-1,"sharedStrings."+r,it.SST)),o="xl/workbook."+r,Ze(i,o,sb(e,o)),s.workbooks.push(o),ft(t.rels,1,o,it.WB),o="xl/theme/theme1.xml",Ze(i,o,rh(e.Themes,t)),s.themes.push(o),ft(t.wbrels,-1,"theme/theme1.xml",it.THEME),o="xl/styles."+r,Ze(i,o,ib(e,o,t)),s.styles.push(o),ft(t.wbrels,-1,"styles."+r,it.STY),e.vbaraw&&n&&(o="xl/vbaProject.bin",Ze(i,o,e.vbaraw),s.vba.push(o),ft(t.wbrels,-1,"vbaProject.bin",it.VBA)),o="xl/metadata."+r,Ze(i,o,cb(o)),s.metadata.push(o),ft(t.wbrels,-1,"metadata."+r,it.XLMETA),Ze(i,"[Content_Types].xml",Nf(s,t)),Ze(i,"_rels/.rels",Ss(t.rels)),Ze(i,"xl/_rels/workbook."+r+".rels",Ss(t.wbrels)),delete t.revssf,delete t.ssf,i}function nE(e,t){_s=1024,e&&!e.SSF&&(e.SSF=gr(jt)),e&&e.SSF&&(co(),lo(e.SSF),t.revssf=uo(e.SSF),t.revssf[e.SSF[65535]]=0,t.ssf=e.SSF),t.rels={},t.wbrels={},t.Strings=[],t.Strings.Count=0,t.Strings.Unique=0,oa?t.revStrings=new Map:(t.revStrings={},t.revStrings.foo=[],delete t.revStrings.foo);var r="xml",n=ih.indexOf(t.bookType)>-1,s=Pf();ec(t=t||{});var i=Ml(),o="",l=0;if(t.cellXfs=[],Bn(t.cellXfs,{},{revssf:{General:0}}),e.Props||(e.Props={}),o="docProps/core.xml",Ze(i,o,Bf(e.Props,t)),s.coreprops.push(o),ft(t.rels,2,o,it.CORE_PROPS),o="docProps/app.xml",!(e.Props&&e.Props.SheetNames))if(!e.Workbook||!e.Workbook.Sheets)e.Props.SheetNames=e.SheetNames;else{for(var c=[],d=0;d0&&(o="docProps/custom.xml",Ze(i,o,$f(e.Custprops)),s.custprops.push(o),ft(t.rels,4,o,it.CUST_PROPS));var u=["SheetJ5"];for(t.tcid=0,l=1;l<=e.SheetNames.length;++l){var h={"!id":{}},m=e.Sheets[e.SheetNames[l-1]],_=(m||{})["!type"]||"sheet";switch(_){case"chart":default:o="xl/worksheets/sheet"+l+"."+r,Ze(i,o,xh(l-1,t,e,h)),s.sheets.push(o),ft(t.wbrels,-1,"worksheets/sheet"+l+"."+r,it.WS[0])}if(m){var x=m["!comments"],f=!1,p="";if(x&&x.length>0){var I=!1;x.forEach(function(S){S[1].forEach(function(w){w.T==!0&&(I=!0)})}),I&&(p="xl/threadedComments/threadedComment"+l+"."+r,Ze(i,p,Dw(x,u,t)),s.threadedcomments.push(p),ft(h,-1,"../threadedComments/threadedComment"+l+"."+r,it.TCMNT)),p="xl/comments"+l+"."+r,Ze(i,p,ah(x)),s.comments.push(p),ft(h,-1,"../comments"+l+"."+r,it.CMNT),f=!0}m["!legacy"]&&f&&Ze(i,"xl/drawings/vmlDrawing"+l+".vml",sh(l,m["!comments"])),delete m["!comments"],delete m["!legacy"]}h["!id"].rId1&&Ze(i,Lf(o),Ss(h))}return t.Strings!=null&&t.Strings.length>0&&(o="xl/sharedStrings."+r,Ze(i,o,Xf(t.Strings,t)),s.strs.push(o),ft(t.wbrels,-1,"sharedStrings."+r,it.SST)),o="xl/workbook."+r,Ze(i,o,_h(e)),s.workbooks.push(o),ft(t.rels,1,o,it.WB),o="xl/theme/theme1.xml",Ze(i,o,rh(e.Themes,t)),s.themes.push(o),ft(t.wbrels,-1,"theme/theme1.xml",it.THEME),o="xl/styles."+r,Ze(i,o,eh(e,t)),s.styles.push(o),ft(t.wbrels,-1,"styles."+r,it.STY),e.vbaraw&&n&&(o="xl/vbaProject.bin",Ze(i,o,e.vbaraw),s.vba.push(o),ft(t.wbrels,-1,"vbaProject.bin",it.VBA)),o="xl/metadata."+r,Ze(i,o,nh()),s.metadata.push(o),ft(t.wbrels,-1,"metadata."+r,it.XLMETA),u.length>1&&(o="xl/persons/person.xml",Ze(i,o,Pw(u)),s.people.push(o),ft(t.wbrels,-1,"persons/person.xml",it.PEOPLE)),Ze(i,"[Content_Types].xml",Nf(s,t)),Ze(i,"_rels/.rels",Ss(t.rels)),Ze(i,"xl/_rels/workbook."+r+".rels",Ss(t.wbrels)),delete t.revssf,delete t.ssf,i}function sE(e,t){var r="";switch((t||{}).type||"base64"){case"buffer":return[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7]];case"base64":r=vn(e.slice(0,12));break;case"binary":r=e;break;case"array":return[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7]];default:throw new Error("Unrecognized type "+(t&&t.type||"undefined"))}return[r.charCodeAt(0),r.charCodeAt(1),r.charCodeAt(2),r.charCodeAt(3),r.charCodeAt(4),r.charCodeAt(5),r.charCodeAt(6),r.charCodeAt(7)]}function Eh(e,t){switch(t.type){case"base64":case"binary":break;case"buffer":case"array":t.type="";break;case"file":return Pa(t.file,xt.write(e,{type:ct?"buffer":""}));case"string":throw new Error("'string' output type invalid for '"+t.bookType+"' files");default:throw new Error("Unrecognized type "+t.type)}return xt.write(e,t)}function aE(e,t){var r=gr(t||{}),n=tE(e,r);return iE(n,r)}function iE(e,t){var r={},n=ct?"nodebuffer":typeof Uint8Array<"u"?"array":"string";if(t.compression&&(r.compression="DEFLATE"),t.password)r.type=n;else switch(t.type){case"base64":r.type="base64";break;case"binary":r.type="string";break;case"string":throw new Error("'string' output type invalid for '"+t.bookType+"' files");case"buffer":case"file":r.type=n;break;default:throw new Error("Unrecognized type "+t.type)}var s=e.FullPaths?xt.write(e,{fileType:"zip",type:{nodebuffer:"buffer",string:"binary"}[r.type]||r.type,compression:!!t.compression}):e.generate(r);if(typeof Deno<"u"&&typeof s=="string"){if(t.type=="binary"||t.type=="base64")return s;s=new Uint8Array(oo(s))}return t.password&&typeof encrypt_agile<"u"?Eh(encrypt_agile(s,t.password),t):t.type==="file"?Pa(t.file,s):t.type=="string"?na(s):s}function oE(e,t){var r=t||{},n=Tb(e,r);return Eh(n,r)}function en(e,t,r){r||(r="");var n=r+e;switch(t.type){case"base64":return _a(ya(n));case"binary":return ya(n);case"string":return e;case"file":return Pa(t.file,n,"utf8");case"buffer":return ct?wn(n,"utf8"):typeof TextEncoder<"u"?new TextEncoder().encode(n):en(n,{type:"binary"}).split("").map(function(s){return s.charCodeAt(0)})}throw new Error("Unrecognized type "+t.type)}function lE(e,t){switch(t.type){case"base64":return _a(e);case"binary":return e;case"string":return e;case"file":return Pa(t.file,e,"binary");case"buffer":return ct?wn(e,"binary"):e.split("").map(function(r){return r.charCodeAt(0)})}throw new Error("Unrecognized type "+t.type)}function ii(e,t){switch(t.type){case"string":case"base64":case"binary":for(var r="",n=0;n0&&(s=0);var h=Jt(c.s.r),m=[],_=[],x=0,f=0,p=Array.isArray(e),I=c.s.r,S=0,w={};p&&!e[I]&&(e[I]=[]);var v=d.skipHidden&&e["!cols"]||[],y=d.skipHidden&&e["!rows"]||[];for(S=c.s.c;S<=c.e.c;++S)if(!(v[S]||{}).hidden)switch(m[S]=sr(S),r=p?e[I][S]:e[m[S]+h],n){case 1:i[S]=S-c.s.c;break;case 2:i[S]=m[S];break;case 3:i[S]=d.header[S-c.s.c];break;default:if(r==null&&(r={w:"__EMPTY",t:"s"}),l=o=yn(r,null,d),f=w[o]||0,!f)w[o]=1;else{do l=o+"_"+f++;while(w[l]);w[o]=f,w[l]=1}i[S]=l}for(I=c.s.r+s;I<=c.e.r;++I)if(!(y[I]||{}).hidden){var R=uE(e,c,I,m,n,i,p,d);(R.isempty===!1||(n===1?d.blankrows!==!1:d.blankrows))&&(_[x++]=R.row)}return _.length=x,_}var Yd=/"/g;function fE(e,t,r,n,s,i,o,l){for(var c=!0,d=[],u="",h=Jt(r),m=t.s.c;m<=t.e.c;++m)if(n[m]){var _=l.dense?(e[r]||[])[m]:e[n[m]+h];if(_==null)u="";else if(_.v!=null){c=!1,u=""+(l.rawNumbers&&_.t=="n"?_.v:yn(_,null,l));for(var x=0,f=0;x!==u.length;++x)if((f=u.charCodeAt(x))===s||f===i||f===34||l.forceQuotes){u='"'+u.replace(Yd,'""')+'"';break}u=="ID"&&(u='"ID"')}else _.f!=null&&!_.F?(c=!1,u="="+_.f,u.indexOf(",")>=0&&(u='"'+u.replace(Yd,'""')+'"')):u="";d.push(u)}return l.blankrows===!1&&c?null:d.join(o)}function tc(e,t){var r=[],n=t??{};if(e==null||e["!ref"]==null)return"";var s=vt(e["!ref"]),i=n.FS!==void 0?n.FS:",",o=i.charCodeAt(0),l=n.RS!==void 0?n.RS:` +`,c=l.charCodeAt(0),d=new RegExp((i=="|"?"\\|":i)+"+$"),u="",h=[];n.dense=Array.isArray(e);for(var m=n.skipHidden&&e["!cols"]||[],_=n.skipHidden&&e["!rows"]||[],x=s.s.c;x<=s.e.c;++x)(m[x]||{}).hidden||(h[x]=sr(x));for(var f=0,p=s.s.r;p<=s.e.r;++p)(_[p]||{}).hidden||(u=fE(e,s,p,h,o,c,i,n),u!=null&&(n.strip&&(u=u.replace(d,"")),(u||n.blankrows!==!1)&&r.push((f++?l:"")+u)));return delete n.dense,r.join("")}function Ih(e,t){t||(t={}),t.FS=" ",t.RS=` +`;var r=tc(e,t);return r}function hE(e){var t="",r,n="";if(e==null||e["!ref"]==null)return[];var s=vt(e["!ref"]),i="",o=[],l,c=[],d=Array.isArray(e);for(l=s.s.c;l<=s.e.c;++l)o[l]=sr(l);for(var u=s.s.r;u<=s.e.r;++u)for(i=Jt(u),l=s.s.c;l<=s.e.c;++l)if(t=o[l]+i,r=d?(e[u]||[])[l]:e[t],n="",r!==void 0){if(r.F!=null){if(t=r.F,!r.f)continue;n=r.f,t.indexOf(":")==-1&&(t=t+":"+t)}if(r.f!=null)n=r.f;else{if(r.t=="z")continue;if(r.t=="n"&&r.v!=null)n=""+r.v;else if(r.t=="b")n=r.v?"TRUE":"FALSE";else if(r.w!==void 0)n="'"+r.w;else{if(r.v===void 0)continue;r.t=="s"?n="'"+r.v:n=""+r.v}}c[c.length]=t+"="+n}return c}function Ch(e,t,r){var n=r||{},s=+!n.skipHeader,i=e||{},o=0,l=0;if(i&&n.origin!=null)if(typeof n.origin=="number")o=n.origin;else{var c=typeof n.origin=="string"?zt(n.origin):n.origin;o=c.r,l=c.c}var d,u={s:{c:0,r:0},e:{c:l,r:o+t.length-1+s}};if(i["!ref"]){var h=vt(i["!ref"]);u.e.c=Math.max(u.e.c,h.e.c),u.e.r=Math.max(u.e.r,h.e.r),o==-1&&(o=h.e.r+1,u.e.r=o+t.length-1+s)}else o==-1&&(o=0,u.e.r=t.length-1+s);var m=n.header||[],_=0;t.forEach(function(f,p){Zt(f).forEach(function(I){(_=m.indexOf(I))==-1&&(m[_=m.length]=I);var S=f[I],w="z",v="",y=mt({c:l+_,r:o+p+s});d=Ta(i,y),S&&typeof S=="object"&&!(S instanceof Date)?i[y]=S:(typeof S=="number"?w="n":typeof S=="boolean"?w="b":typeof S=="string"?w="s":S instanceof Date?(w="d",n.cellDates||(w="n",S=pr(S)),v=n.dateNF||jt[14]):S===null&&n.nullError&&(w="e",S=0),d?(d.t=w,d.v=S,delete d.w,delete d.R,v&&(d.z=v)):i[y]=d={t:w,v:S},v&&(d.z=v))})}),u.e.c=Math.max(u.e.c,l+m.length-1);var x=Jt(o);if(s)for(_=0;_=0&&e.SheetNames.length>t)return t;throw new Error("Cannot find sheet # "+t)}else if(typeof t=="string"){var r=e.SheetNames.indexOf(t);if(r>-1)return r;throw new Error("Cannot find sheet name |"+t+"|")}else throw new Error("Cannot find sheet |"+t+"|")}function pE(){return{SheetNames:[],Sheets:{}}}function gE(e,t,r,n){var s=1;if(!r)for(;s<=65535&&e.SheetNames.indexOf(r="Sheet"+s)!=-1;++s,r=void 0);if(!r||e.SheetNames.length>=65535)throw new Error("Too many worksheets");if(n&&e.SheetNames.indexOf(r)>=0){var i=r.match(/(^.*?)(\d+)$/);s=i&&+i[2]||0;var o=i&&i[1]||r;for(++s;s<=65535&&e.SheetNames.indexOf(r=o+s)!=-1;++s);}if(gh(r),e.SheetNames.indexOf(r)>=0)throw new Error("Worksheet with name |"+r+"| already exists!");return e.SheetNames.push(r),e.Sheets[r]=t,r}function _E(e,t,r){e.Workbook||(e.Workbook={}),e.Workbook.Sheets||(e.Workbook.Sheets=[]);var n=xE(e,t);switch(e.Workbook.Sheets[n]||(e.Workbook.Sheets[n]={}),r){case 0:case 1:case 2:break;default:throw new Error("Bad sheet visibility setting "+r)}e.Workbook.Sheets[n].Hidden=r}function vE(e,t){return e.z=t,e}function Ah(e,t,r){return t?(e.l={Target:t},r&&(e.l.Tooltip=r)):delete e.l,e}function yE(e,t,r){return Ah(e,"#"+t,r)}function wE(e,t,r){e.c||(e.c=[]),e.c.push({t,a:r||"SheetJS"})}function SE(e,t,r,n){for(var s=typeof t!="string"?t:vt(t),i=typeof t=="string"?t:Ot(t),o=s.s.r;o<=s.e.r;++o)for(var l=s.s.c;l<=s.e.c;++l){var c=Ta(e,o,l);c.t="n",c.F=i,delete c.v,o==s.s.r&&l==s.s.c&&(c.f=r,n&&(c.D=!0))}return e}var $o={encode_col:sr,encode_row:Jt,encode_cell:mt,encode_range:Ot,decode_col:Hl,decode_row:Wl,split_cell:Nv,decode_cell:zt,decode_range:Ir,format_cell:yn,sheet_add_aoa:Af,sheet_add_json:Ch,sheet_add_dom:Sh,aoa_to_sheet:Ls,json_to_sheet:mE,table_to_sheet:Th,table_to_book:Vb,sheet_to_csv:tc,sheet_to_txt:Ih,sheet_to_json:Ui,sheet_to_html:wh,sheet_to_formulae:hE,sheet_to_row_object_array:Ui,sheet_get_cell:Ta,book_new:pE,book_append_sheet:gE,book_set_sheet_visibility:_E,cell_set_number_format:vE,cell_set_hyperlink:Ah,cell_set_internal_link:yE,cell_add_comment:wE,sheet_set_array_formula:SE,consts:{SHEET_VISIBLE:0,SHEET_HIDDEN:1,SHEET_VERY_HIDDEN:2}};const TE=["昵称","手机号","密码"];function bE(){const e=$o.aoa_to_sheet([[...TE],["张三","13800001111","Abc12345"]]);e["!cols"]=[{wch:16},{wch:14},{wch:16}];const t=$o.book_new();$o.book_append_sheet(t,e,"用户导入"),dE(t,"导入用户模板.xlsx")}const EE=[{label:"启用",value:"active"},{label:"封禁",value:"disabled"},{label:"已注销",value:"deleted"}],jE=()=>{const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),n=!!e&&!e.tenant_id,{renderTenantId:s}=Yr(),[i,o]=g.useState(!1),[l,c]=g.useState([]),[d,u]=g.useState(1),[h,m]=g.useState(20),[_,x]=g.useState(0),[f,p]=g.useState({}),[I,S]=g.useState(!1),[w,v]=g.useState(!1),[y,R]=g.useState(null),[j,T]=g.useState(!1),[C,F]=g.useState(!1),[P,V]=g.useState(null),[X,_e]=g.useState(null),[B,te]=g.useState(""),[J,G]=g.useState(!1),[se,Q]=g.useState(!1),[de,k]=g.useState(!1),[W,z]=g.useState(!1),[D,q]=g.useState(!1),[K,Z]=g.useState(!1),[me,ie]=g.useState(!1),[he,we]=g.useState(Y0),[He,ze]=g.useState(!1),[gt,qe]=g.useState(!1),[le,fe]=g.useState(null),[Re,Ue]=g.useState(""),[nt,Tt]=g.useState(!1),[yt,De]=g.useState([]),[Ce,Qe]=g.useState(e==null?void 0:e.tenant_id),[Xe,Je]=g.useState(null),[xe,ke]=g.useState(),[et,_t]=g.useState(!1),[Wt,Sn]=g.useState(!1),[cr,as]=g.useState(null),[Tn]=b.useForm(),[kr]=b.useForm(),[qr]=b.useForm(),[bn]=b.useForm(),[En]=b.useForm(),[St]=b.useForm(),st=async(H=d,ee=h,ye=f)=>{o(!0);try{const Ne=await Lt.list({...ye,page:H,page_size:ee});(Ne.code===0||Ne.code===200)&&Ne.data?(c(Ne.data.items),x(Ne.data.total),u(Ne.data.page),m(Ne.data.size)):E.error(Ne.message||"获取用户列表失败")}catch(Ne){E.error(Ne.message||"获取用户列表失败")}finally{o(!1)}},kt=async H=>{const ee=await R_(H);return we(ee),ee},dr=async H=>{if(Qe(H),!H)return De([]),[];try{const ee=await Fn.list(r?H:void 0);if((ee.code===0||ee.code===200)&&ee.data)return De(ee.data),ee.data;E.error(ee.message||"获取用户分组失败")}catch(ee){E.error(ee.message||"获取用户分组失败")}return[]};g.useEffect(()=>{st(1,h,f),kt(r||e==null?void 0:e.tenant_id),e!=null&&e.tenant_id&&dr(e.tenant_id)},[]);const Qt=H=>{const ee={id:r&&H.id?Number(H.id):void 0,user_no:!r&&H.user_no?Number(H.user_no):void 0,tenant_id:H.tenant_id,policy_group_id:H.policy_group_id,status:H.status,keyword:H.keyword};p(ee),st(1,h,ee)},Ht=async H=>{const ee=H.tenant_id;Ce!==ee&&await dr(ee),Je(H),ke(H.policy_group_id)},ur=async()=>{if(!(!Xe||!xe)){_t(!0);try{const H=await Fn.assignUsers(xe,Xe.tenant_id,[Xe.id]);H.code===0||H.code===200?(E.success("用户分组已调整"),Je(null),st()):E.error(H.message||"调整用户分组失败")}catch(H){E.error(H.message||"调整用户分组失败")}finally{_t(!1)}}},Xr=H=>{const ee=H.status==="active",ye=ee?"封禁":"解封";Me.confirm({title:`${ye}用户`,content:ee?`确认${ye}用户「${H.nickname||H.username}」?${ye}后该用户将被强制下线并无法登录。`:`确认${ye}用户「${H.nickname||H.username}」?${ye}后该用户可以正常登录使用。`,okText:`确认${ye}`,okButtonProps:{danger:ee},cancelText:"取消",onOk:async()=>{try{const Ne=ee?"disabled":"active",We=await Lt.updateStatus(H.id,Ne);We.code===0||We.code===200?(E.success(`用户已${ye}`),st()):E.error(We.message||`${ye}失败`)}catch(Ne){E.error(Ne.message||`${ye}失败`)}}})},It=async()=>{try{const H=await En.validateFields(),ee=Array.from(new Set(String(H.usernames).split(/\r?\n/).map(dt=>dt.trim()).filter(Boolean)));if(ee.length>500){E.error("单次最多封禁 500 个用户");return}q(!0);const ye=await Lt.batchBan(ee);if(!(ye.code===0||ye.code===200)||!ye.data){E.error(ye.message||"批量封禁失败");return}z(!1),En.resetFields(),st();const We=ye.data.results.filter(dt=>dt.status==="failed");Me.info({title:"批量封禁结果",width:640,content:a.jsxs("div",{children:[a.jsxs("div",{style:{marginBottom:We.length>0?12:0},children:["成功 ",ye.data.success_count," 人,失败 ",ye.data.failed_count," 人。 成功项均已撤销登录会话并发送强制下线指令。"]}),We.length>0&&a.jsx(Ye,{size:"small",rowKey:"username",pagination:!1,scroll:{y:300},dataSource:We,columns:[{title:"用户名",dataIndex:"username",width:180},{title:"失败原因",dataIndex:"reason"}]})]})})}catch(H){if(H!=null&&H.errorFields)return;E.error(H.message||"批量封禁失败")}finally{q(!1)}},Fr=async()=>{var H;try{const ee=await St.validateFields();ie(!0);const ye=await Lt.banByIP(String(ee.ip).trim());if(!(ye.code===0||ye.code===200)||!ye.data){E.error(ye.message||"按 IP 封禁失败");return}Z(!1),St.resetFields(),st();const We=ye.data.results.filter(dt=>dt.status==="failed");Me.info({title:"IP 封禁结果",width:640,content:a.jsxs("div",{children:[a.jsxs("div",{style:{marginBottom:We.length>0?12:0},children:["IP ",ye.data.ip,",命中 ",ye.data.matched_count," 人, 成功 ",ye.data.success_count," 人,失败 ",ye.data.failed_count," 人。 成功项均已撤销登录会话并发送强制下线指令。"]}),We.length>0&&a.jsx(Ye,{size:"small",rowKey:"username",pagination:!1,scroll:{y:300},dataSource:We,columns:[{title:"用户名",dataIndex:"username",width:180},{title:"失败原因",dataIndex:"reason"}]})]})})}catch(ee){if(ee!=null&&ee.errorFields)return;if((H=ee==null?void 0:ee.message)!=null&&H.includes("timeout")){E.warning("请求超时,后台可能仍在处理,请稍后刷新用户列表确认状态");return}E.error(ee.message||"按 IP 封禁失败")}finally{ie(!1)}},er=async()=>{kr.resetFields();const H=await kt(r||e==null?void 0:e.tenant_id);kr.setFieldsValue({password:Za(H.minLength)}),T(!0)},vr=async()=>{var H,ee;try{const ye=await kr.validateFields(),Ne=r?ye.tenant_id:e==null?void 0:e.tenant_id;if(!Ne){console.error("租户信息调试:",{admin:e,tenantId:e==null?void 0:e.tenant_id,isPlatformAdmin:r}),E.error(`无法获取租户信息(当前 admin.tenant_id = ${e==null?void 0:e.tenant_id}),请联系管理员`);return}let We=((H=ye.nickname)==null?void 0:H.trim())||void 0;if(!We)try{const{prefixes:bt,suffixes:tr}=await ae();if(bt.length>0&&tr.length>0){const wt=bt[Math.floor(Math.random()*bt.length)],is=tr[Math.floor(Math.random()*tr.length)];We=`${wt}的${is}`}}catch{}const dt=await Lt.create({tenant_id:Ne,phone:((ee=ye.phone)==null?void 0:ee.trim())||void 0,nickname:We,password:ye.password});dt.code===0||dt.code===200?(E.success("用户已创建"),T(!1),st()):E.error(dt.message||"创建用户失败")}catch(ye){if(ye!=null&&ye.errorFields)return;E.error(ye.message||"创建用户失败")}},on=()=>Za(he.minLength),ln=async H=>{V(H),qr.resetFields();const ee=await kt(r?H.tenant_id:e==null?void 0:e.tenant_id);qr.setFieldsValue({password:Za(ee.minLength)}),F(!0)},A=async H=>{const ee=H.getFieldValue("password");if(!ee){E.warning("请先生成密码");return}try{await navigator.clipboard.writeText(ee),E.success("密码已复制到剪贴板")}catch{E.error("复制失败,请手动复制")}},L=async()=>{if(P)try{const H=await qr.validateFields(),ee=await Lt.resetPassword(P.id,H.password);ee.code===0||ee.code===200?(E.success("密码已重置"),F(!1),st()):E.error(ee.message||"重置密码失败")}catch(H){if(H!=null&&H.errorFields)return;E.error(H.message||"重置密码失败")}},O=H=>{const ye=!(H.can_view_security_info??!1);Me.confirm({title:"安全信息查看权限",content:`确认将用户「${H.nickname||H.username}」的安全信息查看权限${ye?"开启":"关闭"}?`,okText:"确认",cancelText:"取消",onOk:async()=>{try{const Ne=await Lt.updateSecurityPerm(H.id,ye);Ne.code===0||Ne.code===200?(E.success("安全权限已更新"),st()):E.error(Ne.message||"更新安全权限失败")}catch(Ne){E.error(Ne.message||"更新安全权限失败")}}})},N=H=>{Me.confirm({title:"强制用户下线",content:`确认强制用户「${H.nickname||H.username}」下线?将踢出该用户的所有在线终端。`,okText:"确认下线",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const ee=await Lt.kick(H.id);ee.code===0||ee.code===200?E.success("用户已强制下线"):E.error(ee.message||"操作失败")}catch(ee){E.error(ee.message||"操作失败")}}})},M=H=>{if(!H.username_editable||!H.username_prefix){E.warning("该账号不符合自动分配规则,不能修改用户名");return}_e(H),te(H.username_suffix||"")},U=async()=>{if(!X||!/^[0-9]{4,8}$/.test(B)){E.error("请输入4至8位数字");return}if(B===X.username_suffix){E.warning("用户名数字部分没有变化");return}G(!0);try{const H=await Lt.updateUsername(X.id,B);if(!(H.code===0||H.code===200)||!H.data){E.error(H.message||"修改用户名失败");return}const ye=H.data;ye.force_logout_succeeded?E.success("用户名已修改,用户已被强制下线"):E.warning("用户名已修改,但部分会话下线失败,请手动执行强制下线"),c(Ne=>Ne.map(We=>We.id===X.id?{...We,username:ye.username,username_prefix:ye.username_prefix,username_suffix:ye.username_suffix}:We)),R(Ne=>(Ne==null?void 0:Ne.id)===X.id?{...Ne,username:ye.username,username_prefix:ye.username_prefix,username_suffix:ye.username_suffix}:Ne),_e(null)}catch(H){E.error(H.message||"修改用户名失败")}finally{G(!1)}},ne=async H=>{if(fe(H),H.login_ip_whitelist!==void 0)Ue(H.login_ip_whitelist);else try{const ee=await Lt.detail(H.id),ye=ee.code===0||ee.code===200;Ue(ye&&ee.data?ee.data.login_ip_whitelist??"":"")}catch{Ue("")}qe(!0)},ge=async()=>{if(le){Tt(!0);try{const H=await Lt.updateIPWhitelist(le.id,Re.trim());H.code===0||H.code===200?(E.success("IP 白名单已保存"),qe(!1),st()):E.error(H.message||"保存失败")}catch(H){E.error(H.message||"保存失败")}finally{Tt(!1)}}},re=H=>{Me.confirm({title:"强制注销用户",content:`确认强制注销用户「${H.nickname||H.username}」?注销后该用户数据将被清除且无法恢复。`,okText:"确认注销",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const ee=await Lt.forceDeactivate(H.id);ee.code===0||ee.code===200?(E.success("用户已强制注销"),st()):E.error(ee.message||"注销失败")}catch(ee){E.error(ee.message||"注销失败")}}})},ae=async()=>{const[H,ee]=await Promise.all([fetch("/前缀.txt").then(We=>We.text()),fetch("/后缀.txt").then(We=>We.text())]),ye=H.split(` +`).map(We=>We.trim()).filter(Boolean),Ne=ee.split(` +`).map(We=>We.trim()).filter(Boolean);return{prefixes:ye,suffixes:Ne}},oe=(H,ee,ye)=>{const Ne=[];for(let We=0;We{const Ne=new Date,We=`${Ne.getFullYear()}-${String(Ne.getMonth()+1).padStart(2,"0")}-${String(Ne.getDate()).padStart(2,"0")} ${String(Ne.getHours()).padStart(2,"0")}:${String(Ne.getMinutes()).padStart(2,"0")}:${String(Ne.getSeconds()).padStart(2,"0")}`;let dt=`批量创建用户 - 生成时间:${We} +`;r&&(dt+=`租户 ID:${ye} +`),dt+=`创建数量:${H.length} +`,dt+=`================================================ +`,dt+=`昵称 用户名 密码 +`,dt+=`------------------------------------------------ +`;for(const wt of H){const is=ee.get(wt.nickname)||"";dt+=`${wt.nickname} ${wt.username} ${is} +`}const yr=new Blob(["\uFEFF"+dt],{type:"text/plain;charset=utf-8"}),bt=URL.createObjectURL(yr),tr=document.createElement("a");tr.href=bt,tr.download=`批量创建用户_${We.replace(/[: ]/g,"-")}.txt`,document.body.appendChild(tr),tr.click(),document.body.removeChild(tr),URL.revokeObjectURL(bt)},Pe=async()=>{try{const H=await bn.validateFields(),ee=r?H.tenant_id:e==null?void 0:e.tenant_id;if(!ee){E.error("无法获取租户信息");return}const ye=H.count;k(!0);let Ne,We;try{const wt=await ae();Ne=wt.prefixes,We=wt.suffixes}catch{E.error("加载前缀/后缀文件失败"),k(!1);return}if(Ne.length===0||We.length===0){E.error("前缀或后缀文件为空"),k(!1);return}const dt=oe(ye,Ne,We),yr=new Map;dt.forEach(wt=>yr.set(wt.nickname,wt.password));const bt=await Lt.batchCreate({tenant_id:ee,users:dt});if((bt.code===0||bt.code===200)&&bt.data){const{created:wt,failed:is}=bt.data;E.success(`成功创建 ${wt.length} 名用户${is>0?`,${is} 名失败`:""}`),Ee(wt,yr,ee),Q(!1),st()}else E.error(bt.message||"批量创建失败")}catch(H){if(H!=null&&H.errorFields)return;E.error(H.message||"批量创建失败")}finally{k(!1)}},Be=async H=>{let ee;if(r){if(ee=Tn.getFieldValue("tenant_id"),!ee){E.warning("平台管理员请先在筛选栏选择租户,再进行 Excel 导入");return}}else if(ee=e==null?void 0:e.tenant_id,!ee){E.error("无法获取租户信息");return}const ye=new FormData;ye.append("file",H),ye.append("tenant_id",String(ee)),ze(!0);try{const Ne=await Lt.importExcel(ye);(Ne.code===0||Ne.code===200)&&Ne.data?(as(Ne.data),Sn(!0),st()):E.error(Ne.message||"导入失败")}catch(Ne){E.error(Ne.message||"导入失败")}finally{ze(!1)}},Ae=async H=>{S(!0),v(!0);try{const ee=await Lt.detail(H);(ee.code===0||ee.code===200)&&ee.data?R(ee.data):E.error(ee.message||"获取用户详情失败")}catch(ee){E.error(ee.message||"获取用户详情失败")}finally{v(!1)}},Le=[...r?[{title:"ID",dataIndex:"id",width:80}]:[],{title:"编号",dataIndex:"user_no",width:80},{title:"头像",dataIndex:"avatar",width:80,render:(H,ee)=>{const ye=ee.status==="deleted",Ne=ye&&ee.deactivated_avatar||H,We=ye?ee.deactivated_nickname||ee.nickname||ee.username:ee.nickname||ee.username;return Ne?a.jsx(Mr,{src:Ne,alt:We,width:40,height:40,style:{objectFit:"cover",cursor:"pointer",opacity:ye?.5:1},preview:{mask:"点击查看"}}):a.jsx(da,{size:40,shape:"square",icon:a.jsx(ca,{}),style:ye?{opacity:.5}:void 0,children:We?We.charAt(0):""})}},{title:"用户名",dataIndex:"username",width:160},{title:"昵称",dataIndex:"nickname",width:160,render:(H,ee)=>ee.status==="deleted"&&ee.deactivated_nickname?a.jsx("span",{style:{color:"#999"},children:ee.deactivated_nickname}):ee.nickname||"--"},...r?[{title:"租户",dataIndex:"tenant_id",width:160,render:s}]:[],{title:"手机号",dataIndex:"phone",width:140},{title:"注册方式",dataIndex:"register_source",width:100,render:H=>({admin:"后台创建",ios:"iOS 注册",android:"安卓注册"})[H]||H||"--"},{title:"状态",dataIndex:"status",width:100,render:H=>{const ee={active:{color:"green",text:"正常"},disabled:{color:"red",text:"已封禁"},deleted:{color:"default",text:"已注销"}},ye=ee[H]||ee.disabled;return a.jsx(Te,{color:ye.color,children:ye.text})}},{title:"用户分组",dataIndex:"policy_group_name",width:140,render:H=>H||"--"},{title:"最近登录",dataIndex:"last_login_at",width:180,render:H=>H?Ke(H):"--"},{title:"创建时间",dataIndex:"created_at",width:180,render:H=>Ke(H)},{title:"操作",key:"actions",width:400,render:(H,ee)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>Ae(ee.id),children:"详情"}),ee.status!=="deleted"&&a.jsxs(a.Fragment,{children:[a.jsx(Y,{size:"small",onClick:()=>ln(ee),children:"重置密码"}),a.jsx(Y,{size:"small",onClick:()=>ne(ee),children:"IP白名单"}),a.jsx(Y,{size:"small",onClick:()=>Ht(ee),children:"调整分组"}),(n||ee.tenant_enable_security_perm)&&a.jsx(Y,{size:"small",type:ee.can_view_security_info??!1?"primary":"default",onClick:()=>O(ee),children:ee.can_view_security_info??!1?"关闭安全权限":"开启安全权限"}),a.jsx(Y,{size:"small",danger:ee.status==="active",onClick:()=>Xr(ee),children:ee.status==="active"?"封禁":"解封"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>N(ee),children:"强制下线"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>re(ee),children:"强制注销"})]})]})}];return a.jsxs("div",{className:"admin-users",children:[a.jsx(be,{className:"admin-users-filter",children:a.jsxs(b,{form:Tn,layout:"inline",onFinish:Qt,children:[r?a.jsx(b.Item,{label:"ID",name:"id",children:a.jsx(ve,{placeholder:"用户 ID",allowClear:!0,style:{width:120}})}):a.jsx(b.Item,{label:"编号",name:"user_no",children:a.jsx(ve,{placeholder:"用户编号",allowClear:!0,style:{width:120}})}),r&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200},onChange:H=>{Tn.setFieldValue("policy_group_id",void 0),dr(H)}})}),a.jsx(b.Item,{label:"用户分组",name:"policy_group_id",children:a.jsx($e,{placeholder:r&&!Ce?"请先选择租户":"全部",allowClear:!0,disabled:r&&!Ce,options:yt.map(H=>({label:H.name,value:H.id})),style:{width:150}})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:EE,style:{width:120}})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"用户名/昵称/手机号",allowClear:!0})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>Tn.resetFields(),children:"重置"}),a.jsx(Y,{onClick:er,children:"创建用户"}),a.jsx(Y,{onClick:()=>{bn.resetFields(),Q(!0)},children:"批量创建"}),r&&a.jsxs(a.Fragment,{children:[a.jsx(Y,{danger:!0,icon:a.jsx(ju,{}),onClick:()=>{En.resetFields(),z(!0)},children:"批量封禁"}),a.jsx(Y,{danger:!0,icon:a.jsx(Yo,{}),onClick:()=>{St.resetFields(),Z(!0)},children:"按 IP 封禁"})]}),a.jsx(Y,{icon:a.jsx(Iu,{}),loading:He,onClick:()=>{const H=document.createElement("input");H.type="file",H.accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",H.onchange=ee=>{var Ne;const ye=(Ne=ee.target.files)==null?void 0:Ne[0];ye&&Be(ye)},H.click()},children:"导入Excel"}),a.jsx(Y,{icon:a.jsx($r,{}),onClick:bE,children:"下载模板"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:Le,dataSource:l,loading:i,scroll:{x:900},pagination:{current:d,pageSize:h,total:_,showSizeChanger:!0,onChange:(H,ee)=>{u(H),m(ee),st(H,ee)}}})}),a.jsx($i,{title:"用户详情",width:420,open:I,onClose:()=>S(!1),children:a.jsx(Mn,{spinning:w,children:y&&a.jsxs(a.Fragment,{children:[a.jsx("div",{style:{textAlign:"center",marginBottom:16},children:(()=>{const H=y.status==="deleted",ee=H&&y.deactivated_avatar||y.avatar,ye=H?y.deactivated_nickname||y.nickname||y.username:y.nickname||y.username;return ee?a.jsx(Mr,{src:ee,alt:ye,width:80,height:80,style:{objectFit:"cover",cursor:"pointer",opacity:H?.5:1},preview:{mask:"点击查看大图"}}):a.jsx(da,{size:80,shape:"square",icon:a.jsx(ca,{}),style:H?{opacity:.5}:void 0,children:ye?ye.charAt(0):""})})()}),a.jsxs(je,{column:1,bordered:!0,size:"small",children:[r&&a.jsx(je.Item,{label:"ID",children:y.id}),a.jsx(je.Item,{label:"用户名",children:a.jsxs(Ie,{children:[a.jsx("span",{children:y.username}),y.status!=="deleted"&&y.username_editable&&a.jsx(Y,{size:"small",onClick:()=>M(y),children:"修改"})]})}),a.jsx(je.Item,{label:"昵称",children:y.nickname||"--"}),y.status==="deleted"&&y.deactivated_nickname&&a.jsx(je.Item,{label:"注销前昵称",children:a.jsx("span",{style:{color:"#fa8c16"},children:y.deactivated_nickname})}),r&&a.jsx(je.Item,{label:"租户",children:s(y.tenant_id)}),a.jsx(je.Item,{label:"手机号",children:y.phone||"--"}),a.jsx(je.Item,{label:"注册方式",children:y.register_source==="admin"?"后台创建":y.register_source==="ios"?"iOS 注册":y.register_source==="android"?"安卓注册":y.register_source||"--"}),y.register_source!=="admin"&&y.register_ip&&a.jsx(je.Item,{label:"注册IP",children:y.register_ip}),a.jsx(je.Item,{label:"状态",children:a.jsx(Te,{color:y.status==="active"?"green":y.status==="deleted"?"default":"red",children:y.status==="active"?"正常":y.status==="deleted"?"已注销":"已封禁"})}),a.jsx(je.Item,{label:"用户分组",children:y.policy_group_name||"--"}),y.deactivated_at&&a.jsx(je.Item,{label:"注销时间",children:Ke(y.deactivated_at)}),y.last_login_at&&a.jsx(je.Item,{label:"最近登录时间",children:Ke(y.last_login_at)}),y.last_login_ip&&a.jsx(je.Item,{label:"最近登录IP",children:y.last_login_ip}),a.jsx(je.Item,{label:"创建时间",children:Ke(y.created_at)}),a.jsx(je.Item,{label:"更新时间",children:Ke(y.updated_at)})]})]})})}),a.jsxs(Me,{title:"修改用户名",open:!!X,onCancel:()=>_e(null),onOk:U,okText:"确认修改",cancelText:"取消",confirmLoading:J,destroyOnClose:!0,children:[a.jsx("div",{style:{marginBottom:8,color:"#666"},children:"只能修改前缀后的数字,修改后该用户所有设备会被强制下线。"}),a.jsx(ve,{addonBefore:X==null?void 0:X.username_prefix,value:B,maxLength:8,placeholder:"请输入4至8位数字",onChange:H=>te(H.target.value.replace(/\D/g,"").slice(0,8))}),a.jsxs("div",{style:{marginTop:8,color:"#888",fontSize:12},children:["新用户名:",(X==null?void 0:X.username_prefix)||"",B]})]}),a.jsx(Me,{title:`调整分组${Xe?`:${Xe.nickname||Xe.username}`:""}`,open:!!Xe,onCancel:()=>Je(null),onOk:ur,okText:"保存",cancelText:"取消",confirmLoading:et,children:a.jsx($e,{value:xe,onChange:ke,options:yt.map(H=>({label:`${H.name}${H.enabled?"":"(已停用)"}`,value:H.id,disabled:!H.enabled})),style:{width:"100%"},placeholder:"请选择用户分组"})}),a.jsx(Me,{title:"创建用户",open:j,onCancel:()=>T(!1),onOk:vr,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:kr,layout:"vertical",children:[r&&a.jsx(b.Item,{label:"租户",name:"tenant_id",rules:[{required:!0,message:"请选择租户"}],children:a.jsx(ot,{style:{width:"100%"},onChange:H=>{kt(H).then(ee=>{kr.setFieldsValue({password:Za(ee.minLength)})})}})}),a.jsx(b.Item,{label:"手机号",name:"phone",children:a.jsx(ve,{placeholder:"可选手机号"})}),a.jsx(b.Item,{label:"昵称",name:"nickname",children:a.jsx(ve,{placeholder:"用户昵称"})}),a.jsx(b.Item,{label:"密码",name:"password",tooltip:od(he),rules:ld(he),children:a.jsx(ve,{placeholder:"自动生成,可手动修改",addonAfter:a.jsx(Y,{type:"text",icon:a.jsx(un,{}),onClick:()=>A(kr),size:"small",style:{padding:"0 4px"},children:"复制"})})})]})}),a.jsx(Me,{title:`重置密码${P?`:${P.nickname||P.username}`:""}`,open:C,onCancel:()=>F(!1),onOk:L,okText:"确认",cancelText:"取消",destroyOnClose:!0,children:a.jsx(b,{form:qr,layout:"vertical",children:a.jsx(b.Item,{label:"新密码",name:"password",tooltip:od(he),rules:ld(he,"请输入新密码"),children:a.jsx(ve,{placeholder:"自动生成,可手动修改",addonAfter:a.jsx(Y,{type:"text",icon:a.jsx(un,{}),onClick:()=>A(qr),size:"small",style:{padding:"0 4px"},children:"复制"})})})})}),a.jsx(Me,{title:"批量创建用户",open:se,onCancel:()=>Q(!1),onOk:Pe,okText:"创建",cancelText:"取消",confirmLoading:de,destroyOnClose:!0,children:a.jsxs(b,{form:bn,layout:"vertical",children:[r&&a.jsx(b.Item,{label:"租户",name:"tenant_id",rules:[{required:!0,message:"请选择租户"}],children:a.jsx(ot,{style:{width:"100%"}})}),a.jsx(b.Item,{label:"创建数量",name:"count",rules:[{required:!0,message:"请输入创建数量"}],initialValue:10,children:a.jsx(at,{min:1,max:100,style:{width:"100%"}})}),a.jsxs("div",{style:{color:"#999",fontSize:12},children:["昵称从前缀/后缀词库随机组合,密码自动生成 12 位随机字符。",a.jsx("br",{}),"创建完成后自动下载包含用户名和密码的 TXT 文件。"]})]})}),a.jsx(Me,{title:"批量封禁用户",open:W,onCancel:()=>z(!1),onOk:It,okText:"确认封禁",okButtonProps:{danger:!0},cancelText:"取消",confirmLoading:D,destroyOnClose:!0,children:a.jsx(b,{form:En,layout:"vertical",children:a.jsx(b.Item,{label:"用户名",name:"usernames",rules:[{required:!0,message:"请输入至少一个用户名"}],extra:"每行一个用户名,自动忽略空行和重复项,单次最多 500 个。封禁成功后会立即撤销全部登录会话并踢下线。",children:a.jsx(ve.TextArea,{rows:12,placeholder:`user0001 +user0002 +user0003`})})})}),a.jsx(Me,{title:"按 IP 封禁用户",open:K,onCancel:()=>Z(!1),onOk:Fr,okText:"确认封禁并下线",okButtonProps:{danger:!0},cancelText:"取消",confirmLoading:me,destroyOnClose:!0,children:a.jsx(b,{form:St,layout:"vertical",children:a.jsx(b.Item,{label:"IP 地址",name:"ip",rules:[{required:!0,message:"请输入 IPv4 或 IPv6 地址"}],extra:"匹配全部租户账号的注册 IP、最近登录 IP 和历史登录 IP。命中的全部非注销账号都会被封禁,并立即撤销登录会话、强制下线。",children:a.jsx(ve,{placeholder:"例如 203.0.113.10 或 2001:db8::1",allowClear:!0})})})}),a.jsx(Me,{title:"Excel 导入结果",open:Wt,onCancel:()=>Sn(!1),footer:null,width:600,destroyOnClose:!0,children:cr&&a.jsxs("div",{children:[a.jsxs("div",{style:{marginBottom:16,fontSize:15},children:[a.jsxs("span",{style:{color:"#52c41a",fontWeight:600},children:["成功 ",cr.success_count," 人"]}),a.jsx("span",{style:{margin:"0 12px"},children:"|"}),a.jsxs("span",{style:{color:cr.failed_count>0?"#ff4d4f":"#999",fontWeight:600},children:["失败 ",cr.failed_count," 人"]})]}),cr.failed_items&&cr.failed_items.length>0&&a.jsxs(a.Fragment,{children:[a.jsx("div",{style:{marginBottom:8,fontWeight:500},children:"失败详情:"}),a.jsx(Ye,{size:"small",rowKey:"row",dataSource:cr.failed_items,pagination:!1,scroll:{y:300},columns:[{title:"行号",dataIndex:"row",width:60},{title:"昵称",dataIndex:"nickname",width:100,render:H=>H||"--"},{title:"失败原因",dataIndex:"reason"}]})]})]})}),a.jsxs(Me,{title:`IP 白名单${le?`:${le.nickname||le.username}`:""}`,open:gt,onCancel:()=>qe(!1),onOk:ge,okText:"保存",cancelText:"取消",confirmLoading:nt,destroyOnClose:!0,children:[a.jsx("div",{style:{marginBottom:8,color:"#666",fontSize:13},children:"填写允许登录的 IPv4、IPv6 或 CIDR,多个规则用逗号或换行分隔。留空表示不限制登录 IP。"}),a.jsx(ve.TextArea,{value:Re,onChange:H=>Ue(H.target.value),placeholder:`例:203.0.113.10 +2001:db8::/32`,autoSize:{minRows:3,maxRows:6},allowClear:!0}),Re.trim()&&a.jsxs("div",{style:{marginTop:8,color:"#888",fontSize:12},children:["当前限制 IP:",Re.split(",").map(H=>H.trim()).filter(Boolean).map(H=>a.jsx(Te,{style:{marginLeft:4},children:H},H))]})]})]})},{TextArea:IE}=ve,CE=e=>e<1024?e+" B":e<1024*1024?(e/1024).toFixed(1)+" KB":e<1024*1024*1024?(e/(1024*1024)).toFixed(1)+" MB":(e/(1024*1024*1024)).toFixed(1)+" GB",qd={xlsx:{icon:vs,color:"#52c41a"},xls:{icon:vs,color:"#52c41a"},csv:{icon:vs,color:"#52c41a"},doc:{icon:_i,color:"#1890ff"},docx:{icon:_i,color:"#1890ff"},ppt:{icon:gi,color:"#fa8c16"},pptx:{icon:gi,color:"#fa8c16"},mp4:{icon:An,color:"#1890ff"},avi:{icon:An,color:"#1890ff"},mov:{icon:An,color:"#1890ff"},mkv:{icon:An,color:"#1890ff"},wmv:{icon:An,color:"#1890ff"},flv:{icon:An,color:"#1890ff"},webm:{icon:An,color:"#1890ff"},mp3:{icon:zn,color:"#722ed1"},wav:{icon:zn,color:"#722ed1"},flac:{icon:zn,color:"#722ed1"},aac:{icon:zn,color:"#722ed1"},ogg:{icon:zn,color:"#722ed1"},wma:{icon:zn,color:"#722ed1"},jpg:{icon:Cn,color:"#52c41a"},jpeg:{icon:Cn,color:"#52c41a"},png:{icon:Cn,color:"#52c41a"},gif:{icon:Cn,color:"#52c41a"},bmp:{icon:Cn,color:"#52c41a"},webp:{icon:Cn,color:"#52c41a"},svg:{icon:Cn,color:"#52c41a"},txt:{icon:Xs,color:"#8c8c8c"},log:{icon:Xs,color:"#8c8c8c"},zip:{icon:rn,color:"#faad14"},rar:{icon:rn,color:"#faad14"},"7z":{icon:rn,color:"#faad14"},tar:{icon:rn,color:"#faad14"},gz:{icon:rn,color:"#faad14"},md:{icon:Cu,color:"#595959"},js:{icon:rr,color:"#fadb14"},ts:{icon:rr,color:"#1890ff"},jsx:{icon:rr,color:"#fadb14"},tsx:{icon:rr,color:"#1890ff"},py:{icon:rr,color:"#389e0d"},go:{icon:rr,color:"#13c2c2"},java:{icon:rr,color:"#f5222d"},html:{icon:rr,color:"#fa541c"},css:{icon:rr,color:"#1890ff"},json:{icon:rr,color:"#8c8c8c"},pdf:{icon:pl,color:"#f5222d"}},AE=(e,t)=>{var r;if(t){const n=(r=t.split(".").pop())==null?void 0:r.toLowerCase();if(n&&qd[n]){const{icon:s,color:i}=qd[n];return a.jsx(s,{style:{fontSize:18,color:i}})}}return e!=null&&e.startsWith("image/")?a.jsx(Cn,{style:{fontSize:18,color:"#52c41a"}}):e!=null&&e.startsWith("video/")?a.jsx(An,{style:{fontSize:18,color:"#1890ff"}}):e!=null&&e.startsWith("audio/")?a.jsx(zn,{style:{fontSize:18,color:"#722ed1"}}):e==="application/pdf"?a.jsx(pl,{style:{fontSize:18,color:"#f5222d"}}):a.jsx(Au,{style:{fontSize:18}})},oi={normal:{label:"正常",color:"green"},banned:{label:"封禁",color:"red"},dissolved:{label:"已解散",color:"default"}},kE=()=>{var Ue,nt,Tt,yt;const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),{renderTenantId:n}=Yr(),[s,i]=g.useState(!1),[o,l]=g.useState([]),[c,d]=g.useState(1),[u,h]=g.useState(20),[m,_]=g.useState(0),[x,f]=g.useState({}),[p,I]=g.useState(!1),[S,w]=g.useState(!1),[v,y]=g.useState(null),[R,j]=g.useState(!1),[T,C]=g.useState(null),[F]=b.useForm(),[P]=b.useForm(),[V,X]=g.useState(null),[_e,B]=g.useState(!1),[te,J]=g.useState([]),[G,se]=g.useState(1),[Q]=g.useState(20),[de,k]=g.useState(0),[W,z]=g.useState(""),[D,q]=g.useState("all"),[K,Z]=g.useState(null),me=g.useCallback(async(De,Ce=1,Qe="",Xe="all")=>{B(!0);try{const Je=await ad.list(De,{keyword:Qe||void 0,type:Xe==="all"?void 0:Xe,page:Ce,page_size:Q});(Je.code===0||Je.code===200)&&Je.data?(J(Je.data.items),k(Je.data.total),se(Je.data.page)):E.error(Je.message||"获取群文件失败")}catch(Je){E.error(Je.message||"获取群文件失败")}finally{B(!1)}},[Q]),ie=De=>{X(De),z(""),q("all"),J([]),k(0),se(1),me(De.id)},he=(De,Ce)=>{Me.confirm({title:"确认删除该文件?",content:`文件名:${Ce.file_name}`,okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const Qe=await ad.delete(De,Ce.id);Qe.code===0||Qe.code===200?(E.success("文件已删除"),J(Je=>Je.filter(xe=>xe.id!==Ce.id)),k(Je=>Math.max(0,Je-1))):E.error(Qe.message||"删除失败")}catch(Qe){E.error(Qe.message||"删除失败")}}})},we=async(De=c,Ce=u,Qe=x)=>{i(!0);try{const Xe=await Wn.list({...Qe,page:De,page_size:Ce});(Xe.code===0||Xe.code===200)&&Xe.data?(l(Xe.data.items),_(Xe.data.total),d(Xe.data.page),h(Xe.data.size)):E.error(Xe.message||"获取群组列表失败")}catch(Xe){E.error(Xe.message||"获取群组列表失败")}finally{i(!1)}};g.useEffect(()=>{we(1,u,x)},[]);const He=De=>{const Ce={keyword:De.keyword,status:De.status||void 0};r?(Ce.tenant_id=De.tenant_id,Ce.id=De.id?Number(De.id):void 0):Ce.group_code=De.group_code||void 0,f(Ce),we(1,u,Ce)},ze=De=>{Me.confirm({title:"确认解散该群组?",content:"解散群组会清理成员与会话数据,群记录和消息记录将保留。",okText:"解散",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const Ce=await Wn.dismiss(De.id);Ce.code===0||Ce.code===200?(E.success("群组已解散"),we()):E.error(Ce.message||"解散失败")}catch(Ce){E.error(Ce.message||"解散失败")}}})},gt=De=>{C(De),j(!0),P.resetFields()},qe=async()=>{if(T)try{const De=await P.validateFields(),Ce=await Wn.ban(T.id,De.reason);Ce.code===0||Ce.code===200?(E.success("群组已封禁"),j(!1),we()):E.error(Ce.message||"封禁失败")}catch(De){De.message&&E.error(De.message||"封禁失败")}},le=De=>{Me.confirm({title:"确认解封该群组?",content:"解封后群成员可正常使用群聊功能。",okText:"解封",cancelText:"取消",onOk:async()=>{try{const Ce=await Wn.unban(De.id);Ce.code===0||Ce.code===200?(E.success("群组已解封"),we()):E.error(Ce.message||"解封失败")}catch(Ce){E.error(Ce.message||"解封失败")}}})},fe=async De=>{I(!0),w(!0);try{const Ce=await Wn.detail(De);(Ce.code===0||Ce.code===200)&&Ce.data?y(Ce.data):E.error(Ce.message||"获取群组详情失败")}catch(Ce){E.error(Ce.message||"获取群组详情失败")}finally{w(!1)}},Re=[r?{title:"ID",dataIndex:"id",width:80}:{title:"群组编号",dataIndex:"group_no",width:100},{title:"群号",dataIndex:"group_code",width:120,render:De=>De||"--"},{title:"群组名称",dataIndex:"name",width:220,render:(De,Ce)=>a.jsxs(Ie,{children:[a.jsx(da,{src:Ce.avatar||void 0,icon:a.jsx($n,{}),size:"small",shape:"square",style:{cursor:Ce.avatar?"pointer":void 0},onClick:Qe=>{Ce.avatar&&(Qe==null||Qe.stopPropagation(),Me.info({title:Ce.name,icon:null,content:a.jsx("div",{style:{textAlign:"center",padding:"16px 0"},children:a.jsx("img",{src:Ce.avatar,alt:Ce.name,style:{maxWidth:"100%",maxHeight:400,borderRadius:4}})}),okText:"关闭",width:480}))}}),Ce.name]})},...r?[{title:"租户",dataIndex:"tenant_id",width:160,render:n}]:[],{title:"成员数",dataIndex:"member_count",width:100},{title:"群主昵称",dataIndex:"owner",width:140,render:(De,Ce)=>{var Qe,Xe;return((Qe=Ce.owner)==null?void 0:Qe.nickname)||((Xe=Ce.owner)==null?void 0:Xe.username)||"--"}},r?{title:"群主用户 ID",dataIndex:"owner_id",width:100}:{title:"群主用户名",dataIndex:["owner","username"],width:100,render:De=>De||"--"},{title:"状态",dataIndex:"status",width:90,render:De=>{const Ce=oi[De]||oi.normal;return a.jsx(Te,{color:Ce.color,children:Ce.label})}},{title:"创建时间",dataIndex:"created_at",width:180,render:De=>Ke(De)},{title:"操作",key:"actions",width:280,render:(De,Ce)=>{const Qe=Ce.status||"normal";return a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>fe(Ce.id),children:"详情"}),a.jsx(Y,{size:"small",icon:a.jsx(Eu,{}),onClick:()=>ie(Ce),children:"群文件"}),Qe==="normal"&&a.jsxs(a.Fragment,{children:[a.jsx(Y,{size:"small",danger:!0,onClick:()=>gt(Ce),children:"封禁"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>ze(Ce),children:"解散"})]}),Qe==="banned"&&a.jsx(Y,{size:"small",onClick:()=>le(Ce),children:"解封"})]})}}];return a.jsxs("div",{className:"admin-groups",children:[a.jsx(be,{className:"admin-groups-filter",children:a.jsxs(b,{form:F,layout:"inline",onFinish:He,children:[r&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),r?a.jsx(b.Item,{label:"ID",name:"id",children:a.jsx(ve,{placeholder:"群组 ID",allowClear:!0})}):a.jsx(b.Item,{label:"群号",name:"group_code",children:a.jsx(ve,{placeholder:"群号",allowClear:!0})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"群名称",allowClear:!0})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsxs($e,{placeholder:"全部",allowClear:!0,style:{width:100},children:[a.jsx($e.Option,{value:"normal",children:"正常"}),a.jsx($e.Option,{value:"banned",children:"封禁"}),a.jsx($e.Option,{value:"dissolved",children:"已解散"})]})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>F.resetFields(),children:"重置"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:Re,dataSource:o,loading:s,scroll:{x:1e3},pagination:{current:c,pageSize:u,total:m,showSizeChanger:!0,onChange:(De,Ce)=>{d(De),h(Ce),we(De,Ce)}}})}),a.jsx($i,{title:"群组详情",width:420,open:p,onClose:()=>I(!1),children:a.jsx(Mn,{spinning:S,children:v&&a.jsxs(je,{column:1,bordered:!0,size:"small",children:[r?a.jsx(je.Item,{label:"ID",children:v.id}):a.jsx(je.Item,{label:"群组编号",children:v.group_no||"--"}),a.jsx(je.Item,{label:"群号",children:v.group_code||"--"}),a.jsx(je.Item,{label:"群头像",children:a.jsx(da,{src:v.avatar||void 0,icon:a.jsx($n,{}),size:48,shape:"square",style:{cursor:v.avatar?"pointer":void 0},onClick:()=>{v.avatar&&Me.info({title:v.name,icon:null,content:a.jsx("div",{style:{textAlign:"center",padding:"16px 0"},children:a.jsx("img",{src:v.avatar,alt:v.name,style:{maxWidth:"100%",maxHeight:400,borderRadius:4}})}),okText:"关闭",width:480})}})}),a.jsx(je.Item,{label:"群名称",children:v.name}),r&&a.jsx(je.Item,{label:"租户 ID",children:v.tenant_id}),a.jsx(je.Item,{label:"群主昵称",children:((Ue=v.owner)==null?void 0:Ue.nickname)||((nt=v.owner)==null?void 0:nt.username)||"--"}),a.jsx(je.Item,{label:r?"群主用户 ID":"群主用户名",children:r?((Tt=v.owner)==null?void 0:Tt.id)||v.owner_id:((yt=v.owner)==null?void 0:yt.username)||"--"}),a.jsx(je.Item,{label:"状态",children:(()=>{const De=oi[v.status||"normal"]||oi.normal;return a.jsx(Te,{color:De.color,children:De.label})})()}),v.status==="banned"&&v.ban_reason&&a.jsx(je.Item,{label:"封禁原因",children:v.ban_reason}),a.jsx(je.Item,{label:"成员数",children:v.member_count}),a.jsx(je.Item,{label:"最大人数",children:v.max_members}),a.jsx(je.Item,{label:"群简介",children:v.description||"--"}),a.jsx(je.Item,{label:"创建时间",children:Ke(v.created_at)}),v.status==="dissolved"&&v.dissolved_at&&a.jsx(je.Item,{label:"解散时间",children:Ke(v.dissolved_at)})]})})}),a.jsxs(Me,{title:"封禁群组",open:R,onOk:qe,onCancel:()=>j(!1),okText:"确认封禁",okButtonProps:{danger:!0},cancelText:"取消",children:[a.jsxs("p",{children:["确认封禁群组 ",a.jsx("strong",{children:T==null?void 0:T.name}),"?"]}),a.jsx("p",{style:{color:"#999",fontSize:12},children:"封禁后将向群内发送系统消息,所有成员将无法发送消息和进行群操作。"}),a.jsx(b,{form:P,layout:"vertical",children:a.jsx(b.Item,{label:"封禁原因",name:"reason",rules:[{required:!0,message:"请输入封禁原因"}],children:a.jsx(IE,{rows:3,placeholder:"请输入封禁原因",maxLength:500,showCount:!0})})})]}),a.jsx(Me,{open:!!V,onCancel:()=>X(null),footer:null,centered:!0,destroyOnClose:!0,width:"90%",style:{maxWidth:1100},title:`群文件 - ${(V==null?void 0:V.name)||""}`,children:V&&a.jsxs("div",{children:[a.jsxs("div",{style:{display:"flex",gap:12,marginBottom:16,alignItems:"center",flexWrap:"wrap"},children:[a.jsx(qo,{value:D,options:[{label:"全部",value:"all"},{label:"图片",value:"image"},{label:"视频",value:"video"},{label:"音频",value:"audio"},{label:"文档",value:"document"},{label:"其他",value:"other"}],onChange:De=>{const Ce=De;q(Ce),me(V.id,1,W,Ce)}}),a.jsx(ve,{placeholder:"搜索文件名",prefix:a.jsx(Ar,{}),allowClear:!0,style:{width:200},value:W,onChange:De=>z(De.target.value),onPressEnter:()=>me(V.id,1,W,D)})]}),a.jsx(Ye,{rowKey:"id",dataSource:te,loading:_e,size:"small",scroll:{x:700},pagination:{current:G,pageSize:Q,total:de,showSizeChanger:!1,onChange:De=>me(V.id,De,W,D)},columns:[{title:"文件",dataIndex:"file_name",ellipsis:!0,render:(De,Ce)=>a.jsxs(Ie,{children:[AE(Ce.content_type,Ce.file_name),a.jsx("span",{children:Ce.file_name})]})},{title:"大小",dataIndex:"file_size",width:100,render:De=>CE(De)},{title:"上传者",dataIndex:"uploader",width:140,render:(De,Ce)=>{var Qe,Xe;return((Qe=Ce.uploader)==null?void 0:Qe.nickname)||((Xe=Ce.uploader)==null?void 0:Xe.username)||"--"}},{title:"上传时间",dataIndex:"created_at",width:170,render:De=>Ke(De)},{title:"操作",key:"actions",width:140,render:(De,Ce)=>{var Qe;return a.jsxs(Ie,{children:[((Qe=Ce.content_type)==null?void 0:Qe.startsWith("image/"))&&a.jsx(Xt,{title:"预览",children:a.jsx(Y,{size:"small",type:"text",icon:a.jsx(xl,{}),onClick:()=>Z(Ce.file_url)})}),a.jsx(Xt,{title:"下载",children:a.jsx(Y,{size:"small",type:"text",icon:a.jsx($r,{}),onClick:()=>window.open(Ce.file_url,"_blank")})}),a.jsx(Xt,{title:"删除",children:a.jsx(Y,{size:"small",type:"text",danger:!0,icon:a.jsx(Gs,{}),onClick:()=>he(V.id,Ce)})})]})}}]}),K&&a.jsx(Mr,{src:K,style:{display:"none"},preview:{visible:!0,onVisibleChange:De=>{De||Z(null)}}})]})})]})},{Text:Rr}=Cr,Xd=e=>!e||e<=0?"":e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`,Wo=e=>{if(!e||e<=0)return"";const t=Math.floor(e/60),r=e%60;return`${t}:${r.toString().padStart(2,"0")}`},In=(e,t=120)=>!e||!e.includes("aliyuncs.com")?e:`${e.split("?")[0]}?x-oss-process=image/resize,w_${t},m_lfit/quality,q_80`,FE=new Set(["pdf","doc","docx","xls","xlsx","csv","ppt","pptx","txt","md","rtf"]),Jd=new Set(["jpg","jpeg","png","gif","bmp","webp","svg","ico","tiff","tif"]),Zd=new Set(["mp4","avi","mov","mkv","wmv","flv","webm","m4v"]),OE={pdf:{icon:pl,color:"#f5222d"},doc:{icon:_i,color:"#1890ff"},docx:{icon:_i,color:"#1890ff"},xls:{icon:vs,color:"#52c41a"},xlsx:{icon:vs,color:"#52c41a"},csv:{icon:vs,color:"#52c41a"},ppt:{icon:gi,color:"#fa8c16"},pptx:{icon:gi,color:"#fa8c16"},txt:{icon:Xs,color:"#8c8c8c"},log:{icon:Xs,color:"#8c8c8c"},rtf:{icon:Xs,color:"#8c8c8c"},md:{icon:Cu,color:"#595959"},zip:{icon:rn,color:"#faad14"},rar:{icon:rn,color:"#faad14"},"7z":{icon:rn,color:"#faad14"},tar:{icon:rn,color:"#faad14"},gz:{icon:rn,color:"#faad14"},js:{icon:rr,color:"#fadb14"},ts:{icon:rr,color:"#1890ff"},py:{icon:rr,color:"#389e0d"},go:{icon:rr,color:"#13c2c2"},java:{icon:rr,color:"#f5222d"}},RE=e=>{var i;const t=((i=e==null?void 0:e.split(".").pop())==null?void 0:i.toLowerCase())||"",r=OE[t],n=(r==null?void 0:r.icon)||Au,s=(r==null?void 0:r.color)||"#8c8c8c";return a.jsx(n,{style:{fontSize:20,color:s}})},ms=async(e,t)=>{try{const n=await(await fetch(e)).blob(),s=document.createElement("a");s.href=URL.createObjectURL(n),s.download=t,s.click(),URL.revokeObjectURL(s.href)}catch{window.open(e,"_blank")}},rc=({conversationType:e,messageTypes:t})=>{const{admin:r,permissions:n}=pt(),s=!!r&&!r.tenant_id&&!!(n!=null&&n.tenant_manage),{renderTenantId:i}=Yr(),o=e==="single",l=!!t&&t.length>0,[c]=b.useForm(),[d,u]=g.useState(!1),[h,m]=g.useState([]),[_,x]=g.useState(1),[f,p]=g.useState(20),[I,S]=g.useState(0),[w,v]=g.useState({}),[y,R]=g.useState("all"),[j,T]=g.useState("all"),[C,F]=g.useState(null),P={text:{label:"文本",color:"blue"},image:{label:"图片",color:"green"},video:{label:"视频",color:"purple"},audio:{label:"语音",color:"cyan"},file:{label:"文件",color:"orange"},contact_card:{label:"名片",color:"geekblue"},system:{label:"系统",color:"default"}},V=Q=>{if(!Q)return null;if(typeof Q=="object")return Q;try{return JSON.parse(Q)}catch{return null}},X=Q=>{const de=Q.is_revoked&&Q.original_content?Q.original_content:Q.content,k=V(de);if(!k)return typeof de=="string"?de:"--";switch(Q.type){case"text":return k.text||"--";case"image":return"[图片]";case"video":return k.file_name?`[视频] ${k.file_name}`:"[视频]";case"audio":return"[语音]";case"file":return k.file_name?`[文件] ${k.file_name}`:"[文件]";case"contact_card":return k.contact_name||k.contact_username||`ID:${k.contact_id||"?"}`;case"system":return k.system_msg?k.system_msg:(k.system_msg_data||k).type||"[系统消息]";default:return JSON.stringify(k)}},_e=Q=>{var Z;const de=Q.is_revoked&&Q.original_content?Q.original_content:Q.content,k=V(de);if(k){const me=k.url;if(l&&me){const ie=k.file_name||"",he=((Z=ie.split(".").pop())==null?void 0:Z.toLowerCase())||"";return Jd.has(he)||Q.type==="image"?a.jsx("div",{className:"admin-media-cell",children:a.jsxs(Ie,{size:8,align:"start",children:[a.jsx(Mr,{src:In(k.thumbnail||me),width:60,style:{maxHeight:60,objectFit:"cover",borderRadius:4},preview:{src:In(me,800)}}),a.jsx(Y,{type:"link",size:"small",icon:a.jsx($r,{}),onClick:()=>ms(me,ie||"图片"),children:"下载"})]})}):Zd.has(he)||Q.type==="video"?a.jsx("div",{className:"admin-media-cell",children:a.jsxs(Ie,{size:8,align:"start",children:[a.jsxs("div",{className:"admin-video-thumb",onClick:()=>F({type:"video",url:me,title:ie||"视频播放",poster:k.thumbnail?In(k.thumbnail,300):void 0}),children:[k.thumbnail?a.jsx("img",{src:In(k.thumbnail)}):a.jsx("div",{className:"admin-video-thumb-empty"}),a.jsx(dc,{className:"admin-video-play"})]}),a.jsx(Y,{type:"link",size:"small",icon:a.jsx($r,{}),onClick:()=>ms(me,ie||"视频"),children:"下载"})]})}):Q.type==="audio"?a.jsx("div",{className:"admin-media-cell",children:a.jsxs(Ie,{size:8,align:"center",children:[a.jsx(go,{style:{fontSize:20,color:"#1677ff",cursor:"pointer"},onClick:()=>F({type:"audio",url:me,title:"语音播放"})}),!!k.duration&&a.jsx(Rr,{type:"secondary",style:{fontSize:11},children:Wo(k.duration)})]})}):a.jsx("div",{className:"admin-media-cell",children:a.jsxs(Ie,{size:8,align:"center",children:[RE(ie),a.jsx(Y,{type:"link",size:"small",icon:a.jsx($r,{}),onClick:()=>ms(me,ie||"文件"),children:"下载"})]})})}switch(Q.type){case"image":if(me)return a.jsx("div",{className:"admin-media-cell",children:a.jsxs(Ie,{size:8,align:"start",children:[a.jsx(Mr,{src:In(k.thumbnail||me),width:60,style:{maxHeight:60,objectFit:"cover",borderRadius:4},preview:{src:In(me,800)}}),a.jsx(Y,{type:"link",size:"small",icon:a.jsx($r,{}),onClick:()=>ms(me,"图片"),children:"下载"})]})});break;case"video":if(me)return a.jsx("div",{className:"admin-media-cell",children:a.jsxs(Ie,{size:8,align:"start",children:[a.jsxs("div",{className:"admin-video-thumb",onClick:()=>F({type:"video",url:me,title:k.file_name||"视频播放",poster:k.thumbnail?In(k.thumbnail,300):void 0}),children:[k.thumbnail?a.jsx("img",{src:In(k.thumbnail)}):a.jsx("div",{className:"admin-video-thumb-empty"}),a.jsx(dc,{className:"admin-video-play"})]}),a.jsxs("div",{children:[a.jsx("div",{children:a.jsx(Rr,{ellipsis:{tooltip:!0},style:{maxWidth:160,fontSize:12},children:k.file_name||"视频"})}),!!k.duration&&a.jsx(Rr,{type:"secondary",style:{fontSize:11},children:Wo(k.duration)}),a.jsx("div",{children:a.jsx(Y,{type:"link",size:"small",icon:a.jsx($r,{}),onClick:()=>ms(me,k.file_name||"视频"),children:"下载"})})]})]})});break;case"audio":if(me)return a.jsx("div",{className:"admin-media-cell",children:a.jsxs(Ie,{size:8,align:"center",children:[a.jsx(go,{style:{fontSize:20,color:"#1677ff",cursor:"pointer"},onClick:()=>F({type:"audio",url:me,title:"语音播放"})}),!!k.duration&&a.jsx(Rr,{type:"secondary",style:{fontSize:11},children:Wo(k.duration)})]})});break;case"file":if(me)return a.jsx("div",{className:"admin-media-cell",children:a.jsxs("div",{children:[a.jsx("div",{children:a.jsx(Rr,{ellipsis:{tooltip:!0},style:{maxWidth:200,fontSize:12},children:k.file_name||"文件"})}),a.jsxs(Ie,{size:8,children:[!!k.file_size&&a.jsx(Rr,{type:"secondary",style:{fontSize:11},children:Xd(k.file_size)}),a.jsx(Y,{type:"link",size:"small",icon:a.jsx($r,{}),onClick:()=>ms(me,k.file_name||"文件"),children:"下载"})]})]})});break;case"contact_card":{if(s)return`ID:${k.contact_id||"?"}`;const ie=k.contact_name,he=k.contact_username;return ie||he?a.jsxs("div",{children:[a.jsx("div",{children:ie||he}),he&&ie&&a.jsx(Rr,{type:"secondary",style:{fontSize:12},children:he})]}):`ID:${k.contact_id||"?"}`}}}const W=X(Q),z=W.replace(/[\r\n]+/g," "),D=z.length>20,q=D?z.slice(0,20)+"...":z,K=()=>{Me.info({title:"消息内容",width:520,content:a.jsx("div",{style:{maxHeight:400,overflow:"auto",whiteSpace:"pre-wrap",wordBreak:"break-all"},children:W}),okText:"关闭"})};return a.jsxs("div",{style:{whiteSpace:"nowrap"},children:[a.jsx("span",{style:{color:"rgba(0,0,0,0.65)"},children:q}),D&&a.jsx(Y,{type:"link",size:"small",style:{padding:"0 0 0 4px",height:"auto",fontSize:12},onClick:K,children:"详情"})]})},B=async(Q=_,de=f,k=w,W)=>{u(!0);const z=W??(l?y:j);let D=t,q;l&&z!=="all"?z==="document"||z==="other"?(D=["file"],q=z):D=[z]:!l&&z!=="all"&&(D=[z]);try{const K=await ed.search({...k,conversation_type:e,message_types:D==null?void 0:D.join(","),file_category:q,page:Q,page_size:de});(K.code===0||K.code===200)&&K.data?(m(K.data.items),S(K.data.total),x(K.data.page),p(K.data.size)):E.error(K.message||"获取消息列表失败")}catch(K){E.error(K.message||"获取消息列表失败")}finally{u(!1)}};g.useEffect(()=>{e||B(1,f,w)},[e]);const te=Q=>{const de={tenant_id:Q.tenant_id,conversation_id:Q.conversation_id,sender_id:Q.sender_id,receiver_id:Q.receiver_id,sender_username:Q.sender_username,receiver_username:Q.receiver_username,keyword:Q.keyword,start_time:Q.startTime?Q.startTime.format("YYYY-MM-DD HH:mm:ss"):void 0,end_time:Q.endTime?Q.endTime.format("YYYY-MM-DD HH:mm:ss"):void 0};v(de),B(1,f,de)},J=Q=>{Me.confirm({title:"确认删除该消息?",content:l?"删除后该文件消息将从聊天中实时消失,后台仍保留记录。":o?"删除后该消息将从双方聊天列表中实时消失,后台仍保留记录。":"删除后该消息将从群聊中实时消失,后台仍保留记录。",okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const de=await ed.delete(Q.id);de.code===0||de.code===200?(E.success("消息已删除"),B()):E.error(de.message||"删除失败")}catch(de){E.error(de.message||"删除失败")}}})},G=(Q,de)=>{if(!Q)return de||"--";const k=Q.nickname||Q.username||"--",W=Q.username||(s?`ID:${Q.id}`:"");return a.jsxs("div",{children:[a.jsx("div",{children:k}),W&&a.jsx(Rr,{type:"secondary",style:{fontSize:12},children:W})]})},se=[...s?[{title:"ID",dataIndex:"id",width:80},{title:"会话 ID",dataIndex:"conversation_id",width:100},{title:"租户",dataIndex:"tenant_id",width:160,render:i},{title:"SEQ",dataIndex:"seq",width:80}]:[],{title:"发送人",dataIndex:"sender",width:160,render:(Q,de)=>G(de.sender,de.sender_id)},...l?[{title:"接收方",key:"target",width:160,render:(Q,de)=>de.conversation_type==="group"?de.group_name?a.jsxs("div",{children:[a.jsx("div",{children:de.group_name}),!!de.group_code&&a.jsx(Rr,{type:"secondary",style:{fontSize:12},children:de.group_code})]}):"--":G(de.receiver)}]:[...o?[{title:"接收人",dataIndex:"receiver",width:160,render:(Q,de)=>G(de.receiver)}]:[],...e==="group"?[{title:"群名称",dataIndex:"group_name",width:160,render:(Q,de)=>de.group_name?a.jsxs("div",{children:[a.jsx("div",{children:de.group_name}),!!de.group_code&&a.jsx(Rr,{type:"secondary",style:{fontSize:12},children:de.group_code})]}):"--"}]:[]],{title:"类型",dataIndex:"type",width:80,render:(Q,de)=>{var W;if(l){const z=V(de.content),D=z==null?void 0:z.file_name,q=((W=D==null?void 0:D.split(".").pop())==null?void 0:W.toLowerCase())||"";return Jd.has(q)||Q==="image"?a.jsx(Te,{color:"green",children:"图片"}):Zd.has(q)||Q==="video"?a.jsx(Te,{color:"blue",children:"视频"}):Q==="audio"?a.jsx(Te,{color:"purple",children:"音频"}):FE.has(q)?a.jsx(Te,{color:"orange",children:"文档"}):a.jsx(Te,{color:"default",children:"其他"})}const k=P[Q];return k?a.jsx(Te,{color:k.color,children:k.label}):a.jsx(Te,{children:Q})}},{title:"内容",dataIndex:"content",width:l?140:300,render:(Q,de)=>_e(de)},...l?[{title:"文件名",key:"file_name",width:260,render:(Q,de)=>{const k=V(de.content),W=k==null?void 0:k.file_name;return W?a.jsx(Rr,{ellipsis:{tooltip:!0},style:{maxWidth:240},children:W}):"--"}},{title:"文件大小",key:"file_size",width:100,render:(Q,de)=>{const k=V(de.content),W=k==null?void 0:k.file_size;return W?Xd(W):"--"}},{title:"URL",key:"file_url",width:200,render:(Q,de)=>{const k=V(de.content),W=k==null?void 0:k.url;return W?a.jsx(Xt,{title:W,children:a.jsx(Rr,{copyable:!0,ellipsis:!0,style:{maxWidth:180,fontSize:12},children:W})}):"--"}}]:[],{title:"状态",dataIndex:"is_revoked",width:80,render:(Q,de)=>de.is_admin_deleted?a.jsx(Te,{color:"default",children:"已删除"}):de.is_revoked?a.jsx(Te,{color:"orange",children:"已撤回"}):a.jsx(Te,{color:"green",children:"正常"})},{title:"发送时间",dataIndex:"created_at",width:170,render:Q=>Ke(Q)},{title:"操作",key:"actions",width:80,render:(Q,de)=>de.is_admin_deleted?a.jsx(Te,{color:"default",children:"已删除"}):a.jsx(Y,{size:"small",danger:!0,onClick:()=>J(de),children:"删除"})}];return a.jsxs("div",{className:"admin-messages",children:[a.jsxs(be,{className:"admin-messages-filter",children:[l?a.jsx(qo,{options:[{label:"全部",value:"all"},{label:"图片",value:"image"},{label:"视频",value:"video"},{label:"音频",value:"audio"},{label:"文档",value:"document"},{label:"其他",value:"other"}],value:y,onChange:Q=>{R(Q),B(1,f,w,Q)},style:{marginBottom:12}}):a.jsx(qo,{options:[{label:"全部",value:"all"},{label:"文本",value:"text"},{label:"图片",value:"image"},{label:"视频",value:"video"},{label:"语音",value:"audio"},{label:"文件",value:"file"},{label:"名片",value:"contact_card"},{label:"系统",value:"system"}],value:j,onChange:Q=>{T(Q),B(1,f,w,Q)},style:{marginBottom:12}}),a.jsxs(b,{form:c,layout:"inline",onFinish:te,children:[s&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),s?a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"会话 ID",name:"conversation_id",children:a.jsx(at,{placeholder:"可选",min:1})}),a.jsx(b.Item,{label:"发送人 ID",name:"sender_id",children:a.jsx(at,{placeholder:"可选",min:1})}),o&&a.jsx(b.Item,{label:"接收人 ID",name:"receiver_id",children:a.jsx(at,{placeholder:"可选",min:1})})]}):a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"发送人用户名",name:"sender_username",children:a.jsx(ve,{placeholder:"可选",allowClear:!0})}),o&&!l&&a.jsx(b.Item,{label:"接收人用户名",name:"receiver_username",children:a.jsx(ve,{placeholder:"可选",allowClear:!0})})]}),a.jsx(b.Item,{label:l?"文件名":"关键词",name:"keyword",children:a.jsx(ve,{placeholder:l?"搜索文件名":"关键字",allowClear:!0})}),a.jsx(b.Item,{label:"开始时间",name:"startTime",children:a.jsx(jr,{showTime:!0,placeholder:"开始时间",style:{width:200}})}),a.jsx(b.Item,{label:"结束时间",name:"endTime",children:a.jsx(jr,{showTime:!0,placeholder:"结束时间",style:{width:200}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>{c.resetFields(),T("all"),R("all")},children:"重置"}),a.jsx(Y,{onClick:()=>B(),children:"刷新"})]})})]})]}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:se,dataSource:h,loading:d,scroll:{x:l?1800:1400},pagination:{current:_,pageSize:f,total:I,showSizeChanger:!0,onChange:(Q,de)=>{x(Q),p(de),B(Q,de)}}})}),a.jsxs(Me,{open:!!C,onCancel:()=>F(null),footer:null,centered:!0,destroyOnClose:!0,width:(C==null?void 0:C.type)==="video"?680:420,title:C==null?void 0:C.title,children:[(C==null?void 0:C.type)==="video"&&a.jsx("video",{controls:!0,autoPlay:!0,src:C.url,poster:C.poster,style:{width:"100%",borderRadius:8,background:"#000"}}),(C==null?void 0:C.type)==="audio"&&a.jsxs("div",{style:{padding:"24px 0",textAlign:"center"},children:[a.jsx(go,{style:{fontSize:48,color:"#1677ff",marginBottom:16}}),a.jsx("audio",{controls:!0,autoPlay:!0,src:C.url,style:{width:"100%"}})]})]})]})},DE=()=>a.jsx(rc,{conversationType:"single"}),PE=()=>a.jsx(rc,{conversationType:"group"}),{Text:Zr}=Cr,kh=[{label:"搜索",value:"search"},{label:"导出",value:"export"},{label:"创建用户",value:"create_user"},{label:"批量创建用户",value:"batch_create_users"},{label:"处理举报",value:"handle_report"},{label:"更新状态",value:"update_status"},{label:"重置密码",value:"reset_password"},{label:"修改用户名",value:"update_username"},{label:"更新安全权限",value:"update_security_perm"},{label:"强制下线",value:"kick_user"},{label:"解散群组",value:"dismiss_group"},{label:"封禁群组",value:"ban_group"},{label:"批量封禁用户",value:"batch_ban_users"},{label:"按注册IP封禁用户(历史)",value:"ban_users_by_register_ip"},{label:"按IP封禁用户",value:"ban_users_by_ip"},{label:"解封群组",value:"unban_group"},{label:"删除消息",value:"delete_message"},{label:"踢出群成员",value:"kick_group_member"},{label:"禁言群成员",value:"mute_group_member"},{label:"解除禁言",value:"unmute_group_member"},{label:"强制注销",value:"force_deactivate"},{label:"更新安全策略",value:"update_security_settings"},{label:"创建用户分组",value:"create_policy_group"},{label:"更新用户分组",value:"update_policy_group"},{label:"删除用户分组",value:"delete_policy_group"},{label:"调整用户分组",value:"assign_policy_group"},{label:"更新分组IP白名单",value:"update_policy_ip_whitelist"},{label:"删除群文件",value:"delete_group_file"}],Fh=[{label:"用户",value:"user"},{label:"群组",value:"group"},{label:"消息",value:"message"},{label:"举报",value:"report"},{label:"租户",value:"tenant"},{label:"会话",value:"conversation"},{label:"用户分组",value:"user_policy_group"}],NE=Object.fromEntries(kh.map(e=>[e.value,e.label])),LE=Object.fromEntries(Fh.map(e=>[e.value,e.label])),ME={tenant_id:"租户",user_id:"用户",group_id:"群组",keyword:"关键词",conversation_type:"会话类型",start_time:"开始时间",end_time:"结束时间",sender_username:"发送人",receiver_username:"接收人",reason:"原因",target_member:"操作成员"},BE={conversation_type:{single:"单聊",group:"群聊"}},Qd=(e,t=120)=>!e||!e.includes("aliyuncs.com")?e:`${e.split("?")[0]}?x-oss-process=image/resize,w_${t},m_lfit/quality,q_80`,UE=e=>{const t=e.match(/^\[(图片|语音|视频)]\s+(https?:\/\/\S+)/);return t?{type:{图片:"image",语音:"audio",视频:"video"}[t[1]]||null,url:t[2],label:t[1]}:{type:null,url:"",label:e}},zE=e=>!!(e==null||e===""||e===0||typeof e=="string"&&e.startsWith("0001-01-01")),mi=e=>{const t=e.lastIndexOf("(");return t>0&&e.endsWith(")")?e.slice(0,t):e},$E=(e,t)=>{const r=String(t),n=BE[e];return n&&n[r]?n[r]:e==="target_member"||e==="sender_username"||e==="receiver_username"?mi(r):(e==="start_time"||e==="end_time")&&typeof t=="string"&&t.includes("T")?r.replace("T"," ").replace("Z","").replace(/:\d{2}$/,""):r},WE=(e,t)=>{if(!e)return"--";const r=[];for(const[n,s]of Object.entries(e)){if(zE(s)||t!=null&&t.has(n))continue;const i=ME[n]||n;r.push(`${i}: ${$E(n,s)}`)}return r.length>0?r.join(" "):"--"},HE=()=>{const{admin:e,permissions:t}=pt(),r=!(e!=null&&e.tenant_id),{renderTenantId:n}=Yr(),[s,i]=g.useState(!1),[o,l]=g.useState(!1),[c,d]=g.useState([]),[u,h]=g.useState(1),[m,_]=g.useState(20),[x,f]=g.useState(0),[p,I]=g.useState({}),[S]=b.useForm(),w=async(T=u,C=m,F=p)=>{i(!0);try{const P=await td.list({...F,page:T,page_size:C});(P.code===0||P.code===200)&&P.data?(d(P.data.items),f(P.data.total),h(P.data.page),_(P.data.size)):E.error(P.message||"获取审计日志失败")}catch(P){E.error(P.message||"获取审计日志失败")}finally{i(!1)}};g.useEffect(()=>{w(1,m,p)},[]);const v=T=>{const C={};return T.admin_id&&(C.admin_id=T.admin_id),T.tenant_id&&(C.tenant_id=T.tenant_id),T.action&&(C.action=T.action),T.target_type&&(C.target_type=T.target_type),r?(T.target_user_id&&(C.target_user_id=T.target_user_id),T.target_group_id&&(C.target_group_id=T.target_group_id)):(T.target_username&&(C.target_username=T.target_username),T.target_group_code&&(C.target_group_code=T.target_group_code)),T.startTime&&(C.start_time=T.startTime.format("YYYY-MM-DD HH:mm:ss")),T.endTime&&(C.end_time=T.endTime.format("YYYY-MM-DD HH:mm:ss")),C},y=T=>{const C=v(T);I(C),w(1,m,C)},R=async()=>{const T=S.getFieldsValue(),C=v(T);l(!0);try{await td.exportCsv(C),E.success("导出成功")}catch(F){E.error(F.message||"导出失败")}finally{l(!1)}},j=[r?{title:"ID",dataIndex:"id",width:80}:null,{title:"管理员",dataIndex:"admin_name",width:160},r?{title:"租户",dataIndex:"tenant_id",width:160,render:n}:null,{title:"动作",dataIndex:"action",width:120,render:T=>a.jsx(Te,{color:"blue",children:NE[T]||T})},{title:"目标类型",dataIndex:"target_type",width:90,render:T=>a.jsx(Te,{color:"geekblue",children:LE[T]||T})},r?{title:"目标 ID",dataIndex:"target_id",width:100,render:T=>T??"--"}:{title:"目标",dataIndex:"target_display",width:160,render:(T,C)=>{const F=C.target_display;return F?a.jsxs("div",{children:[a.jsx("div",{children:F.name}),F.sub&&a.jsx(Zr,{type:"secondary",style:{fontSize:12},children:F.sub})]}):C.target_id!=null?String(C.target_id):"--"}},{title:"查询条件",dataIndex:"query",width:260,render:T=>{const C=T==null?void 0:T.details,F=T==null?void 0:T.reason,P=T==null?void 0:T.sender_username,V=T==null?void 0:T.receiver_username,X=T==null?void 0:T.target_member,_e=new Set(["details","group_id","reason","target_member"]);C&&(_e.add("sender_username"),_e.add("receiver_username")),r||_e.add("tenant_id");const B=WE(T,_e),te=!!(C||F||X);return a.jsxs(Ie,{direction:"vertical",size:0,children:[B!=="--"?a.jsx(Xt,{title:B,children:a.jsx(Zr,{type:"secondary",ellipsis:!0,className:"admin-audit-query",children:B})}):te?null:"--",te&&a.jsx(Y,{type:"link",size:"small",style:{padding:0,height:"auto",fontSize:12},onClick:()=>{if(!P&&!V&&!X&&(C!=null&&C.includes(" "))){const G=C.split(` +`).filter(Boolean).map((se,Q)=>{const de=se.split(" ");return{key:Q,nickname:de[0]||se,username:de[1]||""}});Me.info({title:"操作详情",width:480,content:a.jsxs("div",{children:[a.jsx("div",{style:{maxHeight:360,overflow:"auto"},children:a.jsx(Ye,{size:"small",pagination:!1,rowKey:"key",dataSource:G,columns:[{title:"#",dataIndex:"key",width:40,render:(se,Q,de)=>a.jsx(Zr,{type:"secondary",children:de+1})},{title:"昵称",dataIndex:"nickname"},{title:"用户名",dataIndex:"username"}]})}),a.jsx("div",{style:{textAlign:"right",marginTop:8},children:a.jsx(Y,{size:"small",onClick:()=>{const se=G.map(Q=>Q.username?`${Q.nickname} ${Q.username}`:Q.nickname).join(` +`);navigator.clipboard.writeText(se).then(()=>E.success("已复制"))},children:"复制全部"})})]}),okText:"关闭"})}else{const J=X?mi(X):void 0,G=X&&X.lastIndexOf("(")>0&&X.endsWith(")")?X.slice(X.lastIndexOf("(")+1,-1):void 0;Me.info({title:"操作详情",width:480,content:a.jsxs("div",{children:[J&&a.jsxs("div",{style:{marginBottom:4},children:[a.jsx(Zr,{type:"secondary",children:"操作成员:"}),J,G&&a.jsxs(Zr,{type:"secondary",style:{marginLeft:8},children:["(",G,")"]})]}),P&&a.jsxs("div",{style:{marginBottom:4},children:[a.jsx(Zr,{type:"secondary",children:"发送人:"}),mi(P)]}),V&&a.jsxs("div",{style:{marginBottom:4},children:[a.jsx(Zr,{type:"secondary",children:"接收人:"}),mi(V)]}),F&&a.jsxs("div",{style:{marginBottom:4},children:[a.jsx(Zr,{type:"secondary",children:"原因:"}),F]}),C&&(()=>{const se=UE(C);return se.type==="image"&&se.url?a.jsxs("div",{style:{marginTop:8},children:[a.jsxs(Zr,{type:"secondary",children:["消息内容:[",se.label,"]"]}),a.jsx("div",{style:{marginTop:4},children:a.jsx(Mr,{src:Qd(se.url,400),style:{maxWidth:360,maxHeight:300,borderRadius:4},preview:{src:Qd(se.url,800)}})})]}):(se.type==="video"||se.type==="audio")&&se.url?a.jsxs("div",{style:{marginTop:8},children:[a.jsxs(Zr,{type:"secondary",children:["消息内容:[",se.label,"]"]}),a.jsx("div",{style:{marginTop:4},children:a.jsx("a",{href:se.url,target:"_blank",rel:"noopener noreferrer",children:se.url})})]}):a.jsx("div",{style:{marginTop:8,padding:8,background:"#fafafa",borderRadius:4,maxHeight:300,overflow:"auto",whiteSpace:"pre-wrap",wordBreak:"break-all"},children:C})})()]}),okText:"关闭"})}},children:"详情"})]})}},{title:"IP",dataIndex:"ip",width:140},{title:"时间",dataIndex:"created_at",width:180,render:T=>Ke(T)}].filter(T=>T!=null);return a.jsxs("div",{className:"admin-audit",children:[a.jsx(be,{className:"admin-audit-filter",children:a.jsxs(b,{form:S,layout:"inline",onFinish:y,children:[r&&a.jsx(b.Item,{label:"管理员 ID",name:"admin_id",children:a.jsx(at,{placeholder:"可选",min:1})}),r&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"动作",name:"action",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:kh,style:{width:120}})}),a.jsx(b.Item,{label:"目标类型",name:"target_type",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:Fh,style:{width:120}})}),r?a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"用户 ID",name:"target_user_id",children:a.jsx(at,{placeholder:"可选",min:1})}),a.jsx(b.Item,{label:"群组 ID",name:"target_group_id",children:a.jsx(at,{placeholder:"可选",min:1})})]}):a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"目标用户",name:"target_username",children:a.jsx(ve,{placeholder:"用户名",allowClear:!0,style:{width:130}})}),a.jsx(b.Item,{label:"目标群",name:"target_group_code",children:a.jsx(ve,{placeholder:"群号",allowClear:!0,style:{width:130}})})]}),a.jsx(b.Item,{label:"开始时间",name:"startTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{label:"结束时间",name:"endTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:()=>S.resetFields(),children:"重置"}),a.jsx(Y,{icon:a.jsx($r,{}),onClick:R,loading:o,disabled:!(t!=null&&t.export_chat),children:"导出 CSV"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:j,dataSource:c,loading:s,scroll:{x:1200},pagination:{current:u,pageSize:m,total:x,showSizeChanger:!0,onChange:(T,C)=>{h(T),_(C),w(T,C)}}})})]})},VE=[{label:"启用",value:"active"},{label:"封禁",value:"banned"}],KE=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(1),[o,l]=g.useState(20),[c,d]=g.useState(0),[u,h]=g.useState({}),[m]=b.useForm(),[_,x]=g.useState(!1),[f,p]=g.useState(null),[I]=b.useForm(),[S,w]=g.useState({}),[v,y]=g.useState([]),R=async(K=s,Z=o,me=u)=>{t(!0);try{const ie=await hn.list({...me,page:K,page_size:Z});(ie.code===0||ie.code===200)&&ie.data?(n(ie.data.items),d(ie.data.total),i(ie.data.page),l(ie.data.size),j(ie.data.items)):E.error(ie.message||"获取私域列表失败")}catch(ie){E.error(ie.message||"获取私域列表失败")}finally{t(!1)}},j=g.useCallback(async K=>{const Z={};(await Promise.allSettled(K.map(ie=>On.getTenantBinding(ie.id)))).forEach((ie,he)=>{if(ie.status==="fulfilled"){const we=ie.value;(we.code===0||we.code===200)&&we.data&&(Z[K[he].id]=we.data)}}),w(Z)},[]),T=async()=>{try{const K=await On.list({page:1,page_size:100});(K.code===0||K.code===200)&&K.data&&y(K.data.items||[])}catch{}};g.useEffect(()=>{R(1,o,u),T()},[]);const C=K=>{const Z={tenant_id:K.tenant_id,status:K.status,keyword:K.keyword};h(Z),R(1,o,Z)},F=g.useMemo(()=>v.find(K=>K.is_default),[v]),P=g.useMemo(()=>{const K=[];return F&&F.status==="active"&&K.push({label:`${F.name}(中心服务器)`,value:F.node_id}),v.filter(Z=>!Z.is_default&&Z.status==="active"&&Z.tenant_count===0).forEach(Z=>K.push({label:`${Z.name}(${Z.node_id})`,value:Z.node_id})),K},[v,F]),V=()=>{p(null),I.resetFields(),x(!0)},X=K=>{p(K),I.setFieldsValue({name:K.name,username_prefix:K.username_prefix,default_password:"",max_users:K.max_users}),x(!0)},_e=async()=>{try{const K=await I.validateFields();let Z;f?Z=await hn.update(f.id,{name:K.name,username_prefix:K.username_prefix,default_password:K.default_password||void 0,max_users:K.max_users}):Z=await hn.create({code:K.code,name:K.name,username_prefix:K.username_prefix,default_password:K.default_password,max_users:K.max_users,node_id:K.node_id,admin_username:K.admin_username,admin_password:K.admin_password}),Z.code===0||Z.code===200?(E.success(f?"私域已更新":"私域已创建"),x(!1),R()):E.error(Z.message||"操作失败")}catch(K){if(K!=null&&K.errorFields)return;E.error(K.message||"操作失败")}},[B,te]=g.useState(!1),[J,G]=g.useState(null),[se,Q]=g.useState(""),de=K=>{G(K),Q(""),te(!0)},k=async()=>{if(J)try{const K=await hn.updateStatus(J.id,"banned",se);K.code===0||K.code===200?(E.success("私域已封禁,所有在线用户已被踢下线"),te(!1),R()):E.error(K.message||"封禁失败")}catch(K){E.error(K.message||"封禁失败")}},W=async K=>{try{const Z=await hn.updateStatus(K.id,"active");Z.code===0||Z.code===200?(E.success("私域已启用"),R()):E.error(Z.message||"启用失败")}catch(Z){E.error(Z.message||"启用失败")}},z=()=>{Me.confirm({title:"自动绑定",content:"将所有未绑定节点的私域自动绑定到默认节点,确认操作?",okText:"确认",cancelText:"取消",onOk:async()=>{var K;try{const Z=await hn.autoBind();Z.code===0||Z.code===200?(E.success(`已自动绑定 ${((K=Z.data)==null?void 0:K.bound_count)??0} 个私域`),R(),T()):E.error(Z.message||"自动绑定失败")}catch(Z){E.error(Z.message||"自动绑定失败")}}})},D=K=>{Me.confirm({title:"确认踢出节点?",content:`将解除私域「${K.name}」的节点绑定关系,解绑后该私域将不可用。`,okText:"踢出",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const Z=await On.unbindTenant(K.id);Z.code===0||Z.code===200?(E.success("已踢出节点"),j(r),T()):E.error(Z.message||"踢出失败")}catch(Z){E.error(Z.message||"踢出失败")}}})},q=[{title:"ID",dataIndex:"id",width:80},{title:"编号",dataIndex:"tenant_no",width:80},{title:"私域编码",dataIndex:"code",width:140},{title:"私域名称",dataIndex:"name",width:160},{title:"管理员",dataIndex:"admin_username",width:120,render:K=>K||"-"},{title:"前缀",dataIndex:"username_prefix",width:100},{title:"人数",key:"user_count",width:120,render:(K,Z)=>{const me=Z.max_users>0?Z.max_users:"∞";return`${Z.user_count} / ${me}`}},{title:"状态",dataIndex:"status",width:100,render:K=>a.jsx(Te,{color:K==="active"?"green":"red",children:K==="active"?"启用":"封禁"})},{title:"绑定节点",key:"binding",width:160,render:(K,Z)=>{const me=S[Z.id];return me?a.jsx(Te,{color:"blue",children:me.node_name||me.node_id}):a.jsx(Te,{children:"未绑定"})}},{title:"创建时间",dataIndex:"created_at",width:170,render:K=>Ke(K)},{title:"操作",key:"actions",width:240,render:(K,Z)=>{const me=S[Z.id];return a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>X(Z),children:"编辑"}),Z.status==="active"?a.jsx(Y,{size:"small",danger:!0,onClick:()=>de(Z),children:"封禁"}):a.jsx(Y,{size:"small",onClick:()=>W(Z),children:"启用"}),me&&a.jsx(Y,{size:"small",danger:!0,onClick:()=>D(Z),children:"踢出节点"})]})}}];return a.jsxs("div",{className:"admin-tenants",children:[a.jsx(be,{className:"admin-tenants-filter",children:a.jsxs(b,{form:m,layout:"inline",onFinish:C,children:[a.jsx(b.Item,{label:"私域 ID",name:"tenant_id",children:a.jsx(at,{placeholder:"可选",min:1})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:VE,style:{width:120}})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"私域名称 / 编码",allowClear:!0})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>m.resetFields(),children:"重置"}),a.jsx(Y,{onClick:V,children:"创建私域"}),a.jsx(Y,{onClick:z,children:"自动绑定"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:q,dataSource:r,loading:e,scroll:{x:1600},pagination:{current:s,pageSize:o,total:c,showSizeChanger:!0,onChange:(K,Z)=>{i(K),l(Z),R(K,Z)}}})}),a.jsx(Me,{title:f?"编辑私域":"创建私域",open:_,onCancel:()=>x(!1),onOk:_e,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:I,layout:"vertical",children:[!f&&a.jsx(b.Item,{label:"私域编码",name:"code",rules:[{required:!0,message:"请输入私域编码"}],children:a.jsx(ve,{placeholder:"例如 TEST01"})}),a.jsx(b.Item,{label:"私域名称",name:"name",rules:[{required:!0,message:"请输入私域名称"}],children:a.jsx(ve,{placeholder:"私域名称"})}),a.jsx(b.Item,{label:"用户名前缀",name:"username_prefix",rules:[{required:!0,message:"请输入用户名前缀"}],children:a.jsx(ve,{placeholder:"2-4 位前缀",maxLength:4})}),a.jsx(b.Item,{label:"默认密码",name:"default_password",children:a.jsx(ve.Password,{placeholder:f?"留空表示不修改":"可选"})}),f&&a.jsx(b.Item,{label:`最大用户数(当前 ${f.user_count} 人)`,name:"max_users",rules:[{required:!0,message:"请输入最大用户数"},{type:"number",min:1,message:"最大用户数必须大于 0"}],children:a.jsx(at,{min:1,placeholder:"请输入大于 0 的数值",style:{width:"100%"}})}),!f&&a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"最大用户数",name:"max_users",rules:[{required:!0,message:"请输入最大用户数"},{type:"number",min:1,message:"最大用户数必须大于 0"}],children:a.jsx(at,{min:1,placeholder:"请输入大于 0 的数值",style:{width:"100%"}})}),a.jsx(b.Item,{label:"节点",name:"node_id",initialValue:F==null?void 0:F.node_id,extra:"默认为中心服务器,子节点 1:1 绑定",children:a.jsx($e,{placeholder:"选择节点",options:P})}),a.jsx(b.Item,{label:"管理员用户名",name:"admin_username",rules:[{required:!0,message:"请输入管理员用户名"},{max:20,message:"用户名不超过 20 位"},{pattern:/^[a-z0-9]+$/,message:"仅限小写字母和数字"}],extra:"私域最高管理员账号,小写字母+数字,20 位以内",children:a.jsx(ve,{placeholder:"小写字母+数字",maxLength:20})}),a.jsx(b.Item,{label:"管理员密码",name:"admin_password",rules:[{required:!0,message:"请输入管理员密码"},{min:8,max:20,message:"密码需为 8-20 位"},{pattern:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/,message:"需包含数字、大写和小写字母"}],extra:"数字 + 大小写字母,8-20 位",children:a.jsx(ve.Password,{placeholder:"8-20 位"})})]})]})}),a.jsxs(Me,{title:`封禁私域「${(J==null?void 0:J.name)||""}」`,open:B,onCancel:()=>te(!1),onOk:k,okText:"确认封禁",okButtonProps:{danger:!0},cancelText:"取消",destroyOnClose:!0,children:[a.jsx("p",{style:{marginBottom:8,color:"#666"},children:"封禁后,该私域所有在线用户将被踢下线,且无法再登录。"}),a.jsx(ve.TextArea,{rows:3,placeholder:"请输入封禁原因",value:se,onChange:K=>Q(K.target.value),maxLength:200,showCount:!0})]})]})},ks=[{label:"私域管理",value:"tenant_manage"},{label:"用户管理",value:"user_manage"},{label:"群组管理",value:"group_manage"},{label:"私聊审计",value:"view_private_chat"},{label:"群聊审计",value:"view_group_chat"},{label:"导出记录",value:"export_chat"},{label:"操作日志",value:"view_audit_log"}],Fs=e=>e?ks.filter(t=>e[t.value]).map(t=>t.value):[],nc=(e=[])=>({tenant_manage:e.includes("tenant_manage"),user_manage:e.includes("user_manage"),group_manage:e.includes("group_manage"),view_private_chat:e.includes("view_private_chat"),view_group_chat:e.includes("view_group_chat"),export_chat:e.includes("export_chat"),view_audit_log:e.includes("view_audit_log")}),GE=[{label:"启用",value:"active"},{label:"禁用",value:"disabled"}],YE=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(1),[o,l]=g.useState(20),[c,d]=g.useState(0),[u,h]=g.useState({}),[m]=b.useForm(),[_,x]=g.useState(!1),[f,p]=g.useState(null),[I]=b.useForm(),[S,w]=g.useState(!1),[v,y]=g.useState(null),[R]=b.useForm(),j=async(G=s,se=o,Q=u)=>{t(!0);try{const de=await os.list({...Q,page:G,page_size:se});(de.code===0||de.code===200)&&de.data?(n(de.data.items),d(de.data.total),i(de.data.page),l(de.data.size)):E.error(de.message||"获取管理员列表失败")}catch(de){E.error(de.message||"获取管理员列表失败")}finally{t(!1)}};g.useEffect(()=>{j(1,o,u)},[]);const T=G=>{const se={status:G.status,keyword:G.keyword};h(se),j(1,o,se)},C=()=>{p(null),I.resetFields(),I.setFieldsValue({permissions:[]}),x(!0)},F=G=>{p(G),I.setFieldsValue({nickname:G.nickname,permissions:Fs(G.permissions)}),x(!0)},P=async()=>{try{const G=await I.validateFields(),se=nc(G.permissions||[]),Q=f?await os.update(f.id,{nickname:G.nickname,permissions:se}):await os.create({username:G.username,password:G.password,nickname:G.nickname,permissions:se});Q.code===0||Q.code===200?(E.success(f?"管理员已更新":"管理员已创建"),x(!1),j()):E.error(Q.message||"操作失败")}catch(G){if(G!=null&&G.errorFields)return;E.error(G.message||"操作失败")}},V=async G=>{const se=G.status==="active"?"disabled":"active";try{const Q=await os.updateStatus(G.id,se);Q.code===0||Q.code===200?(E.success("状态已更新"),j()):E.error(Q.message||"更新状态失败")}catch(Q){E.error(Q.message||"更新状态失败")}},X=G=>{y(G),R.resetFields(),w(!0)},_e=async()=>{try{const G=await R.validateFields(),se=await os.resetPassword(v.id,G.password);se.code===0||se.code===200?(E.success("密码已重置"),w(!1)):E.error(se.message||"重置密码失败")}catch(G){if(G!=null&&G.errorFields)return;E.error(G.message||"重置密码失败")}},B=G=>{Me.confirm({title:"确认删除该管理员?",content:"删除后将无法登录后台,请谨慎操作。",okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const se=await os.delete(G.id);se.code===0||se.code===200?(E.success("管理员已删除"),j()):E.error(se.message||"删除失败")}catch(se){E.error(se.message||"删除失败")}}})},te=G=>{const se=Fs(G);return se.length?a.jsx(Ie,{wrap:!0,children:se.map(Q=>{var k;const de=((k=ks.find(W=>W.value===Q))==null?void 0:k.label)||Q;return a.jsx(Te,{color:"blue",children:de},Q)})}):"--"},J=[{title:"ID",dataIndex:"id",width:80},{title:"用户名",dataIndex:"username",width:160},{title:"昵称",dataIndex:"nickname",width:160},{title:"权限",dataIndex:"permissions",width:320,render:(G,se)=>te(se.permissions)},{title:"状态",dataIndex:"status",width:100,render:G=>a.jsx(Te,{color:G==="active"?"green":"red",children:G==="active"?"启用":"禁用"})},{title:"最近登录",dataIndex:"last_login_at",width:180,render:G=>Ke(G)},{title:"创建时间",dataIndex:"created_at",width:180,render:G=>Ke(G)},{title:"操作",key:"actions",width:300,render:(G,se)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>F(se),children:"编辑"}),a.jsx(Y,{size:"small",onClick:()=>X(se),children:"重置密码"}),a.jsx(Y,{size:"small",onClick:()=>V(se),children:se.status==="active"?"禁用":"启用"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>B(se),children:"删除"})]})}];return a.jsxs("div",{className:"admin-admins",children:[a.jsx(be,{className:"admin-admins-filter",children:a.jsxs(b,{form:m,layout:"inline",onFinish:T,children:[a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:GE,style:{width:120}})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"用户名/昵称",allowClear:!0})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>m.resetFields(),children:"重置"}),a.jsx(Y,{onClick:C,children:"创建管理员"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:J,dataSource:r,loading:e,scroll:{x:1200},pagination:{current:s,pageSize:o,total:c,showSizeChanger:!0,onChange:(G,se)=>{i(G),l(se),j(G,se)}}})}),a.jsx(Me,{title:f?"编辑管理员":"创建管理员",open:_,onCancel:()=>x(!1),onOk:P,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:I,layout:"vertical",children:[!f&&a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"用户名",name:"username",rules:[{required:!0,message:"请输入用户名"}],children:a.jsx(ve,{placeholder:"请输入用户名"})}),a.jsx(b.Item,{label:"密码",name:"password",tooltip:"至少 8 位,需包含大小写字母和数字",rules:[{required:!0,message:"请输入密码"},{min:8,message:"密码至少 8 位"},{pattern:/^[\x21-\x7e]+$/,message:"只能包含英文字母、数字和英文特殊字符"},{pattern:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/,message:"必须包含大小写字母和数字"}],children:a.jsx(ve.Password,{placeholder:"请输入密码"})})]}),a.jsx(b.Item,{label:"昵称",name:"nickname",rules:[{required:!0,message:"请输入昵称"}],children:a.jsx(ve,{placeholder:"管理员昵称"})}),a.jsx(b.Item,{label:"权限",name:"permissions",rules:[{required:!0,message:"请选择权限"}],children:a.jsx(gl.Group,{options:ks})})]})}),a.jsx(Me,{title:`重置密码 - ${(v==null?void 0:v.username)||""}`,open:S,onCancel:()=>w(!1),onOk:_e,okText:"确认重置",cancelText:"取消",destroyOnClose:!0,children:a.jsx(b,{form:R,layout:"vertical",children:a.jsx(b.Item,{label:"新密码",name:"password",tooltip:"至少 8 位,需包含大小写字母和数字",rules:[{required:!0,message:"请输入新密码"},{min:8,message:"密码至少 8 位"},{pattern:/^[\x21-\x7e]+$/,message:"只能包含英文字母、数字和英文特殊字符"},{pattern:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/,message:"必须包含大小写字母和数字"}],children:a.jsx(ve.Password,{placeholder:"请输入新密码"})})})})]})},qE=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(1),[o,l]=g.useState(20),[c,d]=g.useState(0),[u,h]=g.useState({}),[m]=b.useForm(),[_,x]=g.useState(!1),[f,p]=g.useState(null),[I]=b.useForm(),S=async(F=s,P=o,V=u)=>{t(!0);try{const X=await Ya.list({...V,page:F,page_size:P});(X.code===0||X.code===200)&&X.data?(n(X.data.items),d(X.data.total),i(X.data.page),l(X.data.size)):E.error(X.message||"获取角色列表失败")}catch(X){E.error(X.message||"获取角色列表失败")}finally{t(!1)}};g.useEffect(()=>{S(1,o,u)},[]);const w=F=>{const P={keyword:F.keyword};h(P),S(1,o,P)},v=()=>{p(null),I.resetFields(),I.setFieldsValue({permissions:[]}),x(!0)},y=F=>{p(F),I.setFieldsValue({name:F.name,description:F.description,permissions:Fs(F.permissions)}),x(!0)},R=async()=>{try{const F=await I.validateFields(),P=nc(F.permissions||[]),V=f?await Ya.update(f.id,{name:F.name,description:F.description,permissions:P}):await Ya.create({name:F.name,description:F.description,permissions:P});V.code===0||V.code===200?(E.success(f?"角色已更新":"角色已创建"),x(!1),S()):E.error(V.message||"操作失败")}catch(F){if(F!=null&&F.errorFields)return;E.error(F.message||"操作失败")}},j=F=>{Me.confirm({title:"确认删除该角色?",content:"删除角色会影响已绑定的管理员权限,请谨慎操作。",okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const P=await Ya.delete(F.id);P.code===0||P.code===200?(E.success("角色已删除"),S()):E.error(P.message||"删除失败")}catch(P){E.error(P.message||"删除失败")}}})},T=F=>{const P=Fs(F);return P.length?a.jsx(Ie,{wrap:!0,children:P.map(V=>{var _e;const X=((_e=ks.find(B=>B.value===V))==null?void 0:_e.label)||V;return a.jsx(Te,{color:"blue",children:X},V)})}):"--"},C=[{title:"ID",dataIndex:"id",width:80},{title:"角色名称",dataIndex:"name",width:160},{title:"描述",dataIndex:"description",width:200,render:F=>F||"--"},{title:"权限",dataIndex:"permissions",width:320,render:(F,P)=>T(P.permissions)},{title:"创建时间",dataIndex:"created_at",width:180,render:F=>Ke(F)},{title:"操作",key:"actions",width:160,render:(F,P)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>y(P),children:"编辑"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>j(P),children:"删除"})]})}];return a.jsxs("div",{className:"admin-roles",children:[a.jsx(be,{className:"admin-roles-filter",children:a.jsxs(b,{form:m,layout:"inline",onFinish:w,children:[a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"角色名称",allowClear:!0})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>m.resetFields(),children:"重置"}),a.jsx(Y,{onClick:v,children:"创建角色"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:C,dataSource:r,loading:e,scroll:{x:1e3},pagination:{current:s,pageSize:o,total:c,showSizeChanger:!0,onChange:(F,P)=>{i(F),l(P),S(F,P)}}})}),a.jsx(Me,{title:f?"编辑角色":"创建角色",open:_,onCancel:()=>x(!1),onOk:R,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:I,layout:"vertical",children:[a.jsx(b.Item,{label:"角色名称",name:"name",rules:[{required:!0,message:"请输入角色名称"}],children:a.jsx(ve,{placeholder:"角色名称"})}),a.jsx(b.Item,{label:"描述",name:"description",children:a.jsx(ve.TextArea,{placeholder:"可选描述",rows:3})}),a.jsx(b.Item,{label:"权限",name:"permissions",rules:[{required:!0,message:"请选择权限"}],children:a.jsx(gl.Group,{options:ks})})]})})]})},{Text:XE}=Cr,JE=[{label:"启用",value:"active"},{label:"已使用",value:"used"},{label:"已删除",value:"deleted"},{label:"禁用",value:"disabled"},{label:"已过期",value:"expired"}],ZE=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,{renderTenantId:r}=Yr(),[n,s]=g.useState(!1),[i,o]=g.useState([]),[l,c]=g.useState(1),[d,u]=g.useState(20),[h,m]=g.useState(0),[_,x]=g.useState({}),[f]=b.useForm(),[p,I]=g.useState(!1),[S,w]=g.useState(!1),[v]=b.useForm(),[y,R]=g.useState([]),[j,T]=g.useState(!1),[C,F]=g.useState(!1),[P,V]=g.useState(!1),[X,_e]=g.useState([]),[B,te]=g.useState(0),[J,G]=g.useState(1),[se,Q]=g.useState(10),[de,k]=g.useState(null),W=b.useWatch("tenant_id",v),z=b.useWatch("auto_add_friend",v),D=async(le=l,fe=d,Re=_)=>{s(!0);try{const Ue=await qa.list({...Re,page:le,page_size:fe});(Ue.code===0||Ue.code===200)&&Ue.data?(o(Ue.data.items),m(Ue.data.total),c(Ue.data.page),u(Ue.data.size)):E.error(Ue.message||"获取邀请码列表失败")}catch(Ue){E.error(Ue.message||"获取邀请码列表失败")}finally{s(!1)}},q=g.useCallback(async(le,fe)=>{T(!0);try{const Re=await Lt.list({tenant_id:le,keyword:fe||void 0,status:"active",page:1,page_size:100});(Re.code===0||Re.code===200)&&Re.data&&R(Re.data.items.map(nt=>({value:nt.id,label:`${nt.nickname||nt.username} (${nt.username})`})))}catch{R([])}finally{T(!1)}},[]);g.useEffect(()=>{D(1,d,_)},[]),g.useEffect(()=>{if(!p)return;const le=t?W:e==null?void 0:e.tenant_id;le?q(le):R([])},[p,W,t,e==null?void 0:e.tenant_id,q]);const K=le=>{const fe={tenant_id:le.tenant_id,status:le.status,keyword:le.keyword};x(fe),D(1,d,fe)},Z=()=>{v.resetFields(),v.setFieldsValue({no_expire:!1,auto_add_friend:!1}),!t&&(e!=null&&e.tenant_id)&&v.setFieldsValue({tenant_id:e.tenant_id}),I(!0)},me=async()=>{try{const le=await v.validateFields(),fe=t?le.tenant_id:e==null?void 0:e.tenant_id;if(!fe){E.error("无法获取租户信息");return}if(le.auto_add_friend&&!le.bind_user_id){E.error("开启自动加好友时必须指定用户");return}w(!0);const Re=await qa.create({tenant_id:fe,bind_user_id:le.bind_user_id,no_expire:le.no_expire,auto_add_friend:le.auto_add_friend});Re.code===0||Re.code===200?(E.success("邀请码已生成"),I(!1),D(1,d,_)):E.error(Re.message||"创建失败")}catch(le){if(le!=null&&le.errorFields)return;E.error(le.message||"创建失败")}finally{w(!1)}},ie=async(le,fe=1,Re=se)=>{V(!0);try{const Ue=await qa.listUsages(le.id,{page:fe,page_size:Re});(Ue.code===0||Ue.code===200)&&Ue.data?(_e(Ue.data.items),te(Ue.data.total),G(Ue.data.page),Q(Ue.data.size)):E.error(Ue.message||"获取注册用户失败")}catch(Ue){E.error(Ue.message||"获取注册用户失败")}finally{V(!1)}},he=le=>{k(le),F(!0),ie(le,1,se)},we=le=>{Me.confirm({title:"确认标记删除该邀请码?",content:"删除后不可再用于注册,历史记录仍保留在列表中。",okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const fe=await qa.delete(le.id);fe.code===0||fe.code===200?(E.success("邀请码已标记删除"),D()):E.error(fe.message||"删除失败")}catch(fe){E.error(fe.message||"删除失败")}}})},He=le=>le==="active"?a.jsx(Te,{color:"green",children:"启用"}):le==="used"?a.jsx(Te,{color:"blue",children:"已使用"}):le==="expired"?a.jsx(Te,{color:"orange",children:"已过期"}):le==="deleted"?a.jsx(Te,{children:"已删除"}):a.jsx(Te,{color:"red",children:"禁用"}),ze=[{title:"ID",dataIndex:"id",key:"id",width:80},{title:"租户",dataIndex:"tenant_id",key:"tenant_id",width:140,render:r},{title:"邀请码",dataIndex:"code",width:100},{title:"指定用户",dataIndex:"bind_username",width:140,render:(le,fe)=>le?`${le}${fe.bind_user_id?` (#${fe.bind_user_id})`:""}`:"-"},{title:"自动加好友",dataIndex:"auto_add_friend",width:110,render:le=>le?a.jsx(Te,{color:"cyan",children:"是"}):a.jsx(Te,{children:"否"})},{title:"使用人数",dataIndex:"used_count",width:90,render:le=>le??0},{title:"创建人",dataIndex:"created_by",width:90},{title:"状态",dataIndex:"status",width:90,render:le=>He(le)},{title:"过期时间",dataIndex:"expires_at",width:170,render:le=>le?Ke(le):"永久有效"},{title:"创建时间",dataIndex:"created_at",width:170,render:le=>Ke(le)},{title:"操作",key:"actions",width:150,fixed:"right",render:(le,fe)=>a.jsxs(Ie,{size:"small",children:[a.jsx(Y,{size:"small",onClick:()=>he(fe),children:"查看"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>we(fe),disabled:fe.status==="deleted",children:"删除"})]})}],gt=t?ze:ze.filter(le=>le.key!=="id"&&le.key!=="tenant_id"),qe=[{title:"用户ID",dataIndex:"user_id",width:100},{title:"用户名",dataIndex:"username",width:140},{title:"昵称",dataIndex:"nickname",width:140,render:le=>le||"-"},{title:"注册时间",dataIndex:"used_at",width:180,render:le=>Ke(le)}];return a.jsxs("div",{className:"admin-invite-codes",children:[a.jsx(be,{className:"admin-invite-codes-filter",children:a.jsxs(b,{form:f,layout:"inline",onFinish:K,children:[t&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:JE,style:{width:120}})}),a.jsx(b.Item,{label:"邀请码",name:"keyword",children:a.jsx(ve,{placeholder:"6 位数字",allowClear:!0,maxLength:6})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>f.resetFields(),children:"重置"}),a.jsx(Y,{type:"primary",onClick:Z,children:"生成邀请码"})]})})]})}),a.jsxs(be,{children:[a.jsx(XE,{type:"secondary",style:{display:"block",marginBottom:12},children:"每次生成 1 个邀请码,可多次使用。可指定企业与用户;勾选「不限制时间」则永久有效;开启「自动加好友」后,使用该码注册的用户将直接成为指定用户的好友。点击「查看」可查看使用该邀请码注册的用户列表。"}),a.jsx(Ye,{rowKey:"id",columns:gt,dataSource:i,loading:n,scroll:{x:1500},pagination:{current:l,pageSize:d,total:h,showSizeChanger:!0,onChange:(le,fe)=>{c(le),u(fe),D(le,fe)}}})]}),a.jsx(Me,{title:"生成邀请码",open:p,onCancel:()=>I(!1),onOk:me,okText:"生成",cancelText:"取消",confirmLoading:S,destroyOnClose:!0,width:520,children:a.jsxs(b,{form:v,layout:"vertical",initialValues:{no_expire:!1,auto_add_friend:!1},children:[t?a.jsx(b.Item,{label:"企业",name:"tenant_id",rules:[{required:!0,message:"请选择企业"}],children:a.jsx(ot,{placeholder:"请选择企业",style:{width:"100%"}})}):a.jsx(b.Item,{label:"企业",children:a.jsx(ve,{value:r(e==null?void 0:e.tenant_id),disabled:!0})}),a.jsx(b.Item,{label:"指定用户",name:"bind_user_id",rules:z?[{required:!0,message:"开启自动加好友时必须指定用户"}]:[],extra:"可选;开启自动加好友时必填",children:a.jsx($e,{allowClear:!0,showSearch:!0,placeholder:"搜索用户名或昵称",optionFilterProp:"label",loading:j,options:y,onSearch:le=>{const fe=t?W:e==null?void 0:e.tenant_id;fe&&q(fe,le)},disabled:!(t?W:e!=null&&e.tenant_id)})}),a.jsx(b.Item,{label:"不限制时间",name:"no_expire",valuePropName:"checked",extra:"不勾选时默认 24 小时有效",children:a.jsx(rt,{checkedChildren:"永久",unCheckedChildren:"24小时"})}),a.jsx(b.Item,{label:"自动加好友",name:"auto_add_friend",valuePropName:"checked",extra:"开启后,使用该邀请码注册的用户将直接成为「指定用户」的好友",children:a.jsx(rt,{checkedChildren:"开启",unCheckedChildren:"关闭"})})]})}),a.jsx(Me,{title:de?`注册用户 - 邀请码 ${de.code}`:"注册用户",open:C,onCancel:()=>{F(!1),k(null)},footer:null,width:720,destroyOnClose:!0,children:a.jsx(Ye,{rowKey:le=>`${le.user_id}-${le.used_at}`,columns:qe,dataSource:X,loading:P,pagination:{current:J,pageSize:se,total:B,showSizeChanger:!0,onChange:(le,fe)=>{de&&ie(de,le,fe)}}})})]})},eu=[{label:"草稿",value:"draft"},{label:"已发布",value:"published"}],QE=()=>{const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),{renderTenantId:n}=Yr(),[s,i]=g.useState(!1),[o,l]=g.useState([]),[c,d]=g.useState(1),[u,h]=g.useState(20),[m,_]=g.useState(0),[x,f]=g.useState({}),[p]=b.useForm(),[I,S]=g.useState(!1),[w,v]=g.useState(null),[y]=b.useForm(),R=async(B=c,te=u,J=x)=>{i(!0);try{const G=await zs.list({...J,page:B,page_size:te});(G.code===0||G.code===200)&&G.data?(l(G.data.items),_(G.data.total),d(G.data.page),h(G.data.size)):E.error(G.message||"获取公告列表失败")}catch(G){E.error(G.message||"获取公告列表失败")}finally{i(!1)}};g.useEffect(()=>{R(1,u,x)},[]);const j=B=>{const te={tenant_id:B.tenant_id,status:B.status,keyword:B.keyword};f(te),R(1,u,te)},T=()=>{v(null),y.resetFields(),y.setFieldsValue({status:"draft"}),S(!0)},C=B=>{v(B),y.setFieldsValue({tenant_id:B.tenant_id??void 0,title:B.title,content:B.content,status:B.status}),S(!0)},F=async()=>{try{const B=await y.validateFields(),te={tenant_id:B.tenant_id||void 0,title:B.title,content:B.content,status:B.status},J=w?await zs.update(w.id,te):await zs.create(te);J.code===0||J.code===200?(E.success(w?"公告已更新":"公告已创建"),S(!1),R()):E.error(J.message||"操作失败")}catch(B){if(B!=null&&B.errorFields)return;E.error(B.message||"操作失败")}},P=B=>{Me.confirm({title:"确认发布该公告?",okText:"发布",cancelText:"取消",onOk:async()=>{try{const te=await zs.publish(B.id);te.code===0||te.code===200?(E.success("公告已发布"),R()):E.error(te.message||"发布失败")}catch(te){E.error(te.message||"发布失败")}}})},V=B=>{Me.confirm({title:"确认删除该公告?",okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const te=await zs.delete(B.id);te.code===0||te.code===200?(E.success("公告已删除"),R()):E.error(te.message||"删除失败")}catch(te){E.error(te.message||"删除失败")}}})},X=B=>B==="published"?a.jsx(Te,{color:"green",children:"已发布"}):a.jsx(Te,{color:"orange",children:"草稿"}),_e=[{title:"ID",dataIndex:"id",width:80},{title:"租户",dataIndex:"tenant_id",width:160,render:B=>B?n(B):"全局"},{title:"标题",dataIndex:"title",width:200},{title:"状态",dataIndex:"status",width:100,render:B=>X(B)},{title:"发布时间",dataIndex:"published_at",width:180,render:B=>Ke(B)},{title:"创建时间",dataIndex:"created_at",width:180,render:B=>Ke(B)},{title:"操作",key:"actions",width:220,render:(B,te)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>C(te),children:"编辑"}),te.status!=="published"&&a.jsx(Y,{size:"small",onClick:()=>P(te),children:"发布"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>V(te),children:"删除"})]})}];return a.jsxs("div",{className:"admin-announcements",children:[a.jsx(be,{className:"admin-announcements-filter",children:a.jsxs(b,{form:p,layout:"inline",onFinish:j,children:[r&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:eu,style:{width:120}})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"公告标题",allowClear:!0})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>p.resetFields(),children:"重置"}),a.jsx(Y,{onClick:T,children:"创建公告"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:_e,dataSource:o,loading:s,scroll:{x:1200},pagination:{current:c,pageSize:u,total:m,showSizeChanger:!0,onChange:(B,te)=>{d(B),h(te),R(B,te)}}})}),a.jsx(Me,{title:w?"编辑公告":"创建公告",open:I,onCancel:()=>S(!1),onOk:F,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:y,layout:"vertical",children:[a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,placeholder:"为空表示全局公告",style:{width:"100%"}})}),a.jsx(b.Item,{label:"标题",name:"title",rules:[{required:!0,message:"请输入公告标题"}],children:a.jsx(ve,{placeholder:"公告标题"})}),a.jsx(b.Item,{label:"内容",name:"content",rules:[{required:!0,message:"请输入公告内容"}],children:a.jsx(ve.TextArea,{placeholder:"公告内容",rows:4})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{options:eu})})]})})]})},Ho=[{label:"低",value:"low"},{label:"中",value:"medium"},{label:"高",value:"high"}],Vo=[{label:"启用",value:"active"},{label:"禁用",value:"disabled"}],ej=()=>{const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),{renderTenantId:n}=Yr(),[s,i]=g.useState(!1),[o,l]=g.useState([]),[c,d]=g.useState(1),[u,h]=g.useState(20),[m,_]=g.useState(0),[x,f]=g.useState({}),[p]=b.useForm(),[I,S]=g.useState(!1),[w,v]=g.useState(!1),[y,R]=g.useState(null),[j]=b.useForm(),[T]=b.useForm(),C=async(D=c,q=u,K=x)=>{i(!0);try{const Z=await ls.list({...K,page:D,page_size:q});(Z.code===0||Z.code===200)&&Z.data?(l(Z.data.items),_(Z.data.total),d(Z.data.page),h(Z.data.size)):E.error(Z.message||"获取敏感词列表失败")}catch(Z){E.error(Z.message||"获取敏感词列表失败")}finally{i(!1)}};g.useEffect(()=>{C(1,u,x)},[]);const F=D=>{const q={tenant_id:D.tenant_id,status:D.status,level:D.level,keyword:D.keyword};f(q),C(1,u,q)},P=()=>{R(null),j.resetFields(),j.setFieldsValue({level:"medium",status:"active"}),S(!0)},V=D=>{R(D),j.setFieldsValue({tenant_id:D.tenant_id??void 0,word:D.word,level:D.level,replacement:D.replacement,status:D.status}),S(!0)},X=async()=>{try{const D=await j.validateFields(),q={tenant_id:D.tenant_id||void 0,word:D.word,level:D.level,replacement:D.replacement,status:D.status},K=y?await ls.update(y.id,q):await ls.create(q);K.code===0||K.code===200?(E.success(y?"敏感词已更新":"敏感词已创建"),S(!1),C()):E.error(K.message||"操作失败")}catch(D){if(D!=null&&D.errorFields)return;E.error(D.message||"操作失败")}},_e=()=>{T.resetFields(),T.setFieldsValue({level:"medium",status:"active"}),v(!0)},B=D=>D.split(/[\n,,]/).map(q=>q.trim()).filter(Boolean),te=async()=>{var D,q;try{const K=await T.validateFields(),Z=B(K.words||"");if(Z.length===0){E.error("请输入敏感词列表");return}const me=await ls.import({tenant_id:K.tenant_id||void 0,words:Z,level:K.level,replacement:K.replacement,status:K.status});if(me.code===0||me.code===200){const he=((D=me.data)==null?void 0:D.created)??0,we=((q=me.data)==null?void 0:q.skipped)??0;E.success(`敏感词已导入,新增 ${he},跳过 ${we}`),v(!1),C()}else E.error(me.message||"导入失败")}catch(K){if(K!=null&&K.errorFields)return;E.error(K.message||"导入失败")}},J=async()=>{try{await ls.export(x),E.success("导出成功")}catch(D){E.error(D.message||"导出失败")}},G=g.useRef(null),se=()=>{var D;(D=G.current)==null||D.click()},Q=async D=>{var me;const q=(me=D.target.files)==null?void 0:me[0];if(!q)return;D.target.value="";const Z=(await q.text()).split(/[\n\r]+/).map(ie=>{var we;return(we=ie.split(",")[0])==null?void 0:we.trim().replace(/^"|"$/g,"")}).filter(ie=>ie&&ie!=="敏感词");if(Z.length===0){E.error("文件中未找到有效敏感词");return}T.resetFields(),T.setFieldsValue({level:"medium",status:"active",words:Z.join(` +`)}),v(!0)},de=D=>{Me.confirm({title:"确认删除该敏感词?",okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const q=await ls.delete(D.id);q.code===0||q.code===200?(E.success("敏感词已删除"),C()):E.error(q.message||"删除失败")}catch(q){E.error(q.message||"删除失败")}}})},k=D=>D==="high"?a.jsx(Te,{color:"red",children:"高"}):D==="low"?a.jsx(Te,{color:"blue",children:"低"}):a.jsx(Te,{color:"orange",children:"中"}),W=D=>D==="active"?a.jsx(Te,{color:"green",children:"启用"}):a.jsx(Te,{color:"red",children:"禁用"}),z=[{title:"ID",dataIndex:"id",width:80},...r?[{title:"私域",dataIndex:"tenant_id",width:180,render:D=>n(D)}]:[],{title:"敏感词",dataIndex:"word",width:180},{title:"等级",dataIndex:"level",width:100,render:D=>k(D)},{title:"替换词",dataIndex:"replacement",width:160,render:D=>D||"--"},{title:"状态",dataIndex:"status",width:100,render:D=>W(D)},{title:"创建时间",dataIndex:"created_at",width:180,render:D=>Ke(D)},{title:"操作",key:"actions",width:160,render:(D,q)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>V(q),children:"编辑"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>de(q),children:"删除"})]})}];return a.jsxs("div",{className:"admin-sensitive-words",children:[a.jsx(be,{className:"admin-sensitive-words-filter",children:a.jsxs(b,{form:p,layout:"inline",onFinish:F,children:[r&&a.jsx(b.Item,{label:"私域",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,placeholder:"请选择私域",style:{width:200}})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:Vo,style:{width:120}})}),a.jsx(b.Item,{label:"等级",name:"level",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:Ho,style:{width:120}})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"敏感词",allowClear:!0})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>p.resetFields(),children:"重置"}),a.jsx(Y,{onClick:P,children:"新增敏感词"}),a.jsx(Y,{onClick:_e,children:"批量导入"}),a.jsx(Y,{icon:a.jsx(Iu,{}),onClick:se,children:"文件导入"}),a.jsx(Y,{icon:a.jsx($r,{}),onClick:J,children:"批量导出"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:z,dataSource:o,loading:s,scroll:{x:1200},pagination:{current:c,pageSize:u,total:m,showSizeChanger:!0,onChange:(D,q)=>{d(D),h(q),C(D,q)}}})}),a.jsx(Me,{title:y?"编辑敏感词":"新增敏感词",open:I,onCancel:()=>S(!1),onOk:X,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:j,layout:"vertical",children:[r&&a.jsx(b.Item,{label:"私域",name:"tenant_id",rules:[{required:!0,message:"请选择私域"}],children:a.jsx(ot,{placeholder:"请选择私域",style:{width:"100%"}})}),a.jsx(b.Item,{label:"敏感词",name:"word",rules:[{required:!0,message:"请输入敏感词"}],children:a.jsx(ve,{placeholder:"敏感词"})}),a.jsx(b.Item,{label:"等级",name:"level",children:a.jsx($e,{options:Ho})}),a.jsx(b.Item,{label:"替换词",name:"replacement",children:a.jsx(ve,{placeholder:"可选替换词"})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{options:Vo})})]})}),a.jsx(Me,{title:"批量导入敏感词",open:w,onCancel:()=>v(!1),onOk:te,okText:"导入",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:T,layout:"vertical",children:[r&&a.jsx(b.Item,{label:"私域",name:"tenant_id",rules:[{required:!0,message:"请选择私域"}],children:a.jsx(ot,{placeholder:"请选择私域",style:{width:"100%"}})}),a.jsx(b.Item,{label:"等级",name:"level",children:a.jsx($e,{options:Ho})}),a.jsx(b.Item,{label:"替换词",name:"replacement",children:a.jsx(ve,{placeholder:"可选替换词"})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{options:Vo})}),a.jsx(b.Item,{label:"敏感词列表",name:"words",rules:[{required:!0,message:"请输入敏感词列表"}],children:a.jsx(ve.TextArea,{placeholder:"一行一个词,或使用英文逗号分隔",rows:5})})]})}),a.jsx("input",{ref:G,type:"file",accept:".txt,.csv",style:{display:"none"},onChange:Q})]})},tj=[{label:"群主",value:"owner"},{label:"管理员",value:"admin"},{label:"成员",value:"member"}],rj=()=>{const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),[n]=b.useForm(),[s,i]=g.useState(!1),[o,l]=g.useState([]),[c,d]=g.useState(1),[u,h]=g.useState(20),[m,_]=g.useState(0),[x,f]=g.useState(null),[p,I]=g.useState({}),S=async(C=c,F=u,P=p,V=x)=>{if(!V){l([]),_(0);return}i(!0);try{const X=await Xa.list(V,{...P,page:C,page_size:F});(X.code===0||X.code===200)&&X.data?(l(X.data.list),_(X.data.total),d(C),h(F)):E.error(X.message||"获取群成员列表失败")}catch(X){E.error(X.message||"获取群成员列表失败")}finally{i(!1)}};g.useEffect(()=>{x&&S(1,u,p,x)},[]);const w=async C=>{const F={keyword:C.keyword,role:C.role};if(r){if(!C.group_id){E.error("请输入群组 ID");return}f(C.group_id),I(F),S(1,u,F,C.group_id)}else{if(!C.group_code){E.error("请输入群号");return}try{const P=await Wn.list({group_code:C.group_code,page:1,page_size:1});if((P.code===0||P.code===200)&&P.data&&P.data.items&&P.data.items.length>0){const X=P.data.items[0].id;f(X),I(F),S(1,u,F,X)}else E.error("未找到该群号")}catch{E.error("查询群组失败")}}},v=C=>{if(!x){E.error("请先查询群组");return}Me.confirm({title:"确认踢出该成员?",okText:"踢出",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const F=await Xa.kick(x,C.user_id);F.code===0||F.code===200?(E.success("成员已踢出"),S()):E.error(F.message||"踢出失败")}catch(F){E.error(F.message||"踢出失败")}}})},y=C=>{if(!x){E.error("请先查询群组");return}Me.confirm({title:"确认禁言该成员?",content:`将永久禁言 ${C.nickname||C.username},直到手动解除。`,okText:"禁言",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const F=await Xa.mute(x,C.user_id);F.code===0||F.code===200?(E.success("成员已禁言"),S()):E.error(F.message||"禁言失败")}catch(F){E.error(F.message||"禁言失败")}}})},R=async C=>{if(!x){E.error("请先查询群组");return}try{const F=await Xa.unmute(x,C.user_id);F.code===0||F.code===200?(E.success("禁言已解除"),S()):E.error(F.message||"解除禁言失败")}catch(F){E.error(F.message||"解除禁言失败")}},j=C=>C==="owner"?a.jsx(Te,{color:"gold",children:"群主"}):C==="admin"?a.jsx(Te,{color:"blue",children:"管理员"}):a.jsx(Te,{children:"成员"}),T=[...r?[{title:"用户 ID",dataIndex:"user_id",width:100}]:[{title:"编号",dataIndex:"user_no",width:100}],{title:"用户名",dataIndex:"username",width:160},{title:"昵称",dataIndex:"nickname",width:160,render:(C,F)=>C||F.username},{title:"群昵称",dataIndex:"nickname_in_group",width:160,render:C=>C||"--"},{title:"角色",dataIndex:"role",width:120,render:C=>j(C)},{title:"禁言状态",dataIndex:"is_muted",width:120,render:C=>a.jsx(Te,{color:C?"red":"green",children:C?"禁言中":"正常"})},{title:"加入时间",dataIndex:"joined_at",width:180,render:C=>Ke(C)},{title:"操作",key:"actions",width:200,render:(C,F)=>{const P=F.role==="owner";return a.jsxs(Ie,{children:[F.is_muted?a.jsx(Y,{size:"small",disabled:P,onClick:()=>R(F),children:"解除禁言"}):a.jsx(Y,{size:"small",disabled:P,onClick:()=>y(F),children:"禁言"}),a.jsx(Y,{size:"small",danger:!0,disabled:P,onClick:()=>v(F),children:"踢出"})]})}}];return a.jsxs("div",{className:"admin-group-members",children:[a.jsx(be,{className:"admin-group-members-filter",children:a.jsxs(b,{form:n,layout:"inline",onFinish:w,children:[r?a.jsx(b.Item,{label:"群组 ID",name:"group_id",rules:[{required:!0,message:"请输入群组 ID"}],children:a.jsx(at,{placeholder:"必填",min:1})}):a.jsx(b.Item,{label:"群号",name:"group_code",rules:[{required:!0,message:"请输入群号"}],children:a.jsx(ve,{placeholder:"必填",allowClear:!0,style:{width:140}})}),a.jsx(b.Item,{label:"角色",name:"role",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:tj,style:{width:120}})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"用户名/昵称",allowClear:!0})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>n.resetFields(),children:"重置"}),a.jsx(Y,{onClick:()=>S(),children:"刷新"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"user_id",columns:T,dataSource:o,loading:s,scroll:{x:1200},pagination:{current:c,pageSize:u,total:m,showSizeChanger:!0,onChange:(C,F)=>{d(C),h(F),S(C,F)}}})})]})},nj=[{label:"活跃",value:"active"},{label:"排空中",value:"draining"},{label:"已禁用",value:"disabled"}],sj={active:"green",draining:"orange",disabled:"red"},aj={active:"活跃",draining:"排空中",disabled:"已禁用"},ij=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(1),[o,l]=g.useState(20),[c,d]=g.useState(0),[u,h]=g.useState(!1),[m,_]=g.useState(null),[x]=b.useForm(),f=async(y=s,R=o)=>{t(!0);try{const j=await On.list({page:y,page_size:R});if((j.code===0||j.code===200)&&j.data){const C=(j.data.items||[]).sort((F,P)=>F.is_default===P.is_default?0:F.is_default?-1:1);n(C),d(j.data.total),i(j.data.page),l(j.data.size)}else E.error(j.message||"获取节点列表失败")}catch(j){E.error(j.message||"获取节点列表失败")}finally{t(!1)}};g.useEffect(()=>{f(1,o)},[]);const p=()=>{_(null),x.resetFields(),h(!0)},I=y=>{_(y),x.setFieldsValue({name:y.name,base_url:y.base_url,status:y.status,version:y.version}),h(!0)},S=async()=>{try{const y=await x.validateFields(),R=m?await On.update(m.id,{name:y.name,base_url:y.base_url,status:y.status,version:y.version||void 0}):await On.create({node_id:y.node_id,name:y.name,base_url:y.base_url,version:y.version||void 0});R.code===0||R.code===200?(E.success(m?"节点已更新":"节点已创建"),h(!1),f()):E.error(R.message||"操作失败")}catch(y){if(y!=null&&y.errorFields)return;E.error(y.message||"操作失败")}},w=y=>{Me.confirm({title:"确认删除该节点?",content:y.tenant_count>0?"该节点下仍有绑定的租户,请先解绑后再删除。":"删除后将无法恢复,请谨慎操作。",okText:"删除",okButtonProps:{danger:!0,disabled:y.tenant_count>0},cancelText:"取消",onOk:async()=>{try{const R=await On.delete(y.id);R.code===0||R.code===200?(E.success("节点已删除"),f()):E.error(R.message||"删除失败")}catch(R){E.error(R.message||"删除失败")}}})},v=[{title:"ID",dataIndex:"id",width:60},{title:"节点 ID",dataIndex:"node_id",width:140},{title:"名称",dataIndex:"name",width:140},{title:"Base URL",dataIndex:"base_url",width:200},{title:"版本",dataIndex:"version",width:100},{title:"状态",dataIndex:"status",width:100,render:y=>a.jsx(Te,{color:sj[y]||"default",children:aj[y]||y})},{title:"绑定租户数",dataIndex:"tenant_count",width:110},{title:"默认节点",dataIndex:"is_default",width:100,render:y=>y?a.jsx(Te,{color:"blue",children:"默认"}):"-"},{title:"最后心跳",dataIndex:"last_heartbeat_at",width:170,render:y=>y?Ke(y):"-"},{title:"创建时间",dataIndex:"created_at",width:170,render:y=>Ke(y)},{title:"操作",key:"actions",width:160,render:(y,R)=>R.is_default?a.jsx(Te,{children:"中心节点(不可操作)"}):a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>I(R),children:"编辑"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>w(R),children:"删除"})]})}];return a.jsxs(a.Fragment,{children:[a.jsx(be,{className:"admin-nodes-filter",children:a.jsxs(b,{layout:"inline",children:[a.jsx(b.Item,{children:a.jsx(Y,{type:"primary",onClick:p,children:"创建节点"})}),a.jsx(b.Item,{children:a.jsx(Y,{onClick:()=>f(1,o),children:"刷新"})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:v,dataSource:r,loading:e,scroll:{x:1400},pagination:{current:s,pageSize:o,total:c,showSizeChanger:!0,onChange:(y,R)=>{i(y),l(R),f(y,R)}}})}),a.jsx(Me,{title:m?"编辑节点":"创建节点",open:u,onCancel:()=>h(!1),onOk:S,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:x,layout:"vertical",children:[!m&&a.jsx(b.Item,{label:"节点 ID",name:"node_id",rules:[{required:!0,message:"请输入节点 ID"}],children:a.jsx(ve,{placeholder:"如 node-01"})}),a.jsx(b.Item,{label:"节点名称",name:"name",rules:[{required:!0,message:"请输入节点名称"}],children:a.jsx(ve,{placeholder:"如 华东节点"})}),a.jsx(b.Item,{label:"Base URL",name:"base_url",rules:[{required:!0,message:"请输入 Base URL"}],children:a.jsx(ve,{placeholder:"如 https://node-01.example.com"})}),m&&a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{options:nj})}),a.jsx(b.Item,{label:"版本",name:"version",children:a.jsx(ve,{placeholder:"可选,如 v1.0.0"})})]})})]})},oj=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(1),[o,l]=g.useState(20),[c,d]=g.useState(0),u=async(m=s,_=o)=>{t(!0);try{const x=await On.cpAuditLogs({page:m,page_size:_});(x.code===0||x.code===200)&&x.data?(n(x.data.items||[]),d(x.data.total),i(x.data.page),l(x.data.size)):E.error(x.message||"获取审计日志失败")}catch(x){E.error(x.message||"获取审计日志失败")}finally{t(!1)}};g.useEffect(()=>{u(1,o)},[]);const h=[{title:"ID",dataIndex:"id",width:60},{title:"操作人",dataIndex:"operator_name",width:120},{title:"操作",dataIndex:"action",width:140},{title:"目标类型",dataIndex:"target_type",width:120},{title:"目标 ID",dataIndex:"target_id",width:140},{title:"备注",key:"reason",width:200,render:(m,_)=>{var x;return((x=_.meta)==null?void 0:x.reason)||"-"}},{title:"时间",dataIndex:"created_at",width:170,render:m=>Ke(m)}];return a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:h,dataSource:r,loading:e,scroll:{x:900},pagination:{current:s,pageSize:o,total:c,showSizeChanger:!0,onChange:(m,_)=>{i(m),l(_),u(m,_)}}})})},lj=()=>{const e=[{key:"nodes",label:"节点管理",children:a.jsx(ij,{})},{key:"audit",label:"控制台操作日志",children:a.jsx(oj,{})}];return a.jsx("div",{className:"admin-nodes",children:a.jsx(be,{className:"admin-nodes-tabs",children:a.jsx(zi,{items:e})})})},{Text:xs}=Cr,tu=[{label:"成员加入",value:"member_joined"},{label:"成员退出",value:"member_left"},{label:"成员踢出",value:"member_kicked"},{label:"注销退出",value:"member_deactivated"},{label:"成员邀请",value:"member_invited"},{label:"成员禁言",value:"member_muted"},{label:"成员解禁",value:"member_unmuted"},{label:"设置管理员",value:"admin_set"},{label:"撤销管理员",value:"admin_removed"},{label:"转让群主",value:"owner_transfer"},{label:"全体禁言",value:"all_mute"},{label:"入群验证",value:"join_verify"},{label:"群私聊",value:"private_chat"},{label:"成员上传权限",value:"member_upload"},{label:"成员改昵称权限",value:"member_nickname"},{label:"修改群名",value:"name_changed"},{label:"修改头像",value:"avatar_changed"},{label:"修改简介",value:"desc_changed"},{label:"发布公告",value:"announcement_set"},{label:"群创建",value:"group_created"},{label:"群解散",value:"group_dismissed"},{label:"群封禁",value:"group_banned"},{label:"群解封",value:"group_unbanned"},{label:"上传文件",value:"file_uploaded"},{label:"删除文件",value:"file_deleted"},{label:"展示身份标识",value:"show_member_role"},{label:"撤回消息",value:"message_revoked"}],cj={member_joined:"green",member_left:"orange",member_kicked:"red",member_deactivated:"magenta",member_muted:"volcano",member_unmuted:"cyan",admin_set:"blue",admin_removed:"purple",owner_transfer:"gold",all_mute:"orange",all_mute_on:"orange",all_mute_off:"orange",join_verify:"orange",join_verify_on:"orange",join_verify_off:"orange",private_chat:"orange",private_chat_on:"orange",private_chat_off:"orange",member_upload:"orange",member_nickname:"orange",group_created:"green",group_dismissed:"red",group_banned:"red",group_unbanned:"green",file_uploaded:"cyan",file_deleted:"orange",show_member_role:"orange",message_revoked:"red"},dj={all_mute_on:"全体禁言",all_mute_off:"全体禁言",join_verify_on:"入群验证",join_verify_off:"入群验证",private_chat_on:"群私聊",private_chat_off:"群私聊"},ru={on:"开启",off:"关闭"},nu=new Set(["announcement_set","desc_changed","message_revoked"]),uj={group_banned:"封禁原因",message_revoked:"消息内容"},fj=()=>{const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),[n,s]=g.useState(!1),[i,o]=g.useState([]),[l,c]=g.useState(1),[d,u]=g.useState(20),[h,m]=g.useState(0),[_,x]=g.useState({}),[f]=b.useForm(),p=async(w=l,v=d,y=_)=>{s(!0);try{const R=await p_.list({...y,page:w,page_size:v});(R.code===0||R.code===200)&&R.data?(o(R.data.items),m(R.data.total),c(R.data.page),u(R.data.size)):E.error(R.message||"获取群事件失败")}catch(R){E.error(R.message||"获取群事件失败")}finally{s(!1)}};g.useEffect(()=>{p(1,d,_)},[]);const I=w=>{const v={};r?(w.group_id&&(v.group_id=w.group_id),w.tenant_id&&(v.tenant_id=w.tenant_id),w.operator_id&&(v.operator_id=w.operator_id),w.target_user_id&&(v.target_user_id=w.target_user_id)):(w.group_code&&(v.group_code=w.group_code.trim()),w.operator_username&&(v.operator_username=w.operator_username.trim()),w.target_username&&(v.target_username=w.target_username.trim())),w.event_type&&(v.event_type=w.event_type),w.startTime&&(v.start_time=w.startTime.format("YYYY-MM-DD HH:mm:ss")),w.endTime&&(v.end_time=w.endTime.format("YYYY-MM-DD HH:mm:ss")),x(v),p(1,d,v)},S=[...r?[{title:"ID",dataIndex:"id",width:80}]:[],{title:"群名称",dataIndex:"group_name",width:160,render:(w,v)=>a.jsxs("div",{children:[a.jsx("div",{children:v.group_name||"--"}),v.group_code&&a.jsx(xs,{type:"secondary",style:{fontSize:12},children:v.group_code})]})},{title:"事件类型",dataIndex:"event_type",width:130,render:w=>{var R;const v=dj[w]||((R=tu.find(j=>j.value===w))==null?void 0:R.label)||w,y=cj[w]||"default";return a.jsx(Te,{color:y,children:v})}},{title:"操作人",dataIndex:"operator_name",width:140,render:(w,v)=>{var y;if(!v.operator_name&&!v.operator_username)return"--";if((y=v.operator_name)!=null&&y.startsWith("管理员: ")){const R=v.operator_name.slice(5);return a.jsxs("div",{children:[a.jsx(Te,{color:"blue",style:{marginRight:0},children:"管理员"}),a.jsx("div",{children:a.jsx(xs,{type:"secondary",style:{fontSize:12},children:R})})]})}return a.jsxs("div",{children:[a.jsx("div",{children:v.operator_name||v.operator_username}),v.operator_username&&v.operator_name&&a.jsx(xs,{type:"secondary",style:{fontSize:12},children:v.operator_username})]})}},{title:"目标用户",dataIndex:"target_user_name",width:140,render:(w,v)=>!v.target_user_name&&!v.target_user_username?"--":a.jsxs("div",{children:[a.jsx("div",{children:v.target_user_name||v.target_user_username}),v.target_user_username&&v.target_user_name&&a.jsx(xs,{type:"secondary",style:{fontSize:12},children:v.target_user_username})]})},{title:"可见范围",dataIndex:"visibility",width:130,render:w=>{const v=w==="全员可见"?"green":"orange";return a.jsx(Te,{color:v,children:w})}},{title:"旧值",dataIndex:"old_value",width:140,ellipsis:!0,render:(w,v)=>{if(!w)return"--";if(v.event_type==="avatar_changed")return a.jsx(Mr,{src:w,width:32,height:32,style:{objectFit:"cover",borderRadius:4}});if(nu.has(v.event_type))return a.jsx(Y,{type:"link",size:"small",style:{padding:0,height:"auto",fontSize:12},onClick:()=>{Me.info({title:"旧值",width:520,okText:"关闭",content:a.jsx("div",{style:{maxHeight:400,overflow:"auto",whiteSpace:"pre-wrap",wordBreak:"break-all"},dangerouslySetInnerHTML:{__html:w}})})},children:"查看内容"});const y=ru[w]||w;return a.jsx(Xt,{title:y,children:a.jsx(xs,{ellipsis:!0,style:{maxWidth:120},children:y})})}},{title:"新值",dataIndex:"new_value",width:140,ellipsis:!0,render:(w,v)=>{if(!w)return"--";if(v.event_type==="avatar_changed")return a.jsx(Mr,{src:w,width:32,height:32,style:{objectFit:"cover",borderRadius:4}});if(nu.has(v.event_type)){const T=v.event_type==="message_revoked"?"消息内容":"新值";return a.jsx(Y,{type:"link",size:"small",style:{padding:0,height:"auto",fontSize:12},onClick:()=>{Me.info({title:T,width:520,okText:"关闭",content:a.jsx("div",{style:{maxHeight:400,overflow:"auto",whiteSpace:"pre-wrap",wordBreak:"break-all"},dangerouslySetInnerHTML:{__html:w}})})},children:"查看内容"})}const y=uj[v.event_type],R=ru[w]||w,j=y?`${y}:${R}`:R;return a.jsx(Xt,{title:j,children:a.jsx(xs,{ellipsis:!0,style:{maxWidth:120},children:j})})}},{title:"时间",dataIndex:"created_at",width:180,render:w=>Ke(w)}];return a.jsxs("div",{className:"admin-group-events",children:[a.jsx(be,{className:"admin-group-events-filter",children:a.jsxs(b,{form:f,layout:"inline",onFinish:I,children:[r?a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"群 ID",name:"group_id",children:a.jsx(at,{placeholder:"可选",min:1})}),a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"操作人 ID",name:"operator_id",children:a.jsx(at,{placeholder:"可选",min:1})}),a.jsx(b.Item,{label:"目标用户 ID",name:"target_user_id",children:a.jsx(at,{placeholder:"可选",min:1})})]}):a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"群号",name:"group_code",children:a.jsx(ve,{placeholder:"可选",allowClear:!0,style:{width:140}})}),a.jsx(b.Item,{label:"操作人",name:"operator_username",children:a.jsx(ve,{placeholder:"用户名",allowClear:!0,style:{width:140}})}),a.jsx(b.Item,{label:"目标用户",name:"target_username",children:a.jsx(ve,{placeholder:"用户名",allowClear:!0,style:{width:140}})})]}),a.jsx(b.Item,{label:"事件类型",name:"event_type",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:tu,style:{width:140}})}),a.jsx(b.Item,{label:"开始时间",name:"startTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{label:"结束时间",name:"endTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:()=>f.resetFields(),children:"重置"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:S,dataSource:i,loading:n,scroll:{x:1100},pagination:{current:l,pageSize:d,total:h,showSizeChanger:!0,onChange:(w,v)=>{c(w),u(v),p(w,v)}}})})]})},{Text:hj}=Cr,mj=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState(!1),[s,i]=g.useState([]),[o,l]=g.useState("random"),[c,d]=g.useState(!1),[u]=b.useForm(),h=async()=>{t(!0);try{const S=await Ao.get();(S.code===0||S.code===200)&&S.data&&(i(S.data.avatars||[]),l(S.data.strategy||"random"))}catch(S){E.error(S.message||"获取头像池失败")}finally{t(!1)}};g.useEffect(()=>{h()},[]);const m=async()=>{n(!0);try{const S=await Ao.update({avatars:s,strategy:o});S.code===0||S.code===200?E.success("保存成功"):E.error(S.message||"保存失败")}catch(S){E.error(S.message||"保存失败")}finally{n(!1)}},_=async()=>{try{const S=await Ao.backfill();(S.code===0||S.code===200)&&S.data?E.success(`补齐完成,更新了 ${S.data.updated} 个用户`):E.error(S.message||"补齐失败")}catch(S){E.error(S.message||"补齐失败")}},x=(S,w)=>{i(v=>v.map(y=>y.key===S?{...y,enabled:w}:y))},f=S=>{i(w=>w.filter(v=>v.key!==S))},p=S=>{if(s.some(v=>v.key===S.key)){E.error("Key 已存在");return}i(v=>[...v,{key:S.key,url:S.url,enabled:!0,sort_order:S.sort_order??v.length}]),d(!1),u.resetFields()},I=[{title:"预览",dataIndex:"url",width:80,render:S=>a.jsx("img",{src:S,alt:"avatar",className:"avatar-preview"})},{title:"Key",dataIndex:"key",width:140},{title:"URL",dataIndex:"url",width:300,render:S=>a.jsx(hj,{ellipsis:!0,style:{maxWidth:280},children:S})},{title:"排序",dataIndex:"sort_order",width:80},{title:"启用",dataIndex:"enabled",width:80,render:(S,w)=>a.jsx(rt,{checked:S,onChange:v=>x(w.key,v)})},{title:"操作",width:80,render:(S,w)=>a.jsx(js,{title:"确认删除?",onConfirm:()=>f(w.key),children:a.jsx(Y,{type:"link",danger:!0,size:"small",children:"删除"})})}];return a.jsxs("div",{className:"admin-avatar-pool",children:[a.jsx(be,{title:"默认头像池配置",extra:a.jsxs(Ie,{children:[a.jsx($e,{value:o,onChange:l,style:{width:120},options:[{label:"随机分配",value:"random"},{label:"顺序分配",value:"sequential"}]}),a.jsx(Y,{icon:a.jsx(ua,{}),onClick:()=>d(!0),children:"添加头像"}),a.jsx(Y,{type:"primary",icon:a.jsx(Js,{}),onClick:m,loading:r,children:"保存配置"}),a.jsx(js,{title:"为所有无头像用户补齐默认头像?",onConfirm:_,children:a.jsx(Y,{icon:a.jsx(rm,{}),children:"存量补齐"})})]}),children:a.jsx(Ye,{rowKey:"key",columns:I,dataSource:s,loading:e,pagination:!1,scroll:{x:800}})}),a.jsx(Me,{title:"添加头像",open:c,onCancel:()=>d(!1),onOk:()=>u.submit(),destroyOnClose:!0,children:a.jsxs(b,{form:u,layout:"vertical",onFinish:p,children:[a.jsx(b.Item,{label:"Key",name:"key",rules:[{required:!0,message:"请输入Key"}],children:a.jsx(ve,{placeholder:"如: avatar_01"})}),a.jsx(b.Item,{label:"图片 URL",name:"url",rules:[{required:!0,message:"请输入URL"}],children:a.jsx(ve,{placeholder:"https://..."})}),a.jsx(b.Item,{label:"排序",name:"sort_order",children:a.jsx(at,{min:0,placeholder:"0"})})]})})]})},xj=()=>{const{renderTenantId:e}=Yr(),[t,r]=g.useState(!1),[n,s]=g.useState([]),[i,o]=g.useState(1),[l,c]=g.useState(20),[d,u]=g.useState(0),[h,m]=g.useState({}),[_]=b.useForm(),[x,f]=g.useState(!1),[p,I]=g.useState(null),[S]=b.useForm(),[w,v]=g.useState(!1),[y]=b.useForm(),R=async(B=i,te=l,J=h)=>{r(!0);try{const G=await $s.list({...J,page:B,page_size:te});(G.code===0||G.code===200)&&G.data?(s(G.data.items),u(G.data.total),o(G.data.page),c(G.data.size)):E.error(G.message||"获取系统会话列表失败")}catch(G){E.error(G.message||"获取系统会话列表失败")}finally{r(!1)}};g.useEffect(()=>{R(1,l,h)},[]);const j=B=>{const te={};B.tenant_id&&(te.tenant_id=B.tenant_id),B.is_official!==void 0&&B.is_official!==null&&(te.is_official=B.is_official),B.keyword&&(te.keyword=B.keyword),m(te),R(1,l,te)},T=()=>{I(null),S.resetFields(),f(!0)},C=B=>{I(B),S.setFieldsValue({system_name:B.system_name,system_avatar:B.system_avatar,is_official:B.is_official}),f(!0)},F=async()=>{try{const B=await S.validateFields();let te;p?te=await $s.update(p.id,{system_name:B.system_name,system_avatar:B.system_avatar||void 0,is_official:B.is_official}):te=await $s.create({tenant_id:B.tenant_id,system_name:B.system_name,system_avatar:B.system_avatar||void 0,is_official:B.is_official}),te.code===0||te.code===200?(E.success(p?"系统会话已更新":"系统会话已创建"),f(!1),R()):E.error(te.message||"操作失败")}catch(B){if(B!=null&&B.errorFields)return;E.error(B.message||"操作失败")}},P=B=>{Me.confirm({title:"确认删除该系统会话?",content:`将删除系统会话「${B.system_name||"系统消息"}」及其关联数据,请谨慎操作。`,okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const te=await $s.delete(B.id);te.code===0||te.code===200?(E.success("系统会话已删除"),R()):E.error(te.message||"删除失败")}catch(te){E.error(te.message||"删除失败")}}})},V=()=>{y.resetFields(),v(!0)},X=async()=>{try{const B=await y.validateFields(),te={};B.type==="text"?te.text=B.text:te.url=B.url;const J=await $s.send({tenant_id:B.tenant_id,type:B.type,content:te});(J.code===0||J.code===200)&&J.data?(E.success(`发送成功:${J.data.sent_count} 人成功,${J.data.failed_count} 人失败`),v(!1)):E.error(J.message||"发送失败")}catch(B){if(B!=null&&B.errorFields)return;E.error(B.message||"发送失败")}},_e=[{title:"ID",dataIndex:"id",width:80},{title:"租户",dataIndex:"tenant_id",width:160,render:e},{title:"系统名称",dataIndex:"system_name",width:160},{title:"官方",dataIndex:"is_official",width:80,render:B=>a.jsx(Te,{color:B?"blue":"default",children:B?"是":"否"})},{title:"用户数",dataIndex:"user_count",width:100},{title:"最后消息时间",dataIndex:"last_msg_at",width:180,render:B=>B?Ke(B):"--"},{title:"创建时间",dataIndex:"created_at",width:180,render:B=>Ke(B)},{title:"操作",key:"actions",width:160,render:(B,te)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>C(te),children:"编辑"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>P(te),children:"删除"})]})}];return a.jsxs("div",{className:"admin-sys-conv",children:[a.jsx(be,{className:"admin-sys-conv-filter",children:a.jsxs(b,{form:_,layout:"inline",onFinish:j,children:[a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"官方",name:"is_official",children:a.jsxs($e,{placeholder:"全部",allowClear:!0,style:{width:100},children:[a.jsx($e.Option,{value:!0,children:"是"}),a.jsx($e.Option,{value:!1,children:"否"})]})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"系统名称",allowClear:!0})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>_.resetFields(),children:"重置"}),a.jsx(Y,{onClick:T,children:"创建会话"}),a.jsx(Y,{onClick:V,children:"发送消息"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:_e,dataSource:n,loading:t,scroll:{x:1e3},pagination:{current:i,pageSize:l,total:d,showSizeChanger:!0,onChange:(B,te)=>{o(B),c(te),R(B,te)}}})}),a.jsx(Me,{title:p?"编辑系统会话":"创建系统会话",open:x,onCancel:()=>f(!1),onOk:F,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:S,layout:"vertical",children:[!p&&a.jsx(b.Item,{label:"租户",name:"tenant_id",rules:[{required:!0,message:"请选择租户"}],children:a.jsx(ot,{style:{width:"100%"}})}),a.jsx(b.Item,{label:"系统名称",name:"system_name",children:a.jsx(ve,{placeholder:"默认:系统消息"})}),a.jsx(b.Item,{label:"头像 URL",name:"system_avatar",children:a.jsx(ve,{placeholder:"可选"})}),a.jsx(b.Item,{label:"官方标识",name:"is_official",initialValue:!1,children:a.jsxs($e,{children:[a.jsx($e.Option,{value:!0,children:"是"}),a.jsx($e.Option,{value:!1,children:"否"})]})})]})}),a.jsx(Me,{title:"发送系统消息",open:w,onCancel:()=>v(!1),onOk:X,okText:"发送",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:y,layout:"vertical",children:[a.jsx(b.Item,{label:"租户",name:"tenant_id",rules:[{required:!0,message:"请选择租户"}],children:a.jsx(ot,{style:{width:"100%"}})}),a.jsx(b.Item,{label:"消息类型",name:"type",rules:[{required:!0,message:"请选择消息类型"}],initialValue:"text",children:a.jsxs($e,{children:[a.jsx($e.Option,{value:"text",children:"文本"}),a.jsx($e.Option,{value:"image",children:"图片"})]})}),a.jsx(b.Item,{noStyle:!0,shouldUpdate:(B,te)=>B.type!==te.type,children:({getFieldValue:B})=>B("type")==="text"?a.jsx(b.Item,{label:"文本内容",name:"text",rules:[{required:!0,message:"请输入文本内容"}],children:a.jsx(ve.TextArea,{rows:4,placeholder:"消息内容"})}):a.jsx(b.Item,{label:"图片 URL",name:"url",rules:[{required:!0,message:"请输入图片 URL"}],children:a.jsx(ve,{placeholder:"图片链接"})})})]})})]})},pj=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(!1),[o,l]=g.useState(null),[c]=b.useForm(),d=async()=>{t(!0);try{const f=await ko.list();(f.code===0||f.code===200)&&f.data?n(f.data.items||[]):E.error(f.message||"获取系统通知配置失败")}catch(f){E.error(f.message||"获取系统通知配置失败")}finally{t(!1)}};g.useEffect(()=>{d()},[]);const u=()=>{l(null),c.resetFields(),c.setFieldsValue({enabled:!0}),i(!0)},h=f=>{l(f),c.setFieldsValue({enabled:f.enabled,content:f.content}),i(!0)},m=async()=>{try{const f=await c.validateFields(),p=await ko.update({enabled:f.enabled,content:f.content.trim()});p.code===0||p.code===200?(E.success(o?"系统通知已更新":"系统通知已配置"),i(!1),d()):E.error(p.message||"操作失败")}catch(f){if(f!=null&&f.errorFields)return;E.error(f.message||"操作失败")}},_=()=>{Me.confirm({title:"确认删除系统通知配置?",content:"删除后新注册用户将不再收到「系统消息」中的欢迎通知。",okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const f=await ko.delete();f.code===0||f.code===200?(E.success("已删除"),d()):E.error(f.message||"删除失败")}catch(f){E.error(f.message||"删除失败")}}})},x=[{title:"范围",dataIndex:"scope_label",width:120,render:f=>f||"全平台"},{title:"通知内容",dataIndex:"content",ellipsis:!0},{title:"状态",dataIndex:"enabled",width:100,render:f=>a.jsx(Te,{color:f?"green":"default",children:f?"启用":"停用"})},{title:"更新时间",dataIndex:"updated_at",width:180,render:f=>f?Ke(f):"-"},{title:"操作人",dataIndex:"updated_by_name",width:120,render:f=>f||"-"},{title:"操作",key:"action",width:160,render:(f,p)=>a.jsxs(Ie,{children:[a.jsx(Y,{type:"link",size:"small",onClick:()=>h(p),children:"编辑"}),a.jsx(Y,{type:"link",size:"small",danger:!0,onClick:_,children:"删除"})]})}];return a.jsxs("div",{className:"admin-system-notices",children:[a.jsxs(be,{title:"系统通知",extra:r.length===0?a.jsx(Y,{type:"primary",onClick:u,children:"配置系统通知"}):null,children:[a.jsx("p",{className:"page-desc",children:"配置全平台统一的新用户欢迎通知。启用后,用户注册成功时将通过「系统消息」会话收到该提示文案。"}),a.jsx(Ye,{rowKey:"scope",loading:e,columns:x,dataSource:r,pagination:!1,locale:{emptyText:"暂未配置,点击右上角按钮添加"}})]}),a.jsx(Me,{title:o?"编辑系统通知":"配置系统通知",open:s,onCancel:()=>i(!1),onOk:m,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:c,layout:"vertical",initialValues:{enabled:!0},children:[a.jsx(b.Item,{name:"enabled",label:"启用",valuePropName:"checked",children:a.jsx(rt,{checkedChildren:"启用",unCheckedChildren:"停用"})}),a.jsx(b.Item,{name:"content",label:"通知内容",rules:[{required:!0,message:"请输入通知内容"},{max:500,message:"最多 500 字"}],children:a.jsx(ve.TextArea,{rows:5,placeholder:"请输入新用户注册后在「系统消息」中展示的欢迎文案",showCount:!0,maxLength:500})})]})})]})},{Text:su}=Cr,gj=[{label:"用户",value:"user"},{label:"群组",value:"group"},{label:"消息",value:"message"}],_j=[{label:"待处理",value:"pending"},{label:"已处理",value:"resolved"},{label:"已驳回",value:"rejected"}],au={pending:"orange",resolved:"green",rejected:"red"},iu={pending:"待处理",resolved:"已处理",rejected:"已驳回"},ou={user:"用户",group:"群组",message:"消息"},vj=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,{renderTenantId:r}=Yr(),[n,s]=g.useState(!1),[i,o]=g.useState([]),[l,c]=g.useState(1),[d,u]=g.useState(20),[h,m]=g.useState(0),[_,x]=g.useState({}),[f]=b.useForm(),[p,I]=g.useState(!1),[S,w]=g.useState(!1),[v,y]=g.useState(null),[R,j]=g.useState(!1),[T,C]=g.useState(null),[F]=b.useForm(),P=async(J=l,G=d,se=_)=>{s(!0);try{const Q=await Fo.list({...se,page:J,page_size:G});(Q.code===0||Q.code===200)&&Q.data?(o(Q.data.items),m(Q.data.total),c(Q.data.page),u(Q.data.size)):E.error(Q.message||"获取举报列表失败")}catch(Q){E.error(Q.message||"获取举报列表失败")}finally{s(!1)}};g.useEffect(()=>{P(1,d,_)},[]);const V=J=>{const G={};J.tenant_id&&(G.tenant_id=J.tenant_id),J.target_type&&(G.target_type=J.target_type),J.status&&(G.status=J.status),x(G),P(1,d,G)},X=async J=>{y(null),I(!0),w(!0);try{const G=await Fo.detail(J);(G.code===0||G.code===200)&&G.data?y(G.data):E.error(G.message||"获取举报详情失败")}catch(G){E.error(G.message||"获取举报详情失败")}finally{w(!1)}},_e=J=>{C(J),F.resetFields(),j(!0)},B=async()=>{if(T)try{const J=await F.validateFields(),G=await Fo.handle(T.id,{status:J.status,handle_note:J.handle_note||void 0});G.code===0||G.code===200?(E.success("举报已处理"),j(!1),P()):E.error(G.message||"处理失败")}catch(J){if(J!=null&&J.errorFields)return;E.error(J.message||"处理失败")}},te=[...t?[{title:"ID",dataIndex:"id",width:80}]:[],...t?[{title:"租户",dataIndex:"tenant_id",width:160,render:r}]:[],{title:"举报人",dataIndex:"reporter_name",width:120},{title:"目标类型",dataIndex:"target_type",width:100,render:J=>a.jsx(Te,{color:"geekblue",children:ou[J]||J})},{title:"目标名称",dataIndex:"target_name",width:140},{title:"原因",dataIndex:"reason",width:200,render:J=>a.jsx(Xt,{title:J,children:a.jsx(su,{ellipsis:!0,style:{maxWidth:180},children:J})})},{title:"状态",dataIndex:"status",width:100,render:J=>a.jsx(Te,{color:au[J]||"default",children:iu[J]||J})},{title:"处理人",dataIndex:"handler_name",width:120,render:J=>J||"--"},{title:"创建时间",dataIndex:"created_at",width:180,render:J=>Ke(J)},{title:"操作",key:"actions",width:160,render:(J,G)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>X(G.id),children:"详情"}),G.status==="pending"&&a.jsx(Y,{size:"small",type:"primary",onClick:()=>_e(G),children:"处理"})]})}];return a.jsxs("div",{className:"admin-reports",children:[a.jsx(be,{className:"admin-reports-filter",children:a.jsxs(b,{form:f,layout:"inline",onFinish:V,children:[a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"目标类型",name:"target_type",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:gj,style:{width:120}})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:_j,style:{width:120}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>f.resetFields(),children:"重置"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:te,dataSource:i,loading:n,scroll:{x:1300},pagination:{current:l,pageSize:d,total:h,showSizeChanger:!0,onChange:(J,G)=>{c(J),u(G),P(J,G)}}})}),a.jsx($i,{title:"举报详情",width:480,open:p,onClose:()=>I(!1),children:a.jsx(Mn,{spinning:S,children:v&&a.jsxs(a.Fragment,{children:[a.jsxs(je,{column:1,bordered:!0,size:"small",children:[a.jsx(je.Item,{label:"ID",children:v.id}),a.jsx(je.Item,{label:"租户 ID",children:v.tenant_id}),a.jsxs(je.Item,{label:"举报人",children:[v.reporter_name,"(ID: ",v.reporter_id,")"]}),a.jsx(je.Item,{label:"目标类型",children:a.jsx(Te,{color:"geekblue",children:ou[v.target_type]||v.target_type})}),a.jsxs(je.Item,{label:"目标名称",children:[v.target_name,"(ID: ",v.target_id,")"]}),a.jsx(je.Item,{label:"举报原因",children:v.reason}),a.jsx(je.Item,{label:"状态",children:a.jsx(Te,{color:au[v.status]||"default",children:iu[v.status]||v.status})}),a.jsx(je.Item,{label:"处理人",children:v.handler_name||"--"}),a.jsx(je.Item,{label:"处理备注",children:v.handle_note||"--"}),a.jsx(je.Item,{label:"创建时间",children:Ke(v.created_at)}),a.jsx(je.Item,{label:"更新时间",children:Ke(v.updated_at)})]}),v.evidence&&v.evidence.length>0&&a.jsxs("div",{style:{marginTop:16},children:[a.jsx(su,{strong:!0,children:"证据图片:"}),a.jsx("div",{style:{marginTop:8},children:a.jsx(Mr.PreviewGroup,{children:v.evidence.map((J,G)=>a.jsx(Mr,{src:J,className:"admin-reports-evidence-img",fallback:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mN8/+F9PQAI8wNPvd7POQAAAABJRU5ErkJggg=="},G))})})]})]})})}),a.jsx(Me,{title:"处理举报",open:R,onCancel:()=>j(!1),onOk:B,okText:"确认",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:F,layout:"vertical",children:[a.jsx(b.Item,{label:"处理结果",name:"status",rules:[{required:!0,message:"请选择处理结果"}],children:a.jsxs($e,{placeholder:"选择处理结果",children:[a.jsx($e.Option,{value:"resolved",children:"通过(已处理)"}),a.jsx($e.Option,{value:"rejected",children:"驳回"})]})}),a.jsx(b.Item,{label:"处理备注",name:"handle_note",children:a.jsx(ve.TextArea,{rows:3,placeholder:"可选备注",maxLength:500,showCount:!0})})]})})]})},lu=ks.filter(e=>e.value!=="tenant_manage"),yj=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(1),[o,l]=g.useState(20),[c,d]=g.useState(0),[u,h]=g.useState(),[m,_]=g.useState(!1),[x,f]=g.useState(null),[p]=b.useForm(),[I,S]=g.useState(!1),[w,v]=g.useState(null),[y]=b.useForm(),R=async(J,G=s,se=o)=>{const Q=J??u;if(Q){t(!0);try{const de=await cs.list({tenant_id:Q,page:G,page_size:se});(de.code===0||de.code===200)&&de.data?(n(de.data.items),d(de.data.total),i(de.data.page),l(de.data.size)):E.error(de.message||"获取租户管理员列表失败")}catch(de){E.error(de.message||"获取租户管理员列表失败")}finally{t(!1)}}},j=J=>{h(J),n([]),d(0),i(1),J&&R(J,1,o)},T=()=>{if(!u){E.warning("请先选择租户");return}f(null),p.resetFields(),p.setFieldsValue({permissions:[]}),_(!0)},C=J=>{f(J),p.setFieldsValue({nickname:J.nickname,permissions:Fs(J.permissions)}),_(!0)},F=async()=>{try{const J=await p.validateFields(),G=nc(J.permissions||[]),se=x?await cs.update(x.id,{nickname:J.nickname,permissions:G}):await cs.create({tenant_id:u,username:J.username,password:J.password,nickname:J.nickname,permissions:G});se.code===0||se.code===200?(E.success(x?"租户管理员已更新":"租户管理员已创建"),_(!1),R()):E.error(se.message||"操作失败")}catch(J){if(J!=null&&J.errorFields)return;E.error(J.message||"操作失败")}},P=async J=>{const G=J.status==="active"?"disabled":"active";try{const se=await cs.updateStatus(J.id,G);se.code===0||se.code===200?(E.success("状态已更新"),R()):E.error(se.message||"更新状态失败")}catch(se){E.error(se.message||"更新状态失败")}},V=J=>{v(J),y.resetFields(),S(!0)},X=async()=>{try{const J=await y.validateFields(),G=await cs.resetPassword(w.id,J.password);G.code===0||G.code===200?(E.success("密码已重置"),S(!1)):E.error(G.message||"重置密码失败")}catch(J){if(J!=null&&J.errorFields)return;E.error(J.message||"重置密码失败")}},_e=J=>{Me.confirm({title:"确认删除该租户管理员?",content:"删除后该管理员将无法登录后台管理本租户。",okText:"删除",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const G=await cs.delete(J.id);G.code===0||G.code===200?(E.success("租户管理员已删除"),R()):E.error(G.message||"删除失败")}catch(G){E.error(G.message||"删除失败")}}})},B=J=>{const G=Fs(J);return G.length?a.jsx(Ie,{wrap:!0,children:G.map(se=>{var de;const Q=((de=lu.find(k=>k.value===se))==null?void 0:de.label)||se;return a.jsx(Te,{color:"blue",children:Q},se)})}):"--"},te=[{title:"ID",dataIndex:"id",width:80},{title:"用户名",dataIndex:"username",width:160},{title:"昵称",dataIndex:"nickname",width:160},{title:"权限",dataIndex:"permissions",width:320,render:(J,G)=>B(G.permissions)},{title:"状态",dataIndex:"status",width:100,render:J=>a.jsx(Te,{color:J==="active"?"green":"red",children:J==="active"?"启用":"禁用"})},{title:"最近登录",dataIndex:"last_login_at",width:180,render:J=>Ke(J)},{title:"创建时间",dataIndex:"created_at",width:180,render:J=>Ke(J)},{title:"操作",key:"actions",width:300,render:(J,G)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>C(G),children:"编辑"}),a.jsx(Y,{size:"small",onClick:()=>V(G),children:"重置密码"}),a.jsx(Y,{size:"small",onClick:()=>P(G),children:G.status==="active"?"禁用":"启用"}),a.jsx(Y,{size:"small",danger:!0,onClick:()=>_e(G),children:"删除"})]})}];return a.jsxs("div",{className:"tenant-admins",children:[a.jsx(be,{className:"tenant-admins-filter",children:a.jsxs(b,{layout:"inline",children:[a.jsx(b.Item,{label:"选择租户",children:a.jsx(ot,{style:{width:240},value:u,onChange:j})}),a.jsx(b.Item,{children:a.jsx(Y,{onClick:T,disabled:!u,children:"创建租户管理员"})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:te,dataSource:r,loading:e,scroll:{x:1200},pagination:{current:s,pageSize:o,total:c,showSizeChanger:!0,onChange:(J,G)=>{i(J),l(G),R(void 0,J,G)}}})}),a.jsx(Me,{title:x?"编辑租户管理员":"创建租户管理员",open:m,onCancel:()=>_(!1),onOk:F,okText:"保存",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:p,layout:"vertical",children:[!x&&a.jsxs(a.Fragment,{children:[a.jsx(b.Item,{label:"用户名",name:"username",rules:[{required:!0,message:"请输入用户名"}],children:a.jsx(ve,{placeholder:"小写英文+数字"})}),a.jsx(b.Item,{label:"密码",name:"password",tooltip:"至少 8 位,需包含大小写字母和数字",rules:[{required:!0,message:"请输入密码"},{min:8,message:"密码至少 8 位"},{pattern:/^[\x21-\x7e]+$/,message:"只能包含英文字母、数字和英文特殊字符"},{pattern:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/,message:"必须包含大小写字母和数字"}],children:a.jsx(ve.Password,{placeholder:"请输入密码"})})]}),a.jsx(b.Item,{label:"昵称",name:"nickname",rules:[{required:!0,message:"请输入昵称"}],children:a.jsx(ve,{placeholder:"管理员昵称"})}),a.jsx(b.Item,{label:"权限",name:"permissions",rules:[{required:!0,message:"请选择权限"}],children:a.jsx(gl.Group,{options:lu})})]})}),a.jsx(Me,{title:`重置密码 - ${(w==null?void 0:w.username)||""}`,open:I,onCancel:()=>S(!1),onOk:X,okText:"确认重置",cancelText:"取消",destroyOnClose:!0,children:a.jsx(b,{form:y,layout:"vertical",children:a.jsx(b.Item,{label:"新密码",name:"password",tooltip:"至少 8 位,需包含大小写字母和数字",rules:[{required:!0,message:"请输入新密码"},{min:8,message:"密码至少 8 位"},{pattern:/^[\x21-\x7e]+$/,message:"只能包含英文字母、数字和英文特殊字符"},{pattern:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/,message:"必须包含大小写字母和数字"}],children:a.jsx(ve.Password,{placeholder:"请输入新密码"})})})})]})},wj=()=>{const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),[n,s]=g.useState(!1),[i,o]=g.useState([]),[l,c]=g.useState(1),[d,u]=g.useState(20),[h,m]=g.useState(0),[_,x]=g.useState({}),[f]=b.useForm(),p=async(v=l,y=d,R=_)=>{s(!0);try{const j=await g_.list({...R,page:v,page_size:y});(j.code===0||j.code===200)&&j.data?(o(j.data.items),m(j.data.total),c(j.data.page),u(j.data.size)):E.error(j.message||"获取管理员登录历史失败")}catch(j){E.error(j.message||"获取管理员登录历史失败")}finally{s(!1)}};g.useEffect(()=>{p(1,d,_)},[]);const I=v=>{const y={};return v.admin_id&&(y.admin_id=v.admin_id),v.startTime&&(y.start_time=v.startTime.format("YYYY-MM-DD HH:mm:ss")),v.endTime&&(y.end_time=v.endTime.format("YYYY-MM-DD HH:mm:ss")),y},S=v=>{const y=I(v);x(y),p(1,d,y)},w=[...r?[{title:"ID",dataIndex:"id",width:80}]:[],{title:"用户名",dataIndex:"username",width:160},...r?[{title:"管理员 ID",dataIndex:"admin_id",width:120},{title:"租户名称",dataIndex:"tenant_name",width:160,render:v=>v||a.jsx("span",{style:{color:"#aaa"},children:"平台管理员"})}]:[],{title:"登录时间",dataIndex:"login_time",width:180,render:v=>Ke(v)},{title:"User-Agent",dataIndex:"device_type",ellipsis:!0,render:v=>a.jsx(Te,{color:"blue",style:{maxWidth:300,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:v})},{title:"IP 地址",dataIndex:"ip",width:140}];return a.jsxs("div",{className:"admin-login-history",children:[a.jsx(be,{className:"admin-login-history-filter",children:a.jsxs(b,{form:f,layout:"inline",onFinish:S,children:[r&&a.jsx(b.Item,{label:"管理员 ID",name:"admin_id",children:a.jsx(at,{placeholder:"可选",min:1,style:{width:150}})}),a.jsx(b.Item,{label:"开始时间",name:"startTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{label:"结束时间",name:"endTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{children:a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:w,dataSource:i,loading:n,scroll:{x:r?1300:900},pagination:{current:l,pageSize:d,total:h,showSizeChanger:!0,onChange:(v,y)=>{c(v),u(y),p(v,y)}}})})]})},Sj=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,[r,n]=g.useState(!1),[s,i]=g.useState([]),[o,l]=g.useState(1),[c,d]=g.useState(20),[u,h]=g.useState(0),[m,_]=g.useState({}),[x]=b.useForm(),f=async(v=o,y=c,R=m)=>{n(!0);try{const j=await __.list({...R,page:v,page_size:y});(j.code===0||j.code===200)&&j.data?(i(j.data.items),h(j.data.total),l(j.data.page),d(j.data.size)):E.error(j.message||"获取用户登录历史失败")}catch(j){E.error(j.message||"获取用户登录历史失败")}finally{n(!1)}};g.useEffect(()=>{f(1,c,m)},[]);const p=v=>{const y={};return v.tenant_id&&(y.tenant_id=Number(v.tenant_id)),v.user_id&&(y.user_id=Number(v.user_id)),v.user_no&&(y.user_no=Number(v.user_no)),v.username&&(y.username=v.username.trim()),v.startTime&&(y.start_time=v.startTime.format("YYYY-MM-DD HH:mm:ss")),v.endTime&&(y.end_time=v.endTime.format("YYYY-MM-DD HH:mm:ss")),v.ip&&(y.ip=v.ip.trim()),y},I=v=>{const y=p(v);_(y),f(1,c,y)},S=v=>{if(v.user_status==="deleted")return;const y=v.user_status==="disabled";Me.confirm({title:y?"重新强制下线":"封禁用户",content:y?`用户「${v.username}」已封禁,确认再次撤销全部登录会话并强制下线?`:`确认封禁用户「${v.username}」?封禁后会立即撤销全部登录会话并强制下线。`,okText:y?"确认下线":"确认封禁",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{try{const R=await Lt.updateStatus(v.user_id,"disabled");R.code===0||R.code===200?E.success("用户已封禁并强制下线"):E.error(R.message||"封禁失败")}catch(R){E.error(R.message||"封禁失败")}}})},w=[...t?[{title:"ID",dataIndex:"id",width:80}]:[],...t?[{title:"所属私域",dataIndex:"tenant_name",width:160,render:(v,y)=>a.jsxs("span",{children:[y.tenant_name," (ID: ",y.tenant_id,")"]})},{title:"用户 ID",dataIndex:"user_id",width:120},{title:"用户名",dataIndex:"username",width:160}]:[{title:"用户编号",dataIndex:"user_no",width:120},{title:"用户名",dataIndex:"username",width:160}],{title:"当前状态",dataIndex:"user_status",width:100,render:v=>{const y={active:{color:"green",label:"正常"},disabled:{color:"red",label:"已封禁"},deleted:{color:"default",label:"已注销"}},R=y[v]||y.disabled;return a.jsx(Te,{color:R.color,children:R.label})}},{title:"登录时间",dataIndex:"login_time",width:180,render:v=>Ke(v)},{title:"设备类型",dataIndex:"device_type",width:100,render:v=>{const y={android:"green",ios:"blue",web:"orange"};return a.jsx(Te,{color:y[v]||"default",children:v})}},{title:"设备型号",dataIndex:"device_name",width:160,render:(v,y)=>y.device_type==="web"?y.device_model||"-":y.device_name||y.device_model||"-"},{title:"系统版本",dataIndex:"os_version",width:120,render:v=>v?a.jsx(Te,{color:"purple",children:v}):"-"},{title:"App 版本",dataIndex:"version",width:100,render:v=>v?a.jsx(Te,{color:"geekblue",children:v}):"-"},{title:"IP 地址",dataIndex:"ip",width:140},{title:"归属地",dataIndex:"location",width:120,render:v=>a.jsx(Te,{color:"green",children:v})},{title:"操作",key:"actions",fixed:"right",width:100,render:(v,y)=>a.jsx(Y,{size:"small",danger:!0,disabled:y.user_status==="deleted",onClick:()=>S(y),children:y.user_status==="disabled"?"重新下线":y.user_status==="deleted"?"已注销":"快速封禁"})}];return a.jsxs("div",{className:"user-login-history",children:[a.jsx(be,{className:"user-login-history-filter",children:a.jsxs(b,{form:x,layout:"inline",onFinish:I,children:[t&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),t?a.jsx(b.Item,{label:"用户 ID",name:"user_id",children:a.jsx(ve,{placeholder:"可选",style:{width:150}})}):a.jsx(b.Item,{label:"用户编号",name:"user_no",children:a.jsx(ve,{placeholder:"可选",style:{width:150}})}),a.jsx(b.Item,{label:"用户名",name:"username",children:a.jsx(ve,{placeholder:"可选",style:{width:150}})}),a.jsx(b.Item,{label:"开始时间",name:"startTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{label:"结束时间",name:"endTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{label:"IP",name:"ip",children:a.jsx(ve,{placeholder:"登录IP",allowClear:!0,style:{width:150}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:()=>x.resetFields(),children:"重置"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:w,dataSource:s,loading:r,scroll:{x:t?1920:1720},pagination:{current:o,pageSize:c,total:u,showSizeChanger:!0,onChange:(v,y)=>{l(v),d(y),f(v,y)}}})})]})},Tj=[{label:"当前连续天数",value:"current_streak"},{label:"历史最长天数",value:"max_streak"},{label:"累计登录天数",value:"total_login_days"}],bj=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,[r,n]=g.useState(!1),[s,i]=g.useState([]),[o,l]=g.useState(1),[c,d]=g.useState(20),[u,h]=g.useState(0),[m,_]=g.useState("current_streak"),[x,f]=g.useState({}),[p]=b.useForm(),I=async(j=o,T=c,C=x,F=m)=>{n(!0);try{const P=await y_.list({...C,order_by:F,page:j,page_size:T});(P.code===0||P.code===200)&&P.data?(i(P.data.items),h(P.data.total),l(P.data.page),d(P.data.size)):E.error(P.message||"获取登录排名失败")}catch(P){E.error(P.message||"获取登录排名失败")}finally{n(!1)}};g.useEffect(()=>{I(1,c,x,m)},[]);const S=j=>{const T={};return j.tenant_id&&(T.tenant_id=Number(j.tenant_id)),j.invite_code&&(T.invite_code=j.invite_code.trim()),j.keyword&&(T.keyword=j.keyword.trim()),T},w=j=>{const T=S(j);f(T),I(1,c,T,m)},v=j=>{_(j),I(1,c,x,j)},y=j=>j===1?a.jsx(Te,{color:"gold",children:"🥇 1"}):j===2?a.jsx(Te,{color:"silver",children:"🥈 2"}):j===3?a.jsx(Te,{color:"volcano",children:"🥉 3"}):a.jsx("span",{children:j}),R=[{title:"排名",dataIndex:"rank",width:90,render:j=>y(j)},...t?[{title:"所属私域",dataIndex:"tenant_name",width:180,render:(j,T)=>a.jsxs("span",{children:[T.tenant_name," (ID: ",T.tenant_id,")"]})}]:[{title:"用户编号",dataIndex:"user_no",width:110}],{title:"用户",dataIndex:"nickname",width:200,render:(j,T)=>a.jsxs("span",{children:[T.nickname||T.username,a.jsxs("span",{className:"login-streak-username",children:["(",T.username,")"]})]})},{title:"邀请码",dataIndex:"invite_code",width:120,render:j=>j?a.jsx(Te,{color:"blue",children:j}):"-"},{title:a.jsx(Xt,{title:"截至昨天的连续登录天数,断签立即归零",children:a.jsx("span",{children:"当前连续"})}),dataIndex:"current_streak",width:110,render:j=>a.jsxs(Te,{color:j>0?"green":"default",children:[j," 天"]})},{title:"历史最长",dataIndex:"max_streak",width:110,render:j=>a.jsxs(Te,{color:"geekblue",children:[j," 天"]})},{title:"累计登录",dataIndex:"total_login_days",width:110,render:j=>a.jsxs("span",{children:[j," 天"]})},{title:"最近登录日",dataIndex:"last_login_day",width:130,render:j=>j||"-"},{title:"状态",dataIndex:"user_status",width:90,render:j=>{const T={active:{color:"green",label:"正常"},disabled:{color:"red",label:"已封禁"},deleted:{color:"default",label:"已注销"}},C=T[j]||T.disabled;return a.jsx(Te,{color:C.color,children:C.label})}}];return a.jsxs("div",{className:"login-streak-ranking",children:[a.jsx(be,{className:"login-streak-ranking-filter",children:a.jsxs(b,{form:p,layout:"inline",onFinish:w,children:[t&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"邀请码",name:"invite_code",children:a.jsx(ve,{placeholder:"按团队邀请码",allowClear:!0,style:{width:150}})}),a.jsx(b.Item,{label:"用户",name:"keyword",children:a.jsx(ve,{placeholder:"用户名/昵称",allowClear:!0,style:{width:160}})}),a.jsx(b.Item,{label:"排序",children:a.jsx($e,{value:m,onChange:v,options:Tj,style:{width:150}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:()=>p.resetFields(),children:"重置"})]})})]})}),a.jsx(be,{title:a.jsxs("span",{children:[a.jsx(bu,{style:{color:"#faad14",marginRight:8}}),"连续登录排行榜"]}),extra:a.jsx("span",{className:"login-streak-ranking-hint",children:"每日 00:05 更新(统计截至昨天)"}),children:a.jsx(Ye,{rowKey:"user_id",columns:R,dataSource:s,loading:r,scroll:{x:t?1300:1200},pagination:{current:o,pageSize:c,total:u,showSizeChanger:!0,showTotal:j=>`共 ${j} 人`,onChange:(j,T)=>{l(j),d(T),I(j,T)}}})})]})},Ej=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,[r,n]=g.useState(!1),[s,i]=g.useState([]),[o,l]=g.useState(1),[c,d]=g.useState(20),[u,h]=g.useState(0),[m,_]=g.useState({}),[x]=b.useForm(),f=async(y=o,R=c,j=m)=>{n(!0);try{const T=await w_.list({...j,page:y,page_size:R});(T.code===0||T.code===200)&&T.data?(i(T.data.items),h(T.data.total),l(T.data.page),d(T.data.size)):E.error(T.message||"获取单聊消息排名失败")}catch(T){E.error(T.message||"获取单聊消息排名失败")}finally{n(!1)}};g.useEffect(()=>{f(1,c,m)},[]);const p=y=>{const R={};return y.tenant_id&&(R.tenant_id=Number(y.tenant_id)),y.invite_code&&(R.invite_code=y.invite_code.trim()),y.keyword&&(R.keyword=y.keyword.trim()),R},I=y=>{const R=p(y);_(R),f(1,c,R)},S=y=>y===1?a.jsx(Te,{color:"gold",children:"🥇 1"}):y===2?a.jsx(Te,{color:"silver",children:"🥈 2"}):y===3?a.jsx(Te,{color:"volcano",children:"🥉 3"}):a.jsx("span",{children:y}),w=(y,R,j)=>a.jsxs("span",{children:[y||R,a.jsxs("span",{className:"private-msg-username",children:["(",R,")"]}),j?a.jsx(Te,{color:"blue",style:{marginLeft:6},children:j}):null]}),v=[{title:"排名",dataIndex:"rank",width:80,render:y=>S(y)},...t?[{title:"所属私域",dataIndex:"tenant_name",width:160,render:(y,R)=>a.jsxs("span",{children:[R.tenant_name," (ID: ",R.tenant_id,")"]})}]:[],{title:"会话",dataIndex:"conversation_id",width:110,render:y=>a.jsxs("span",{children:["#",y]})},{title:"用户 A",dataIndex:"user_a_id",width:220,render:(y,R)=>w(R.user_a_nickname,R.user_a_username,R.invite_code_a)},{title:"A 发送",dataIndex:"count_a",width:100,align:"center",render:y=>a.jsxs(Te,{color:"geekblue",children:[y," 条"]})},{title:"用户 B",dataIndex:"user_b_id",width:220,render:(y,R)=>w(R.user_b_nickname,R.user_b_username,R.invite_code_b)},{title:"B 发送",dataIndex:"count_b",width:100,align:"center",render:y=>a.jsxs(Te,{color:"purple",children:[y," 条"]})},{title:"会话总数",dataIndex:"total_count",width:120,align:"center",render:y=>a.jsxs(Te,{color:"green",children:[y," 条"]})},{title:"最近发言",dataIndex:"last_msg_at",width:180,render:y=>y||"-"}];return a.jsxs("div",{className:"private-msg-ranking",children:[a.jsx(be,{className:"private-msg-ranking-filter",children:a.jsxs(b,{form:x,layout:"inline",onFinish:I,children:[t&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"邀请码",name:"invite_code",children:a.jsx(ve,{placeholder:"按团队邀请码",allowClear:!0,style:{width:150}})}),a.jsx(b.Item,{label:"用户",name:"keyword",children:a.jsx(ve,{placeholder:"用户名/昵称",allowClear:!0,style:{width:160}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:()=>x.resetFields(),children:"重置"})]})})]})}),a.jsx(be,{title:a.jsxs("span",{children:[a.jsx(ci,{style:{color:"#52c41a",marginRight:8}}),"单聊消息数量排行榜"]}),extra:a.jsx("span",{className:"private-msg-ranking-hint",children:"每日 00:05 更新(含撤回/删除已剔除)"}),children:a.jsx(Ye,{rowKey:"conversation_id",columns:v,dataSource:s,loading:r,scroll:{x:t?1400:1250},pagination:{current:o,pageSize:c,total:u,showSizeChanger:!0,showTotal:y=>`共 ${y} 个会话`,onChange:(y,R)=>{l(y),d(R),f(y,R)}}})})]})},jj=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState(null),[s,i]=g.useState(!1),[o]=b.useForm(),l=async c=>{const d=(c.keyword||"").trim();if(!c.tenant_id){E.warning("请选择租户");return}if(!d){E.warning("请输入用户名或手机号");return}t(!0),i(!0);try{const u=await S_.lookup({tenant_id:Number(c.tenant_id),keyword:d});(u.code===0||u.code===200)&&u.data?n(u.data):(n(null),E.error(u.message||"查询失败"))}catch(u){n(null),E.error(u.message||"查询失败")}finally{t(!1)}};return a.jsxs("div",{className:"user-password-query",children:[a.jsx(be,{className:"user-password-query-filter",children:a.jsxs(b,{form:o,layout:"inline",onFinish:l,children:[a.jsx(b.Item,{label:"租户",name:"tenant_id",rules:[{required:!0,message:"请选择租户"}],children:a.jsx(ot,{style:{width:220}})}),a.jsx(b.Item,{label:"用户",name:"keyword",rules:[{required:!0,message:"请输入用户名或手机号"}],children:a.jsx(ve,{placeholder:"用户名或手机号",allowClear:!0,style:{width:220}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),loading:e,children:"查询"}),a.jsx(Y,{onClick:()=>{o.resetFields(),n(null),i(!1)},children:"重置"})]})})]})}),a.jsxs(be,{title:a.jsxs("span",{children:[a.jsx(xi,{style:{color:"#1677ff",marginRight:8}}),"查询结果"]}),children:[!s&&a.jsx("div",{className:"user-password-query-empty",children:"请选择租户并输入用户名或手机号后查询"}),s&&!r&&!e&&a.jsx("div",{className:"user-password-query-empty",children:"未查到对应用户"}),r&&a.jsxs(je,{bordered:!0,column:1,size:"middle",children:[a.jsxs(je.Item,{label:"所属私域",children:[r.tenant_name,"(ID: ",r.tenant_id,")"]}),a.jsx(je.Item,{label:"用户编号",children:r.user_no||"-"}),a.jsx(je.Item,{label:"用户名",children:r.username}),a.jsx(je.Item,{label:"昵称",children:r.nickname||"-"}),a.jsx(je.Item,{label:"手机号",children:r.phone||"-"}),a.jsx(je.Item,{label:"密码",children:r.password?a.jsx(Te,{color:"blue",className:"user-password-value",children:r.password}):a.jsx("span",{className:"user-password-missing",children:"未记录该密码"})})]})]})]})},Ij=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(1),[o,l]=g.useState(20),[c,d]=g.useState(0),[u,h]=g.useState({}),[m,_]=g.useState("updated_at"),[x]=b.useForm(),f=async(w=s,v=o,y=u,R=m)=>{t(!0);try{const j=await ps.listAlerts({...y,sort_by:R,page:w,page_size:v});(j.code===0||j.code===200)&&j.data?(n(j.data.items),d(j.data.total),i(j.data.page),l(j.data.size)):E.error(j.message||"获取预警记录失败")}catch(j){E.error(j.message||"获取预警记录失败")}finally{t(!1)}};g.useEffect(()=>{f(1,o,u,m)},[]);const p=w=>{const v={};w.tenant_id&&(v.tenant_id=Number(w.tenant_id)),w.keyword&&(v.keyword=w.keyword.trim()),w.conversation_id&&(v.conversation_id=Number(w.conversation_id)),h(v),f(1,o,v,m)},I=(w,v)=>a.jsxs("span",{children:[w||v,a.jsxs("span",{className:"keyword-alert-username",children:["(",v,")"]})]}),S=[{title:"会话",dataIndex:"conversation_id",width:100,render:w=>`#${w}`},{title:"所属私域",dataIndex:"tenant_name",width:160,render:(w,v)=>`${v.tenant_name}(ID:${v.tenant_id})`},{title:"用户 A",dataIndex:"user_a_id",width:200,render:(w,v)=>I(v.user_a_nickname,v.user_a_username)},{title:"用户 B",dataIndex:"user_b_id",width:200,render:(w,v)=>I(v.user_b_nickname,v.user_b_username)},{title:"关键词",dataIndex:"keyword",width:140,render:w=>a.jsx(Te,{color:"red",children:w})},{title:"出现次数",dataIndex:"hit_count",width:110,align:"center",render:w=>a.jsxs(Te,{color:"volcano",children:[w," 次"]})},{title:"最后更新时间",dataIndex:"updated_at",width:180}];return a.jsxs(a.Fragment,{children:[a.jsx(be,{className:"keyword-alert-filter",children:a.jsxs(b,{form:x,layout:"inline",onFinish:p,children:[a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"按关键词",allowClear:!0,style:{width:150}})}),a.jsx(b.Item,{label:"会话ID",name:"conversation_id",children:a.jsx(at,{placeholder:"会话ID",style:{width:140}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:()=>x.resetFields(),children:"重置"})]})})]})}),a.jsx(be,{title:a.jsxs("span",{children:[a.jsx(Su,{style:{color:"#cf1322",marginRight:8}}),"单聊关键词预警"]}),extra:a.jsxs(Ie,{children:[a.jsx("span",{className:"keyword-alert-hint",children:"排序"}),a.jsx(Y,{size:"small",type:m==="updated_at"?"primary":"default",onClick:()=>{_("updated_at"),f(1,o,u,"updated_at")},children:"最近更新"}),a.jsx(Y,{size:"small",type:m==="hit_count"?"primary":"default",onClick:()=>{_("hit_count"),f(1,o,u,"hit_count")},children:"出现次数"})]}),children:a.jsx(Ye,{rowKey:"id",columns:S,dataSource:r,loading:e,scroll:{x:1200},pagination:{current:s,pageSize:o,total:c,showSizeChanger:!0,showTotal:w=>`共 ${w} 条`,onChange:(w,v)=>{i(w),l(v),f(w,v,u,m)}}})})]})},Cj=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(1),[o,l]=g.useState(20),[c,d]=g.useState(0),[u,h]=g.useState(""),[m,_]=g.useState(!1),[x,f]=g.useState(null),[p]=b.useForm(),I=async(T=s,C=o,F=u)=>{t(!0);try{const P=await ps.listKeywords({keyword:F||void 0,page:T,page_size:C});(P.code===0||P.code===200)&&P.data?(n(P.data.items),d(P.data.total),i(P.data.page),l(P.data.size)):E.error(P.message||"获取词库失败")}catch(P){E.error(P.message||"获取词库失败")}finally{t(!1)}};g.useEffect(()=>{I(1,o,"")},[]);const S=()=>{f(null),p.resetFields(),p.setFieldsValue({enabled:!0}),_(!0)},w=T=>{f(T),p.setFieldsValue({word:T.word,enabled:T.enabled}),_(!0)},v=async()=>{const T=await p.validateFields();try{if(x){const C=await ps.updateKeyword(x.id,{word:T.word.trim(),enabled:T.enabled});if(C.code===0||C.code===200)E.success("已更新");else{E.error(C.message||"更新失败");return}}else{const C=await ps.createKeyword({word:T.word.trim(),enabled:T.enabled});if(C.code===0||C.code===200)E.success("已新增");else{E.error(C.message||"新增失败");return}}_(!1),I(x?s:1,o,u)}catch(C){if(C!=null&&C.errorFields)return;E.error(C.message||"操作失败")}},y=async(T,C)=>{const F=await ps.updateKeyword(T.id,{enabled:C});F.code===0||F.code===200?(E.success(C?"已启用":"已禁用"),I(s,o,u)):E.error(F.message||"操作失败")},R=async T=>{const C=await ps.deleteKeyword(T.id);C.code===0||C.code===200?(E.success("已删除"),I(s,o,u)):E.error(C.message||"删除失败")},j=[{title:"关键词",dataIndex:"word",width:200},{title:"状态",dataIndex:"enabled",width:120,render:(T,C)=>a.jsx(rt,{checked:T,onChange:F=>y(C,F)})},{title:"创建时间",dataIndex:"created_at",width:180},{title:"操作",key:"action",width:160,render:(T,C)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>w(C),children:"编辑"}),a.jsx(js,{title:"确认删除该关键词?",onConfirm:()=>R(C),children:a.jsx(Y,{size:"small",danger:!0,children:"删除"})})]})}];return a.jsxs(a.Fragment,{children:[a.jsx(be,{className:"keyword-alert-filter",children:a.jsxs(Ie,{children:[a.jsx(ve,{placeholder:"搜索关键词",allowClear:!0,style:{width:200},value:u,onChange:T=>h(T.target.value),onPressEnter:()=>I(1,o,u)}),a.jsx(Y,{type:"primary",icon:a.jsx(Ar,{}),onClick:()=>I(1,o,u),children:"查询"}),a.jsx(Y,{icon:a.jsx(ua,{}),onClick:S,children:"新增关键词"})]})}),a.jsx(be,{title:"预警词库(全平台)",children:a.jsx(Ye,{rowKey:"id",columns:j,dataSource:r,loading:e,pagination:{current:s,pageSize:o,total:c,showSizeChanger:!0,showTotal:T=>`共 ${T} 个`,onChange:(T,C)=>{i(T),l(C),I(T,C,u)}}})}),a.jsx(Me,{title:x?"编辑关键词":"新增关键词",open:m,onOk:v,onCancel:()=>_(!1),destroyOnClose:!0,children:a.jsxs(b,{form:p,layout:"vertical",children:[a.jsx(b.Item,{label:"关键词",name:"word",rules:[{required:!0,message:"请输入关键词"}],children:a.jsx(ve,{placeholder:"请输入关键词",maxLength:200})}),a.jsx(b.Item,{label:"启用",name:"enabled",valuePropName:"checked",children:a.jsx(rt,{})})]})})]})},Aj=()=>a.jsx("div",{className:"keyword-alert",children:a.jsx(zi,{defaultActiveKey:"alerts",items:[{key:"alerts",label:"预警记录",children:a.jsx(Ij,{})},{key:"keywords",label:"预警词库",children:a.jsx(Cj,{})}]})}),kj=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState(!1),[s]=b.useForm(),i=async()=>{t(!0);try{const l=await nd.get();(l.code===0||l.code===200)&&l.data?s.setFieldsValue({api_url:l.data.api_url||"",bot_token:l.data.bot_token||"",chat_id:l.data.chat_id||"",alert_every:l.data.alert_every||5,total_login_days:l.data.total_login_days??0}):E.error(l.message||"获取配置失败")}catch(l){E.error(l.message||"获取配置失败")}finally{t(!1)}};g.useEffect(()=>{i()},[]);const o=async l=>{n(!0);try{const c=await nd.update({api_url:(l.api_url||"").trim(),bot_token:(l.bot_token||"").trim(),chat_id:(l.chat_id||"").trim(),alert_every:Number(l.alert_every)||5,total_login_days:Number(l.total_login_days)||0});c.code===0||c.code===200?(E.success("已保存"),c.data&&s.setFieldsValue({api_url:c.data.api_url,bot_token:c.data.bot_token,chat_id:c.data.chat_id,alert_every:c.data.alert_every,total_login_days:c.data.total_login_days})):E.error(c.message||"保存失败")}catch(c){E.error(c.message||"保存失败")}finally{n(!1)}};return a.jsx("div",{className:"alert-bot-config",children:a.jsx(be,{loading:e,title:a.jsxs("span",{children:[a.jsx(Tu,{style:{marginRight:8}}),"预警机器人配置"]}),extra:a.jsx("span",{className:"alert-bot-config-hint",children:"全平台一套,保存后立即生效"}),children:a.jsxs(b,{form:s,layout:"vertical",style:{maxWidth:640},onFinish:o,initialValues:{api_url:"",alert_every:5,total_login_days:0},children:[a.jsx(b.Item,{label:"通知 API 地址",name:"api_url",rules:[{required:!0,message:"请输入通知 API 地址"}],extra:"完整发送地址,如 http://127.0.0.1:8080/send(Form: tgtoken/chatid/msg)",children:a.jsx(ve,{placeholder:"http://127.0.0.1:8080/send",allowClear:!0})}),a.jsx(b.Item,{label:"TG Token",name:"bot_token",rules:[{required:!0,message:"请输入 TG Token"}],children:a.jsx(ve.Password,{placeholder:"BotFather 发放的 bot token",allowClear:!0})}),a.jsx(b.Item,{label:"Chat ID",name:"chat_id",rules:[{required:!0,message:"请输入 Chat ID"}],children:a.jsx(ve,{placeholder:"目标群 chat_id,如 -5227827060",allowClear:!0})}),a.jsx(b.Item,{label:"通知频率 alert_every",name:"alert_every",rules:[{required:!0,message:"请输入通知频率"}],extra:"关键词命中次数达到该值的倍数时推送,默认 5",children:a.jsx(at,{min:1,max:1e4,style:{width:"100%"}})}),a.jsx(b.Item,{label:"累计登录天数 total_login_days",name:"total_login_days",rules:[{required:!0,message:"请输入累计登录天数阈值"}],extra:"运营配置项;封禁用户时若其累计登录天数≥该值则机器人通知;0=关闭",children:a.jsx(at,{min:0,max:1e5,style:{width:"100%"}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Js,{}),loading:r,children:"保存"}),a.jsx(Y,{onClick:i,disabled:e||r,children:"重新加载"})]})})]})})})},Fj=e=>{const t=Math.floor(e/86400),r=Math.floor(e%86400/3600),n=Math.floor(e%3600/60);return t>0?`${t}天 ${r}小时 ${n}分钟`:r>0?`${r}小时 ${n}分钟`:`${n}分钟`},Oj=()=>{const[e,t]=g.useState(!1),[r,n]=g.useState([]),[s,i]=g.useState(""),o=g.useRef(null),l=g.useCallback(async()=>{t(!0);try{const h=await T_.getAllNodesStatus();(h.code===0||h.code===200)&&h.data?(n(h.data),!s&&h.data.length>0&&i(h.data[0].node_id)):E.error(h.message||"获取系统状态失败")}catch(h){E.error(h.message||"获取系统状态失败")}finally{t(!1)}},[s]);g.useEffect(()=>(l(),o.current=setInterval(l,3e4),()=>{o.current&&clearInterval(o.current)}),[]);const c=r.find(h=>h.node_id===s),d=h=>{var _,x,f,p;if(h.error)return a.jsx(Zs,{type:"error",message:"节点不可达",description:h.error,showIcon:!0});const m=h.db.max_open>0?Math.round(h.db.in_use/h.db.max_open*100):0;return a.jsxs(a.Fragment,{children:[a.jsxs(Es,{gutter:[16,16],style:{marginBottom:16},children:[a.jsx(Ct,{xs:24,sm:12,lg:6,children:a.jsx(be,{children:a.jsx(tn,{title:"Goroutines",value:h.go.goroutines})})}),a.jsx(Ct,{xs:24,sm:12,lg:6,children:a.jsx(be,{children:a.jsx(tn,{title:"堆内存",value:h.go.heap_alloc_mb,suffix:"MB",precision:2})})}),a.jsx(Ct,{xs:24,sm:12,lg:6,children:a.jsx(be,{children:a.jsx(tn,{title:"在线用户",value:h.ws.online_users})})}),a.jsx(Ct,{xs:24,sm:12,lg:6,children:a.jsx(be,{children:a.jsx(tn,{title:"DB 连接使用率",value:m,suffix:"%",valueStyle:{color:m>80?"#cf1322":void 0}})})})]}),a.jsxs(Es,{gutter:[16,16],children:[a.jsx(Ct,{xs:24,lg:12,children:a.jsx(be,{title:"Go 运行时",size:"small",children:a.jsxs(je,{column:2,size:"small",children:[a.jsx(je.Item,{label:"版本",children:h.go.version}),a.jsx(je.Item,{label:"运行时长",children:Fj(h.go.uptime_sec)}),a.jsx(je.Item,{label:"GC 次数",children:h.go.num_gc}),a.jsxs(je.Item,{label:"系统内存",children:[h.go.sys_mem_mb," MB"]}),a.jsx(je.Item,{label:"Goroutines",children:h.go.goroutines}),a.jsxs(je.Item,{label:"堆内存",children:[h.go.heap_alloc_mb," MB"]})]})})}),a.jsx(Ct,{xs:24,lg:12,children:a.jsxs(be,{title:"数据库连接池",size:"small",children:[a.jsx("div",{style:{marginBottom:12},children:a.jsx(sm,{percent:m,format:()=>`${h.db.in_use} / ${h.db.max_open}`,status:m>80?"exception":"active"})}),a.jsxs(je,{column:2,size:"small",children:[a.jsx(je.Item,{label:"最大连接",children:h.db.max_open}),a.jsx(je.Item,{label:"当前打开",children:h.db.open}),a.jsx(je.Item,{label:"使用中",children:h.db.in_use}),a.jsx(je.Item,{label:"空闲",children:h.db.idle}),a.jsx(je.Item,{label:"等待次数",children:h.db.wait_count})]})]})}),a.jsx(Ct,{xs:24,lg:12,children:a.jsx(be,{title:"Redis",size:"small",children:a.jsxs(je,{column:2,size:"small",children:[a.jsx(je.Item,{label:"状态",children:h.redis.connected?a.jsx(Te,{color:"green",children:"已连接"}):a.jsx(Te,{color:"red",children:"断开"})}),a.jsx(je.Item,{label:"内存用量",children:h.redis.used_memory||"N/A"}),a.jsx(je.Item,{label:"客户端连接",children:h.redis.connected_clients||"N/A"}),a.jsx(je.Item,{label:"命中率",children:h.redis.hit_rate||"N/A"}),a.jsxs(je.Item,{label:"运行天数",children:[h.redis.uptime_days||"N/A"," 天"]})]})})}),a.jsx(Ct,{xs:24,lg:12,children:a.jsx(be,{title:"WebSocket",size:"small",children:a.jsxs(je,{column:2,size:"small",children:[a.jsx(je.Item,{label:"在线用户",children:h.ws.online_users}),a.jsx(je.Item,{label:"Hub 连接数",children:h.ws.connections})]})})}),a.jsx(Ct,{xs:24,lg:12,children:a.jsx(be,{title:"OSS 存储",size:"small",children:a.jsxs(je,{column:2,size:"small",children:[a.jsx(je.Item,{label:"桶名称",children:((_=h.oss)==null?void 0:_.bucket)||"N/A"}),a.jsx(je.Item,{label:"已用空间",children:((x=h.oss)==null?void 0:x.storage_human)||"N/A"}),a.jsx(je.Item,{label:"文件数量",children:((p=(f=h.oss)==null?void 0:f.object_count)==null?void 0:p.toLocaleString())??"N/A"})]})})})]})]})},u=r.map(h=>({key:h.node_id,label:a.jsxs("span",{children:[a.jsx("span",{className:`node-badge ${h.error?"node-badge-error":"node-badge-ok"}`}),h.node_name||h.node_id]})}));return a.jsxs("div",{className:"system-status",children:[a.jsxs("div",{className:"system-status-header",children:[a.jsx("h3",{children:"系统状态"}),a.jsx(Y,{icon:a.jsx(nm,{}),loading:e,onClick:l,children:"刷新"})]}),r.length>1?a.jsx(zi,{activeKey:s,onChange:i,items:u}):r.length===1&&a.jsxs("div",{style:{marginBottom:8},children:[a.jsx(Te,{color:"blue",children:r[0].node_name||r[0].node_id}),r[0].server_time&&a.jsxs("span",{style:{color:"rgba(0,0,0,0.45)",fontSize:13},children:["服务器时间:",r[0].server_time]})]}),c&&d(c),c&&!c.error&&c.server_time&&r.length>1&&a.jsxs("div",{style:{textAlign:"right",color:"rgba(0,0,0,0.45)",fontSize:12},children:["服务器时间:",c.server_time]})]})},{Text:cu}=Cr,Rj=()=>{const{admin:e,permissions:t}=pt(),r=!!e&&!e.tenant_id&&!!(t!=null&&t.tenant_manage),[n,s]=g.useState(!1),[i,o]=g.useState(!1),[l,c]=g.useState(null),[d,u]=g.useState(),h=g.useRef(0),[m]=b.useForm(),_=async f=>{const p=++h.current;s(!0);try{const I=f?{tenant_id:f}:void 0,S=await sd.get(I);if(p!==h.current)return;(S.code===0||S.code===200)&&S.data?(c(S.data),m.setFieldsValue({max_text_length:S.data.max_text_length,max_image_size_mb:S.data.max_image_size_mb,max_file_size_mb:S.data.max_file_size_mb,max_recall_minutes:S.data.max_recall_minutes??2,enable_security_perm:S.data.enable_security_perm??!1,enable_sms_code:S.data.enable_sms_code??!0})):E.error(S.message||"获取设置失败")}catch(I){if(p!==h.current)return;E.error(I.message||"获取设置失败")}finally{p===h.current&&s(!1)}};g.useEffect(()=>{e!=null&&e.tenant_id&&_()},[e==null?void 0:e.tenant_id]);const x=async()=>{if(r&&(!d||(l==null?void 0:l.tenant_id)!==d)){E.error("请先选择租户并等待配置加载完成");return}try{const f=await m.validateFields();o(!0);const p={max_text_length:f.max_text_length,max_image_size_mb:f.max_image_size_mb,max_file_size_mb:f.max_file_size_mb,max_recall_minutes:f.max_recall_minutes,enable_sms_code:f.enable_sms_code};r&&(p.enable_security_perm=f.enable_security_perm),r&&(p.tenant_id=d);const I=await sd.update(p);I.code===0||I.code===200?E.success("设置已保存"):E.error(I.message||"保存失败")}catch(f){if(f!=null&&f.errorFields)return;E.error(f.message||"保存失败")}finally{o(!1)}};return a.jsx("div",{className:"admin-tenant-settings",children:a.jsx(be,{title:l?`私域设置 - ${l.tenant_name}`:"私域设置",children:a.jsx(Mn,{spinning:n,children:a.jsxs(b,{form:m,layout:"vertical",style:{maxWidth:480},children:[r&&a.jsx(b.Item,{label:"租户",children:a.jsx(ot,{value:d,placeholder:"请选择租户",allowClear:!0,disabled:i,style:{width:"100%"},onChange:f=>{h.current+=1,u(typeof f=="number"?f:void 0),c(null),m.resetFields(),typeof f=="number"?_(f):s(!1)}})}),a.jsx(b.Item,{label:"消息字符上限",name:"max_text_length",rules:[{required:!0,message:"请输入消息字符上限"}],extra:"范围 1~5000,仅允许调低",children:a.jsx(at,{min:1,max:5e3,style:{width:"100%"}})}),a.jsx(b.Item,{label:"图片大小上限(MB)",name:"max_image_size_mb",rules:[{required:!0,message:"请输入图片大小上限"}],extra:"范围 1~1000 MB",children:a.jsx(at,{min:1,max:1e3,style:{width:"100%"}})}),a.jsx(b.Item,{label:"文件大小上限(MB)",name:"max_file_size_mb",rules:[{required:!0,message:"请输入文件大小上限"}],extra:"范围 1~1000 MB,默认 50 MB",children:a.jsx(at,{min:1,max:1e3,style:{width:"100%"}})}),a.jsx(b.Item,{label:"最大撤回消息时间(分钟)",name:"max_recall_minutes",rules:[{required:!0,message:"请输入最大撤回消息时间"}],extra:"群主/管理员撤回自己或他人消息的最长时限,范围 1~1440 分钟;普通用户撤回自己的消息固定为 2 分钟",children:a.jsx(at,{min:1,max:1440,precision:0,style:{width:"100%"}})}),a.jsx(b.Item,{label:"是否开启手机验证码",name:"enable_sms_code",valuePropName:"checked",extra:a.jsx(cu,{type:"secondary",style:{fontSize:12},children:"关闭后,注册仅支持邀请码,短信登录与忘记密码不可用"}),children:a.jsx(rt,{checkedChildren:"开启",unCheckedChildren:"关闭"})}),r&&a.jsx(b.Item,{label:"是否开启私域安全权限",name:"enable_security_perm",valuePropName:"checked",extra:a.jsx(cu,{type:"secondary",style:{fontSize:12},children:"开启后,本企业租户管理员在用户管理页可操作「开启/关闭安全权限」;仅平台超管可修改此开关"}),children:a.jsx(rt,{checkedChildren:"开启",unCheckedChildren:"关闭"})}),a.jsx(b.Item,{children:a.jsx(Y,{type:"primary",onClick:x,loading:i,disabled:n||!l||r&&l.tenant_id!==d,children:"保存设置"})})]})})})})},Dj=()=>a.jsx(rc,{messageTypes:["image","video","audio","file"]}),{Text:Dt}=Cr,Pj=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,[r,n]=g.useState(!1),[s,i]=g.useState(!1),[o,l]=g.useState(null),[c,d]=g.useState(void 0),u=g.useRef(0),[h]=b.useForm(),m=async x=>{const f=++u.current;n(!0);try{const p=x?{tenant_id:x}:void 0,I=await pa.getSettings(p);if(f!==u.current)return;(I.code===0||I.code===200)&&I.data?(l(I.data),h.setFieldsValue({...I.data,group_message_interval_sec:I.data.group_message_interval_sec??0,allow_voice_call:I.data.allow_voice_call??!0,allow_video_call:I.data.allow_video_call??!0,show_message_read_status:I.data.show_message_read_status??!1})):E.error(I.message||"获取安全策略失败")}catch(p){if(f!==u.current)return;E.error(p.message||"获取安全策略失败")}finally{f===u.current&&n(!1)}};g.useEffect(()=>{e!=null&&e.tenant_id&&m()},[e==null?void 0:e.tenant_id]);const _=async()=>{var x,f,p;if(t&&!c){E.error("请先选择租户并加载配置后再保存");return}try{const I=await h.validateFields();t||(delete I.allow_voice_call,delete I.allow_video_call),I.group_message_interval_sec!=null&&(I.group_message_interval_sec=Number(I.group_message_interval_sec)),i(!0);const S=c?{...I,tenant_id:c}:I,w=await pa.updateSettings(S);w.code===0||w.code===200?(E.success("安全策略已保存"),await m(c)):E.error(w.message||"保存失败")}catch(I){if((x=I==null?void 0:I.errorFields)!=null&&x.length){E.error(((p=(f=I.errorFields[0])==null?void 0:f.errors)==null?void 0:p[0])||"请检查表单填写");return}E.error(I.message||"保存失败")}finally{i(!1)}};return a.jsx("div",{className:"security-settings",children:a.jsx(Mn,{spinning:r,children:a.jsxs(b,{form:h,layout:"vertical",children:[t&&a.jsx(be,{size:"small",className:"security-card",children:a.jsx(b.Item,{label:"查询租户",style:{marginBottom:0},children:a.jsx(ot,{value:c,placeholder:"请选择租户",allowClear:!0,disabled:s,style:{width:240},onChange:x=>{u.current+=1,d(typeof x=="number"?x:void 0),l(null),h.resetFields(),typeof x=="number"?m(x):n(!1)}})})}),a.jsx(be,{title:"用户安全",className:"security-card",children:a.jsxs("div",{className:"security-form-grid",children:[a.jsx(b.Item,{label:"验证码触发次数",name:"user_captcha_threshold",rules:[{required:!0,message:"请输入"}],extra:"连续密码错误该次数后要求验证码(1~10)",children:a.jsx(at,{min:1,max:10,style:{width:"100%"}})}),a.jsx(b.Item,{label:"密码最小位数",name:"password_min_length",rules:[{required:!0,message:"请输入"}],extra:"用户密码最少字符数(6~32)",children:a.jsx(at,{min:6,max:32,style:{width:"100%"}})}),a.jsxs("div",{className:"switch-row",style:{alignItems:"center",padding:"8px 0"},children:[a.jsxs("div",{children:[a.jsx("div",{children:"强制包含字母"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"开启后密码必须包含英文字母"})]}),a.jsx(b.Item,{name:"password_require_letter",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]})]})}),a.jsxs("div",{className:"security-switch-grid",children:[a.jsx(be,{title:"注册登录管控",className:"security-card",size:"small",children:a.jsxs("div",{className:"switch-list",children:[a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"用户注册功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后用户端将隐藏注册入口"})]}),a.jsx(b.Item,{name:"allow_user_register",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"修改密码功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后用户无法修改密码,不影响后台重置"})]}),a.jsx(b.Item,{name:"allow_change_password",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"用户登录功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后用户无法登录,不影响已登录用户"})]}),a.jsx(b.Item,{name:"allow_user_login",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"Web 端多端登录"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"开启后同一账号可在多个浏览器标签页同时登录"})]}),a.jsx(b.Item,{name:"allow_web_multi_session",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]})]})}),a.jsx(be,{title:"聊天消息管控",className:"security-card",size:"small",children:a.jsxs("div",{className:"switch-list",children:[a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"全局好友功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后无法搜索和添加好友"})]}),a.jsx(b.Item,{name:"allow_friend_function",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"全局群消息"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后所有群无法发送消息"})]}),a.jsx(b.Item,{name:"allow_group_message",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"全局私聊消息"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后所有私聊无法发送消息"})]}),a.jsx(b.Item,{name:"allow_private_message",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"群聊发言间隔(秒)"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"0 表示不限制;1~1000 表示同一群内两次发言的最小间隔"})]}),a.jsx(b.Item,{name:"group_message_interval_sec",initialValue:0,style:{marginBottom:0},rules:[{validator:(x,f)=>{if(f==null||f==="")return Promise.reject(new Error("请输入群聊发言间隔"));const p=Number(f);return!Number.isFinite(p)||p<0||p>1e3?Promise.reject(new Error("范围为 0~1000 秒")):Promise.resolve()}}],children:a.jsx(at,{min:0,max:1e3,precision:0,style:{width:200}})})]})]})}),a.jsx(be,{title:"群组功能管控",className:"security-card",size:"small",children:a.jsxs("div",{className:"switch-list",children:[a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"群号搜索功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后用户端隐藏群号和群搜索入口"})]}),a.jsx(b.Item,{name:"allow_group_search",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"群创建功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后任何人无法新建群聊"})]}),a.jsx(b.Item,{name:"allow_group_create",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"群解散功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后任何人无法解散群聊,不影响后台管理员"})]}),a.jsx(b.Item,{name:"allow_group_dissolve",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"群管理员功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后任何人无法设置群管理员"})]}),a.jsx(b.Item,{name:"allow_group_admin",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"是否显示群人数"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后用户端查看群资料时不显示群总人数"})]}),a.jsx(b.Item,{name:"show_group_member_count",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]})]})}),a.jsx(be,{title:"其他功能开关",className:"security-card",size:"small",children:a.jsxs("div",{className:"switch-list",children:[a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"允许用户注销账号"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后用户端将隐藏注销账号按钮"})]}),a.jsx(b.Item,{name:"allow_user_deactivate",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),t&&a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"加密推送"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"开启后消息推送内容将加密(通话推送除外)"})]}),a.jsx(b.Item,{name:"push_encrypt_enabled",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]})]})})]}),a.jsxs(be,{title:"IP 访问控制",className:"security-card security-card-call",size:"small",children:[a.jsx(b.Item,{label:"注册 IP 黑名单",name:"register_ip_blacklist",extra:"留空表示不限制;每行一个 IPv4、IPv6 或 CIDR。命中后无法注册及获取注册短信验证码。",children:a.jsx(ve.TextArea,{rows:4,placeholder:`203.0.113.10 +10.0.0.0/8`})}),a.jsx(b.Item,{label:"登录 IP 黑名单",name:"login_ip_blacklist",extra:"留空表示不限制;命中后无法密码登录、短信登录及刷新 Token。与用户分组登录白名单独立,黑名单优先。",style:{marginBottom:0},children:a.jsx(ve.TextArea,{rows:4,placeholder:"198.51.100.0/24"})})]}),a.jsx(be,{title:t?"通话与高级功能":"高级功能",className:"security-card security-card-call",size:"small",children:a.jsxs("div",{className:"switch-list",children:[t&&a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"语音通话功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后用户端隐藏语音通话按钮"})]}),a.jsx(b.Item,{name:"allow_voice_call",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"视频通话功能"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"关闭后用户端隐藏视频通话按钮"})]}),a.jsx(b.Item,{name:"allow_video_call",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]})]}),a.jsxs("div",{className:"switch-row",children:[a.jsxs("div",{children:[a.jsx("div",{children:"消息已读状态"}),a.jsx(Dt,{type:"secondary",style:{fontSize:12},children:"开启后显示消息已读/未读标记"})]}),a.jsx(b.Item,{name:"show_message_read_status",valuePropName:"checked",noStyle:!0,children:a.jsx(rt,{size:"small"})})]})]})}),t&&a.jsx(be,{title:"管理员登录安全",className:"security-card",children:a.jsxs("div",{className:"security-form-grid",children:[a.jsx(b.Item,{label:"密码错误锁定次数",name:"admin_max_login_attempts",rules:[{required:!0,message:"请输入"}],extra:"范围 2~10",children:a.jsx(at,{min:2,max:10,style:{width:"100%"}})}),a.jsx(b.Item,{label:"锁定时长(分钟)",name:"admin_lockout_duration",rules:[{required:!0,message:"请输入"}],extra:"范围 5~1440",children:a.jsx(at,{min:5,max:1440,style:{width:"100%"}})})]})}),a.jsx("div",{className:"security-save",children:a.jsx(Y,{type:"primary",size:"large",onClick:_,loading:s,disabled:r||!o,children:"保存设置"})})]})})})},Nj={password_error:{label:"密码错误",color:"red"},locked:{label:"账户锁定",color:"volcano"},disabled:{label:"账户禁用",color:"orange"},captcha_failed:{label:"验证码错误",color:"gold"},tenant_banned:{label:"私域封禁",color:"magenta"}},Lj={user:{label:"用户",color:"blue"},admin:{label:"管理员",color:"purple"}},Mj=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,[r,n]=g.useState(!1),[s,i]=g.useState([]),[o,l]=g.useState(1),[c,d]=g.useState(20),[u,h]=g.useState(0),[m,_]=g.useState({}),[x]=b.useForm(),f=async(v=o,y=c,R=m)=>{n(!0);try{const j=await pa.listFailureLogs({...R,page:v,page_size:y});(j.code===0||j.code===200)&&j.data?(i(j.data.items||[]),h(j.data.total),l(j.data.page),d(j.data.size)):E.error(j.message||"获取登录失败日志失败")}catch(j){E.error(j.message||"获取登录失败日志失败")}finally{n(!1)}};g.useEffect(()=>{f(1,c,m)},[]);const p=v=>{const y={};return v.tenant_id&&(y.tenant_id=Number(v.tenant_id)),v.target_type&&(y.target_type=v.target_type),v.login_account&&(y.login_account=v.login_account.trim()),v.ip&&(y.ip=v.ip.trim()),v.startTime&&(y.start_time=v.startTime.format("YYYY-MM-DD HH:mm:ss")),v.endTime&&(y.end_time=v.endTime.format("YYYY-MM-DD HH:mm:ss")),y},I=async v=>{try{const y=await pa.unlockAccount({tenant_id:v.tenant_id>0?v.tenant_id:void 0,target_type:v.target_type,login_account:v.login_account});y.code===0||y.code===200?E.success(`已解锁账号 ${v.login_account}`):E.error(y.message||"解锁失败")}catch(y){E.error(y.message||"解锁失败")}},S=v=>{const y=p(v);_(y),f(1,c,y)},w=[...t?[{title:"ID",dataIndex:"id",width:80}]:[],...t?[{title:"所属私域",dataIndex:"tenant_name",width:140,render:(v,y)=>y.tenant_id>0?`${v} (${y.tenant_id})`:"-"}]:[],{title:"类型",dataIndex:"target_type",width:90,render:v=>{const y=Lj[v];return y?a.jsx(Te,{color:y.color,children:y.label}):v}},{title:"登录账号",dataIndex:"login_account",width:160},{title:"失败原因",dataIndex:"failure_reason",width:120,render:v=>{const y=Nj[v];return y?a.jsx(Te,{color:y.color,children:y.label}):a.jsx(Te,{children:v})}},{title:"IP 地址",dataIndex:"ip",width:140},{title:"User-Agent",dataIndex:"user_agent",width:200,ellipsis:!0,render:v=>a.jsx(Xt,{title:v,children:a.jsx("span",{children:v})})},{title:"时间",dataIndex:"created_at",width:180,render:v=>Ke(v)},{title:"操作",key:"action",width:100,render:(v,y)=>y.failure_reason==="locked"||y.failure_reason==="password_error"?a.jsx(js,{title:"确认解锁",description:`解锁账号 ${y.login_account} 的登录锁定?`,onConfirm:()=>I(y),okText:"确认",cancelText:"取消",children:a.jsx(Y,{type:"link",size:"small",icon:a.jsx(Xo,{}),children:"解锁"})}):null}];return a.jsxs("div",{className:"login-failure-logs",children:[a.jsx(be,{className:"login-failure-logs-filter",children:a.jsxs(b,{form:x,layout:"inline",onFinish:S,children:[t&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"类型",name:"target_type",children:a.jsxs($e,{placeholder:"全部",allowClear:!0,style:{width:120},children:[a.jsx($e.Option,{value:"user",children:"用户"}),a.jsx($e.Option,{value:"admin",children:"管理员"})]})}),a.jsx(b.Item,{label:"登录账号",name:"login_account",children:a.jsx(ve,{placeholder:"可选",style:{width:150}})}),a.jsx(b.Item,{label:"IP",name:"ip",children:a.jsx(ve,{placeholder:"可选",style:{width:140}})}),a.jsx(b.Item,{label:"开始时间",name:"startTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{label:"结束时间",name:"endTime",children:a.jsx(jr,{showTime:!0,placeholder:"可选",style:{width:200}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:()=>x.resetFields(),children:"重置"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"id",columns:w,dataSource:s,loading:r,scroll:{x:t?1400:1200},pagination:{current:o,pageSize:c,total:u,showSizeChanger:!0,onChange:(v,y)=>{l(v),d(y),f(v,y)}}})})]})},{Text:Pt,Paragraph:Bj}=Cr,{TextArea:li}=ve,Uj=()=>{const[e,t]=g.useState([""]),[r,n]=g.useState(""),[s,i]=g.useState(""),[o,l]=g.useState(!1),[c,d]=g.useState(""),[u,h]=g.useState(""),[m,_]=g.useState(167),[x,f]=g.useState(""),[p,I]=g.useState(!1),[S,w]=g.useState(""),[v,y]=g.useState(167),[R,j]=g.useState(""),[T,C]=g.useState(""),[F,P]=g.useState([]),[V,X]=g.useState([]),[_e,B]=g.useState(!0),[te,J]=g.useState(!1),[G,se]=g.useState(!1),[Q,de]=g.useState(!1),[k,W]=g.useState([""]),[z,D]=g.useState(""),[q,K]=g.useState(""),[Z,me]=g.useState(null),[ie,he]=g.useState(!1);g.useEffect(()=>{we()},[]);const we=async()=>{B(!0);try{const xe=await Un.getConfig();(xe.code===0||xe.code===200)&&xe.data&&(C(xe.data.aes_key||""),P(xe.data.records||[]),X(xe.data.encrypted_records||[]),xe.data.aes_key&&(n(xe.data.aes_key),K(xe.data.aes_key)))}catch{}finally{B(!1)}},He=async(xe,ke,et)=>{J(!0);try{const _t=await Un.saveConfig({aes_key:xe,records:ke,encrypted_records:et??V});return _t.code===0||_t.code===200?(C(xe),P(ke),et&&X(et),!0):(E.error(_t.message||"保存失败"),!1)}catch(_t){return E.error((_t==null?void 0:_t.message)||"保存请求失败"),!1}finally{J(!1)}},ze=()=>{if(e.length>=10){E.warning("最多支持 10 个域名");return}t([...e,""])},gt=xe=>{e.length<=1||t(e.filter((ke,et)=>et!==xe))},qe=(xe,ke)=>{const et=[...e];et[xe]=ke.trim(),t(et)},le=()=>{const xe=new Uint8Array(32);crypto.getRandomValues(xe);const ke=Array.from(xe).map(et=>et.toString(16).padStart(2,"0")).join("");n(ke)},fe=async()=>{if(r.length!==64){E.error("密钥必须为 64 位 hex");return}await He(r,F)&&E.success("密钥已保存")},Re=()=>{const xe=e.filter(ke=>ke.length>0);if(xe.length===0){E.error("请至少输入一个域名");return}if(r.length!==64){E.error("请先设置 64 位 hex AES 密钥,用于加密推送内容");return}Me.confirm({title:"确认推送域名更新(加密)",content:`将使用 AES-256-GCM 加密后,通过极光推送向所有在线客户端下发 ${xe.length} 个域名。客户端收到后解密并切换 API 地址。确认推送?`,okText:"确认推送",cancelText:"取消",onOk:async()=>{se(!0);try{const ke=await Un.pushUpdate(xe,r);ke.code===0||ke.code===200?E.success(`已加密推送 ${xe.length} 个域名到所有客户端`):E.error(ke.message||"推送失败")}catch(ke){E.error((ke==null?void 0:ke.message)||"推送请求失败")}finally{se(!1)}}})},Ue=()=>{const xe=k.filter(ke=>ke.length>0);if(xe.length===0){E.error("请至少输入一个桶地址");return}if(r.length!==64){E.error("请先设置 64 位 hex AES 密钥,用于加密推送内容");return}Me.confirm({title:"确认推送桶地址更新(加密)",content:`将使用 AES-256-GCM 加密后,通过极光推送向所有客户端下发 ${xe.length} 个桶地址。客户端收到后解密并缓存,下次域名解析时使用新桶地址。确认推送?`,okText:"确认推送",cancelText:"取消",onOk:async()=>{de(!0);try{const ke=await Un.pushBucketUpdate(xe,r);ke.code===0||ke.code===200?E.success(`已加密推送 ${xe.length} 个桶地址到所有客户端`):E.error(ke.message||"推送失败")}catch(ke){E.error((ke==null?void 0:ke.message)||"推送请求失败")}finally{de(!1)}}})},nt=async()=>{const xe=e.filter(ke=>ke.length>0);if(xe.length===0){E.error("请至少输入一个域名");return}if(r.length!==64){E.error("密钥必须为 64 位 hex 字符串(32 字节 AES-256)");return}l(!0);try{const ke=await Un.encrypt({domains:xe,key:r});if((ke.code===0||ke.code===200)&&ke.data){i(ke.data.encrypted);const _t={domains:xe,encrypted:ke.data.encrypted,key_used:r.slice(0,8)+"..."+r.slice(-8),created_at:new Date().toLocaleString()},Wt=[...V,_t];await He(T,F,Wt)?E.success("加密成功,已自动保存记录"):E.success("加密成功")}else E.error(ke.message||"加密失败")}catch(ke){E.error((ke==null?void 0:ke.message)||"加密请求失败")}finally{l(!1)}},Tt=async()=>{if(!z.trim()){E.error("请输入加密内容");return}if(q.length!==64){E.error("密钥必须为 64 位 hex");return}he(!0);try{const xe=await Un.decrypt({encrypted:z.trim(),key:q});(xe.code===0||xe.code===200)&&xe.data?(me(xe.data.domains),E.success("解密成功")):E.error(xe.message||"解密失败")}catch(xe){E.error((xe==null?void 0:xe.message)||"解密失败:密钥不匹配或密文损坏")}finally{he(!1)}},yt=async xe=>{const ke=V.filter((_t,Wt)=>Wt!==xe);await He(T,F,ke)&&E.success("已删除")},De=async()=>{if(!c.trim()){E.error("请输入要混淆的字符串");return}I(!0);try{const xe=await Un.obfuscate({text:c.trim(),xor_key:m});(xe.code===0||xe.code===200)&&xe.data?(f(xe.data.byte_array),E.success("生成成功")):E.error(xe.message||"生成失败")}catch(xe){E.error((xe==null?void 0:xe.message)||"请求失败")}finally{I(!1)}},Ce=async()=>{if(!x){E.error("请先生成混淆结果");return}const xe={label:u.trim()||c.trim().slice(0,30),text:c.trim(),byte_array:x,xor_key:m,created_at:new Date().toLocaleString()},ke=[...F,xe];await He(T,ke)&&E.success("已保存")},Qe=async xe=>{const ke=F.filter((_t,Wt)=>Wt!==xe);await He(T,ke)&&E.success("已删除")},Xe=()=>{try{const xe=S.match(/byteArrayOf\((.+)\)/),et=(xe?xe[1]:S).split(",").map(Wt=>parseInt(Wt.trim(),10));if(et.some(isNaN)){E.error("格式错误,请输入 byteArrayOf(...) 或逗号分隔的数字");return}const _t=et.map(Wt=>String.fromCharCode(Wt&255^v&255)).join("");j(_t)}catch{E.error("解码失败")}},Je=xe=>{if(navigator.clipboard&&window.isSecureContext)navigator.clipboard.writeText(xe).then(()=>E.success("已复制到剪贴板"));else{const ke=document.createElement("textarea");ke.value=xe,ke.style.position="fixed",ke.style.opacity="0",document.body.appendChild(ke),ke.select(),document.execCommand("copy"),document.body.removeChild(ke),E.success("已复制到剪贴板")}};return _e?a.jsx("div",{style:{padding:24,textAlign:"center"},children:a.jsx(Mn,{tip:"加载配置中..."})}):a.jsxs("div",{style:{padding:24},children:[a.jsx(Zs,{message:"域名加密工具",description:"输入 API 域名列表并加密,将加密内容手动上传到阿里云 OSS / 腾讯云 COS 存储桶。App 启动时从存储桶获取并解密,按顺序检测连通性后使用。",type:"info",showIcon:!0,style:{marginBottom:16}}),a.jsxs(Es,{gutter:16,style:{marginBottom:16},align:"stretch",children:[a.jsx(Ct,{span:12,style:{display:"flex"},children:a.jsx(be,{title:a.jsxs(a.Fragment,{children:[a.jsx(xi,{style:{marginRight:8}}),"AES-256 密钥"]}),size:"small",style:{flex:1},children:a.jsxs(Ie,{direction:"vertical",style:{width:"100%"},size:"small",children:[a.jsxs(Ie.Compact,{style:{width:"100%"},children:[a.jsx(ve,{value:r,onChange:xe=>n(xe.target.value.trim()),placeholder:"64 位 hex 字符串(32 字节 AES-256-GCM 密钥)",maxLength:64,style:{fontFamily:"monospace"}}),a.jsx(Y,{onClick:le,children:"随机生成"}),a.jsx(Y,{icon:a.jsx(Js,{}),onClick:fe,loading:te,children:"保存"}),r&&a.jsx(Y,{icon:a.jsx(un,{}),onClick:()=>Je(r)})]}),T&&a.jsxs(Pt,{type:"secondary",children:["已保存: ",a.jsx(Pt,{code:!0,copyable:!0,style:{fontSize:12},children:T})]}),a.jsx(Pt,{type:"secondary",children:"此密钥需硬编码在 App 客户端中用于解密,请妥善保管"})]})})}),a.jsx(Ct,{span:12,style:{display:"flex"},children:a.jsx(be,{title:a.jsxs(a.Fragment,{children:[a.jsx(pi,{style:{marginRight:8}}),"域名列表"]}),size:"small",extra:a.jsxs(Ie,{children:[a.jsx(Y,{type:"dashed",size:"small",icon:a.jsx(ua,{}),onClick:ze,children:"添加"}),a.jsx(Y,{type:"primary",size:"small",loading:o,onClick:nt,children:"加密生成"}),a.jsx(Y,{size:"small",icon:a.jsx(uc,{}),loading:G,onClick:Re,children:"推送下发"})]}),style:{flex:1},children:a.jsxs(Ie,{direction:"vertical",style:{width:"100%"},size:"small",children:[e.map((xe,ke)=>a.jsxs(Ie,{style:{width:"100%"},children:[a.jsx(Te,{color:"blue",style:{minWidth:24,textAlign:"center"},children:ke+1}),a.jsx(ve,{value:xe,onChange:et=>qe(ke,et.target.value),placeholder:"例: api.example.com",style:{flex:1,minWidth:200}}),e.length>1&&a.jsx(Y,{icon:a.jsx(Gs,{}),danger:!0,size:"small",onClick:()=>gt(ke)})]},ke)),a.jsx(Pt,{type:"secondary",children:"App 按此顺序检测连通性,返回 HTTP 200 即使用该域名"})]})})})]}),a.jsx(be,{title:a.jsxs(a.Fragment,{children:[a.jsx(am,{style:{marginRight:8}}),"OSS 桶地址推送"]}),size:"small",extra:a.jsxs(Ie,{children:[a.jsx(Y,{type:"dashed",size:"small",icon:a.jsx(ua,{}),onClick:()=>{if(k.length>=5){E.warning("最多支持 5 个桶地址");return}W([...k,""])},children:"添加"}),a.jsx(Y,{size:"small",icon:a.jsx(uc,{}),loading:Q,onClick:Ue,children:"推送下发"})]}),style:{marginBottom:16},children:a.jsxs(Ie,{direction:"vertical",style:{width:"100%"},size:"small",children:[k.map((xe,ke)=>a.jsxs(Ie,{style:{width:"100%"},children:[a.jsx(Te,{color:"orange",style:{minWidth:24,textAlign:"center"},children:ke+1}),a.jsx(ve,{value:xe,onChange:et=>{const _t=[...k];_t[ke]=et.target.value.trim(),W(_t)},placeholder:"例: https://bucket.oss-accelerate.aliyuncs.com/config.json",style:{flex:1,minWidth:400}}),k.length>1&&a.jsx(Y,{icon:a.jsx(Gs,{}),danger:!0,size:"small",onClick:()=>W(k.filter((et,_t)=>_t!==ke))})]},ke)),a.jsx(Pt,{type:"secondary",children:"推送新桶地址到客户端,客户端缓存后优先使用新地址拉取域名配置(硬编码地址作为兜底)"})]})}),s&&a.jsxs(be,{title:"加密结果",size:"small",extra:a.jsx(Y,{size:"small",icon:a.jsx(un,{}),onClick:()=>Je(s),children:"复制"}),style:{marginBottom:16},children:[a.jsx(li,{value:s,readOnly:!0,rows:4,style:{fontFamily:"monospace",fontSize:12}}),a.jsx(Bj,{type:"secondary",style:{marginTop:8,marginBottom:0},children:"将此内容粘贴到存储桶文件中(阿里云 OSS + 腾讯云 COS 各放一份)"})]}),a.jsx(be,{title:a.jsxs(a.Fragment,{children:[a.jsx(pi,{style:{marginRight:8}}),"已保存的加密记录",a.jsx(Te,{color:"blue",style:{marginLeft:8},children:V.length})]}),size:"small",style:{marginBottom:16},children:V.length===0?a.jsx(Pt,{type:"secondary",children:"暂无加密记录,加密域名后将自动保存到此处"}):a.jsx(Ye,{dataSource:V.map((xe,ke)=>({...xe,_index:ke})),rowKey:"_index",pagination:!1,size:"small",columns:[{title:"域名列表",dataIndex:"domains",width:250,render:xe=>a.jsx(Xt,{title:xe==null?void 0:xe.join(", "),children:a.jsx(Pt,{style:{fontSize:12},children:xe==null?void 0:xe.join(", ")})}),ellipsis:!0},{title:"加密内容",dataIndex:"encrypted",ellipsis:!0,render:xe=>a.jsxs(Ie,{size:4,children:[a.jsx(Xt,{title:xe,children:a.jsx(Pt,{code:!0,style:{fontSize:11,maxWidth:300,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"inline-block",verticalAlign:"middle"},children:xe})}),a.jsx(Y,{type:"text",size:"small",icon:a.jsx(un,{}),onClick:()=>Je(xe),style:{padding:"0 2px",minWidth:24}})]})},{title:"使用密钥",dataIndex:"key_used",width:180,render:xe=>a.jsxs(Ie,{size:4,children:[a.jsx(Pt,{code:!0,style:{fontSize:11},children:xe}),a.jsx(Y,{type:"text",size:"small",icon:a.jsx(un,{}),onClick:()=>Je(xe),style:{padding:"0 2px",minWidth:24}})]})},{title:"时间",dataIndex:"created_at",width:155,ellipsis:!0},{title:"操作",width:90,render:(xe,ke)=>a.jsxs(Ie,{size:"small",children:[a.jsx(Y,{size:"small",icon:a.jsx(xl,{}),onClick:()=>{D(ke.encrypted),T&&K(T),me(null)}}),a.jsx(Y,{size:"small",danger:!0,icon:a.jsx(Gs,{}),onClick:()=>yt(ke._index)})]})}]})}),a.jsxs(Es,{gutter:16,style:{marginBottom:16},align:"stretch",children:[a.jsx(Ct,{span:12,style:{display:"flex"},children:a.jsx(be,{title:a.jsxs(a.Fragment,{children:[a.jsx(Xo,{style:{marginRight:8}}),"域名列表解密"]}),size:"small",style:{flex:1},children:a.jsxs(Ie,{direction:"vertical",style:{width:"100%"},size:"small",children:[a.jsx(li,{value:z,onChange:xe=>D(xe.target.value),placeholder:"粘贴加密后的 base64 内容",rows:3,style:{fontFamily:"monospace",fontSize:12}}),a.jsxs(Ie,{children:[a.jsx(Pt,{children:"密钥:"}),a.jsx(ve,{value:q,onChange:xe=>K(xe.target.value.trim()),placeholder:"64 位 hex 密钥",maxLength:64,style:{flex:1,fontFamily:"monospace",fontSize:12}})]}),a.jsx(Y,{type:"primary",loading:ie,onClick:Tt,children:"解密域名列表"}),Z&&a.jsx(Zs,{type:"success",message:"解密结果",description:a.jsx(Ie,{direction:"vertical",size:2,children:Z.map((xe,ke)=>a.jsxs(Ie,{size:4,children:[a.jsx(Te,{color:"green",children:ke+1}),a.jsx(Pt,{code:!0,copyable:!0,children:xe})]},ke))})})]})})}),a.jsx(Ct,{span:12,style:{display:"flex"},children:a.jsxs(be,{title:a.jsxs(a.Fragment,{children:[a.jsx(rr,{style:{marginRight:8}}),"字符串混淆工具"]}),size:"small",style:{flex:1},children:[a.jsx(Zs,{message:"将密钥或桶地址转为 Kotlin byteArrayOf() 常量,防止反编译直接看到明文",type:"warning",style:{marginBottom:12,padding:"4px 12px"}}),a.jsxs(Ie,{direction:"vertical",style:{width:"100%"},size:"small",children:[a.jsx(ve,{value:u,onChange:xe=>h(xe.target.value),placeholder:"备注名称(如:阿里云 OSS 桶地址)"}),a.jsx(ve,{value:c,onChange:xe=>d(xe.target.value),placeholder:"输入要混淆的字符串(密钥、桶地址等)",style:{fontFamily:"monospace"}}),a.jsxs(Ie,{children:[a.jsx(Pt,{children:"XOR Key:"}),a.jsx(ve,{value:m,onChange:xe=>_(Number(xe.target.value)||0),style:{width:70,fontFamily:"monospace"},type:"number",min:0,max:255}),a.jsx(Pt,{type:"secondary",children:"(0~255,默认 0xA7)"})]}),a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",loading:p,onClick:De,children:"生成 byteArrayOf"}),x&&a.jsx(Y,{icon:a.jsx(Js,{}),onClick:Ce,loading:te,children:"保存记录"})]}),x&&a.jsxs(a.Fragment,{children:[a.jsx(li,{value:x,readOnly:!0,rows:2,style:{fontFamily:"monospace",fontSize:12}}),a.jsx(Y,{size:"small",icon:a.jsx(un,{}),onClick:()=>Je(x),children:"复制"})]})]})]})})]}),a.jsx(be,{title:a.jsxs(a.Fragment,{children:[a.jsx(Js,{style:{marginRight:8}}),"已保存的混淆记录",a.jsx(Te,{color:"blue",style:{marginLeft:8},children:F.length})]}),size:"small",children:F.length===0?a.jsx(Pt,{type:"secondary",children:'暂无混淆记录,生成 byteArrayOf 后点击"保存记录"将保存到此处'}):a.jsx(Ye,{dataSource:F.map((xe,ke)=>({...xe,_index:ke})),rowKey:"_index",pagination:!1,size:"small",columns:[{title:"备注",dataIndex:"label",width:140,ellipsis:!0},{title:"原始字符串",dataIndex:"text",width:280,render:xe=>a.jsxs(Ie,{size:4,children:[a.jsx(Xt,{title:xe,children:a.jsx(Pt,{code:!0,style:{fontSize:11,maxWidth:220,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"inline-block",verticalAlign:"middle"},children:xe})}),a.jsx(Y,{type:"text",size:"small",icon:a.jsx(un,{}),onClick:()=>Je(xe),style:{padding:"0 2px",minWidth:24}})]})},{title:"byteArrayOf",dataIndex:"byte_array",ellipsis:!0,render:xe=>a.jsxs(Ie,{size:4,style:{flexWrap:"nowrap"},children:[a.jsx(Xt,{title:xe,overlayStyle:{maxWidth:600},children:a.jsx(Pt,{code:!0,style:{fontSize:11,maxWidth:350,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"inline-block",verticalAlign:"middle"},children:xe})}),a.jsx(Y,{type:"link",size:"small",icon:a.jsx(un,{}),onClick:()=>Je(xe),style:{flexShrink:0},children:"复制"})]})},{title:"XOR",dataIndex:"xor_key",width:55},{title:"时间",dataIndex:"created_at",width:155,ellipsis:!0},{title:"操作",width:60,render:(xe,ke)=>a.jsx(Y,{size:"small",danger:!0,icon:a.jsx(Gs,{}),onClick:()=>Qe(ke._index)})}]})}),a.jsx(be,{title:a.jsxs(a.Fragment,{children:[a.jsx(Xo,{style:{marginRight:8}}),"XOR 解密验证"]}),size:"small",style:{marginTop:16},children:a.jsxs(Ie,{direction:"vertical",style:{width:"100%"},size:"small",children:[a.jsx(li,{value:S,onChange:xe=>w(xe.target.value),placeholder:"粘贴 byteArrayOf(-61, -106, ...) 或逗号分隔的数字",rows:2,style:{fontFamily:"monospace",fontSize:12}}),a.jsxs(Ie,{children:[a.jsx(Pt,{children:"XOR Key:"}),a.jsx(ve,{value:v,onChange:xe=>y(Number(xe.target.value)||0),style:{width:70,fontFamily:"monospace"},type:"number",min:0,max:255}),a.jsx(Y,{type:"primary",onClick:Xe,children:"解密验证"}),R&&a.jsxs(a.Fragment,{children:[a.jsx(Pt,{children:"结果:"}),a.jsx(Pt,{code:!0,copyable:!0,style:{maxWidth:500,wordBreak:"break-all"},children:R})]})]})]})})]})},{Text:du}=Cr,zj=[{label:"待处理",value:0},{label:"已解决",value:2}],$j=[{label:"低",value:1},{label:"中",value:2},{label:"高",value:3},{label:"紧急",value:4}],uu={0:"orange",2:"green"},fu={0:"待处理",2:"已解决"},hu={1:"blue",2:"cyan",3:"orange",4:"red"},mu={1:"低",2:"中",3:"高",4:"紧急"},Wj=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,{renderTenantId:r}=Yr(),[n,s]=g.useState(!1),[i,o]=g.useState(!1),[l,c]=g.useState([]),[d,u]=g.useState(1),[h,m]=g.useState(20),[_,x]=g.useState(0),[f,p]=g.useState({}),[I,S]=g.useState([]),[w]=b.useForm(),[v,y]=g.useState(!1),[R,j]=g.useState(!1),[T,C]=g.useState(null),[F,P]=g.useState(!1),[V,X]=g.useState(null),[_e]=b.useForm(),[B,te]=g.useState(!1),[J,G]=g.useState(null),[se]=b.useForm(),Q=async(he=d,we=h,He=f)=>{s(!0);try{const ze=await ds.list({...He,page:he,page_size:we});(ze.code===0||ze.code===200)&&ze.data?(c(ze.data.items),x(ze.data.total),u(ze.data.page),m(ze.data.size)):E.error(ze.message||"获取反馈列表失败")}catch(ze){E.error(ze.message||"获取反馈列表失败")}finally{s(!1)}};g.useEffect(()=>{Q(1,h,f)},[]);const de=he=>{const we={};he.tenant_id&&(we.tenant_id=he.tenant_id),he.user_id&&(we.user_id=he.user_id),he.status!==void 0&&he.status!==null&&(we.status=he.status),he.priority&&(we.priority=he.priority),he.keyword&&(we.keyword=he.keyword),p(we),Q(1,h,we)},k=async he=>{C(null),y(!0),j(!0);try{const we=await ds.detail(he);(we.code===0||we.code===200)&&we.data?C(we.data):E.error(we.message||"获取反馈详情失败")}catch(we){E.error(we.message||"获取反馈详情失败")}finally{j(!1)}},W=he=>{X(he),_e.resetFields(),P(!0)},z=async()=>{if(V)try{const he=await _e.validateFields(),we=await ds.handle(V.id,{status:he.status,handle_comment:he.handle_comment||void 0});we.code===0||we.code===200?(E.success("反馈已处理"),P(!1),Q()):E.error(we.message||"处理失败")}catch(he){if(he!=null&&he.errorFields)return;E.error(he.message||"处理失败")}},D=he=>{G(he),se.setFieldsValue({priority:he.priority}),te(!0)},q=async()=>{if(J)try{const he=await se.validateFields(),we=await ds.updatePriority(J.id,{priority:he.priority});we.code===0||we.code===200?(E.success("优先级已更新"),te(!1),Q()):E.error(we.message||"更新失败")}catch(he){if(he!=null&&he.errorFields)return;E.error(he.message||"更新失败")}},K=async()=>{if(I.length===0){E.warning("请先选择要处理的反馈");return}try{const he=await ds.batchHandle({ids:I.map(He=>Number(He))});(he.code===0||he.code===200)&&he.data?(E.success(`批量处理完成:成功 ${he.data.success} 条,失败 ${he.data.failed} 条`),S([]),Q()):E.error(he.message||"批量处理失败")}catch(he){E.error(he.message||"批量处理失败")}},Z=async()=>{o(!0);try{const he=await ds.export(f),we=window.URL.createObjectURL(new Blob([he],{type:"text/csv"})),He=document.createElement("a");He.href=we,He.setAttribute("download",`feedbacks_${Date.now()}.csv`),document.body.appendChild(He),He.click(),He.remove(),window.URL.revokeObjectURL(we),E.success("导出成功")}catch(he){E.error(he.message||"导出失败")}finally{o(!1)}},me={selectedRowKeys:I,onChange:he=>S(he)},ie=[...t?[{title:"ID",dataIndex:"id",width:80}]:[],...t?[{title:"租户",dataIndex:"tenant_id",width:160,render:r}]:[],{title:"用户",dataIndex:"user_name",width:120},{title:"优先级",dataIndex:"priority",width:90,render:he=>a.jsx(Te,{color:hu[he]||"default",children:mu[he]||he})},{title:"内容",dataIndex:"content",width:280,render:he=>a.jsx(Xt,{title:he,children:a.jsx(du,{ellipsis:!0,style:{maxWidth:260},children:he})})},{title:"状态",dataIndex:"status",width:100,render:he=>a.jsx(Te,{color:uu[he]||"default",children:fu[he]||he})},{title:"处理人",dataIndex:"handler_name",width:120,render:he=>he||"--"},{title:"创建时间",dataIndex:"created_at",width:180,render:he=>Ke(he)},{title:"操作",key:"actions",width:200,fixed:"right",render:(he,we)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",onClick:()=>k(we.id),children:"详情"}),we.status===0&&a.jsx(Y,{size:"small",type:"primary",onClick:()=>W(we),children:"处理"}),a.jsx(Y,{size:"small",onClick:()=>D(we),children:"优先级"})]})}];return a.jsxs("div",{className:"admin-feedbacks",children:[a.jsx(be,{className:"admin-feedbacks-filter",children:a.jsxs(b,{form:w,layout:"inline",onFinish:de,children:[t&&a.jsx(b.Item,{label:"租户",name:"tenant_id",children:a.jsx(ot,{allowClear:!0,style:{width:200}})}),a.jsx(b.Item,{label:"用户ID",name:"user_id",children:a.jsx(ve,{placeholder:"用户ID",allowClear:!0,style:{width:140}})}),a.jsx(b.Item,{label:"状态",name:"status",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:zj,style:{width:120}})}),a.jsx(b.Item,{label:"优先级",name:"priority",children:a.jsx($e,{placeholder:"全部",allowClear:!0,options:$j,style:{width:120}})}),a.jsx(b.Item,{label:"关键词",name:"keyword",children:a.jsx(ve,{placeholder:"内容/联系方式",allowClear:!0,style:{width:180}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",children:"查询"}),a.jsx(Y,{onClick:()=>{w.resetFields(),de({})},children:"重置"})]})})]})}),a.jsxs(be,{children:[a.jsx("div",{style:{marginBottom:16},children:a.jsxs(Ie,{children:[a.jsx(js,{title:"确认批量处理",description:`将 ${I.length} 条反馈标记为已解决,是否继续?`,onConfirm:K,okText:"确认",cancelText:"取消",children:a.jsx(Y,{disabled:I.length===0,children:"批量处理"})}),a.jsx(Y,{icon:a.jsx($r,{}),loading:i,onClick:Z,children:"导出 CSV"})]})}),a.jsx(Ye,{rowKey:"id",rowSelection:me,columns:ie,dataSource:l,loading:n,scroll:{x:1400},pagination:{current:d,pageSize:h,total:_,showSizeChanger:!0,onChange:(he,we)=>{Q(he,we)}}})]}),a.jsx($i,{title:"反馈详情",width:520,open:v,onClose:()=>y(!1),children:a.jsx(Mn,{spinning:R,children:T&&a.jsxs(a.Fragment,{children:[a.jsxs(je,{column:1,bordered:!0,size:"small",children:[a.jsx(je.Item,{label:"ID",children:T.id}),a.jsx(je.Item,{label:"租户 ID",children:T.tenant_id}),a.jsxs(je.Item,{label:"用户",children:[T.user_name,"(ID: ",T.user_id,")"]}),a.jsx(je.Item,{label:"优先级",children:a.jsx(Te,{color:hu[T.priority]||"default",children:mu[T.priority]||T.priority})}),a.jsx(je.Item,{label:"内容",children:T.content}),a.jsx(je.Item,{label:"联系方式",children:T.contact_info||"--"}),a.jsx(je.Item,{label:"状态",children:a.jsx(Te,{color:uu[T.status]||"default",children:fu[T.status]||T.status})}),a.jsx(je.Item,{label:"处理人",children:T.handler_name||"--"}),a.jsx(je.Item,{label:"处理备注",children:T.handle_comment||"--"}),a.jsx(je.Item,{label:"处理时间",children:Ke(T.handle_time)}),a.jsx(je.Item,{label:"创建时间",children:Ke(T.created_at)}),a.jsx(je.Item,{label:"更新时间",children:Ke(T.updated_at)})]}),T.attachment_urls&&T.attachment_urls.length>0&&a.jsxs("div",{style:{marginTop:16},children:[a.jsx(du,{strong:!0,children:"附件:"}),a.jsx("div",{style:{marginTop:8},children:a.jsx(Mr.PreviewGroup,{children:T.attachment_urls.map((he,we)=>a.jsx(Mr,{src:he,className:"admin-feedbacks-attachment-img",fallback:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mN8/+F9PQAI8wNPvd7POQAAAABJRU5ErkJggg=="},we))})})]})]})})}),a.jsx(Me,{title:"处理反馈",open:F,onCancel:()=>P(!1),onOk:z,okText:"确认",cancelText:"取消",destroyOnClose:!0,children:a.jsxs(b,{form:_e,layout:"vertical",children:[a.jsx(b.Item,{label:"处理结果",name:"status",rules:[{required:!0,message:"请选择处理结果"}],children:a.jsx($e,{placeholder:"选择处理结果",children:a.jsx($e.Option,{value:"resolved",children:"已解决"})})}),a.jsx(b.Item,{label:"处理备注",name:"handle_comment",children:a.jsx(ve.TextArea,{rows:3,placeholder:"可选备注",maxLength:1e3,showCount:!0})})]})}),a.jsx(Me,{title:"更新优先级",open:B,onCancel:()=>te(!1),onOk:q,okText:"确认",cancelText:"取消",destroyOnClose:!0,children:a.jsx(b,{form:se,layout:"vertical",children:a.jsx(b.Item,{label:"优先级",name:"priority",rules:[{required:!0,message:"请选择优先级"}],children:a.jsxs($e,{placeholder:"选择优先级",children:[a.jsx($e.Option,{value:1,children:"低"}),a.jsx($e.Option,{value:2,children:"中"}),a.jsx($e.Option,{value:3,children:"高"}),a.jsx($e.Option,{value:4,children:"紧急"})]})})})})]})},{Title:Hj,Text:Hs,Paragraph:xu}=Cr,Vj=()=>{const e="ABCDEFGHIJKLMNOPQRSTUVWXYZ",t="abcdefghijklmnopqrstuvwxyz",r="0123456789",n=e+t+r,s=[e[Math.floor(Math.random()*e.length)],t[Math.floor(Math.random()*t.length)],r[Math.floor(Math.random()*r.length)]];for(let i=0;i<9;i++)s.push(n[Math.floor(Math.random()*n.length)]);for(let i=s.length-1;i>0;i--){const o=Math.floor(Math.random()*(i+1));[s[i],s[o]]=[s[o],s[i]]}return s.join("")},pu=async()=>{const[e,t]=await Promise.all([fetch("/前缀.txt").then(r=>r.text()),fetch("/后缀.txt").then(r=>r.text())]);return{prefixes:e.split(` +`).map(r=>r.trim()).filter(Boolean),suffixes:t.split(` +`).map(r=>r.trim()).filter(Boolean)}},gu=(e,t,r)=>{const n=[];for(let s=0;s{const[e]=b.useForm(),{admin:t}=pt(),{renderTenantId:r}=Yr(),n=!!t&&!t.tenant_id,[s,i]=g.useState(!1),[o,l]=g.useState("new"),[c,d]=g.useState([]),[u,h]=g.useState(null),[m,_]=g.useState([]),[x,f]=g.useState(!1),p=b.useWatch("tenant_id",e),I=b.useWatch("member_count",e)??10,S=n?p:t==null?void 0:t.tenant_id,w=g.useCallback(async(T,C)=>{var F;f(!0);try{const P=await Lt.list({tenant_id:T,keyword:(C==null?void 0:C.trim())||void 0,page:1,page_size:50});(P.code===0||P.code===200)&&((F=P.data)!=null&&F.items)&&_(P.data.items.map(X=>({value:X.id,label:`${X.nickname||X.username} (${X.username}) #${X.id}`})))}finally{f(!1)}},[]);g.useEffect(()=>{o==="existing"&&S&&w(S)},[o,S,w]);const v=g.useMemo(()=>{const T=Number(I)||0;return o==="existing"?Math.max(0,T-1):T},[I,o]),y=async()=>{try{if(await e.validateFields(["tenant_id","member_count","owner_id"]),v<=0){E.warning("群人数至少为 2");return}const T=await pu();if(T.prefixes.length===0||T.suffixes.length===0){E.error("前缀或后缀文件为空");return}d(gu(v,T.prefixes,T.suffixes)),E.success(`已生成 ${v} 名成员预览`)}catch{}},R=T=>{const C=new Date,F=`${C.getFullYear()}-${String(C.getMonth()+1).padStart(2,"0")}-${String(C.getDate()).padStart(2,"0")} ${String(C.getHours()).padStart(2,"0")}:${String(C.getMinutes()).padStart(2,"0")}:${String(C.getSeconds()).padStart(2,"0")}`;let P=`快速建群 - 生成时间:${F} +`;P+=`群名称:${T.group_name} +`,P+=`群号:${T.group_code} +`,P+=`群 ID:${T.group_id} +`,P+=`群主 ID:${T.owner_id} +`,P+=`================================================ +`,P+=`昵称 用户名 密码 身份 +`,P+=`------------------------------------------------ +`;for(const B of T.members)P+=`${B.nickname} ${B.username} ${B.password} ${B.is_owner?"群主":"成员"} +`;const V=new Blob(["\uFEFF"+P],{type:"text/plain;charset=utf-8"}),X=URL.createObjectURL(V),_e=document.createElement("a");_e.href=X,_e.download=`快速建群_${T.group_code}_${F.replace(/[: ]/g,"-")}.txt`,document.body.appendChild(_e),_e.click(),document.body.removeChild(_e),URL.revokeObjectURL(X)},j=async()=>{var T,C;try{const F=await e.validateFields(),P=n?F.tenant_id:t==null?void 0:t.tenant_id;if(!P){E.error("无法获取企业信息");return}if(o==="existing"&&!F.owner_id){E.error("请选择群主");return}if(v<=0){E.error("群人数至少为 2");return}let V=c;if(V.length!==v){const _e=await pu();V=gu(v,_e.prefixes,_e.suffixes),d(V)}i(!0);const X=E.loading(`正在创建 ${v} 名用户并建群,人数较多可能需要 1~3 分钟,请勿关闭页面…`,0);try{const _e=await Wn.quickCreate({tenant_id:P,owner_id:o==="existing"?F.owner_id:void 0,member_count:F.member_count,group_name:((T=F.group_name)==null?void 0:T.trim())||void 0,users:V});(_e.code===0||_e.code===200)&&_e.data?(h(_e.data),E.success(`群组「${_e.data.group_name}」创建成功`),R(_e.data)):E.error(_e.message||"创建失败")}finally{X()}}catch(F){if(F!=null&&F.errorFields)return;if((C=F==null?void 0:F.message)!=null&&C.includes("timeout")){E.error("请求超时,若后台仍在处理请稍后到群组管理查看是否已创建成功");return}E.error(F.message||"创建失败")}finally{i(!1)}};return a.jsxs("div",{style:{padding:24},children:[a.jsx(Hj,{level:4,style:{marginTop:0},children:"快速建群"}),a.jsx(xu,{type:"secondary",children:"指定企业与群人数,一键批量新建用户并创建群组。可选择已有用户作为群主,或由第一个新建用户担任群主。"}),a.jsx(be,{style:{maxWidth:720,marginBottom:24},children:a.jsxs(b,{form:e,layout:"vertical",initialValues:{member_count:10,owner_mode:"new"},onValuesChange:T=>{"owner_mode"in T&&(l(T.owner_mode),d([]),h(null)),("member_count"in T||"tenant_id"in T)&&(d([]),h(null))},children:[n?a.jsx(b.Item,{label:"企业",name:"tenant_id",rules:[{required:!0,message:"请选择企业"}],children:a.jsx(ot,{placeholder:"请选择企业",style:{width:"100%"}})}):a.jsx(b.Item,{label:"企业",children:a.jsx(ve,{value:r(t==null?void 0:t.tenant_id),disabled:!0})}),a.jsx(b.Item,{label:"群名称",name:"group_name",extra:"留空则自动生成",children:a.jsx(ve,{placeholder:"例如:测试群 A",maxLength:100})}),a.jsx(b.Item,{label:"群人数(含群主)",name:"member_count",rules:[{required:!0,message:"请输入群人数"}],children:a.jsx(at,{min:2,max:500,style:{width:"100%"}})}),a.jsx(b.Item,{label:"群主",name:"owner_mode",children:a.jsxs(_o.Group,{children:[a.jsx(_o,{value:"new",children:"新建用户担任群主(第一个新建用户)"}),a.jsx(_o,{value:"existing",children:"指定已有用户为群主"})]})}),o==="existing"&&a.jsx(b.Item,{label:"选择群主",name:"owner_id",rules:[{required:!0,message:"请选择群主"}],children:a.jsx($e,{showSearch:!0,placeholder:"搜索用户名或昵称",optionFilterProp:"label",loading:x,options:m,onSearch:T=>{S&&w(S,T)},disabled:!S})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsxs(Y,{onClick:y,disabled:!S,children:["预览成员(",v," 人)"]}),a.jsx(Y,{type:"primary",loading:s,onClick:j,children:"一键建群"})]})}),a.jsxs(Hs,{type:"secondary",children:["将新建 ",v," 名用户",o==="existing"?",并使用所选用户作为群主":",其中第一个用户为群主"]})]})}),c.length>0&&a.jsx(be,{title:`成员预览(${c.length} 人)`,style:{marginBottom:24},children:a.jsx(Ye,{rowKey:(T,C)=>String(C),size:"small",pagination:!1,dataSource:c.map((T,C)=>({...T,key:C,role:o==="new"&&C===0?"群主":"成员"})),columns:[{title:"#",width:60,render:(T,C,F)=>F+1},{title:"昵称",dataIndex:"nickname"},{title:"密码",dataIndex:"password",render:T=>a.jsx(Hs,{code:!0,copyable:{text:T},children:T})},{title:"身份",dataIndex:"role",width:80}]})}),u&&a.jsxs(be,{title:"创建结果",extra:u?a.jsx(Y,{onClick:()=>R(u),children:"下载账号 TXT"}):void 0,children:[a.jsxs(xu,{children:["群名称:",a.jsx(Hs,{strong:!0,children:u.group_name})," · ","群号:",a.jsx(Hs,{code:!0,children:u.group_code})," · ","群 ID:",u.group_id]}),a.jsx(Ye,{rowKey:"id",size:"small",dataSource:u.members,columns:[{title:"ID",dataIndex:"id",width:80},{title:"昵称",dataIndex:"nickname"},{title:"用户名",dataIndex:"username"},{title:"密码",dataIndex:"password",render:T=>a.jsx(Hs,{code:!0,copyable:{text:T},children:T})},{title:"身份",dataIndex:"is_owner",width:80,render:T=>T?"群主":"成员"}],pagination:!1})]})]})},_u={name:"",is_default:!1,allow_add_friend:!0,allow_create_group:!0,direct_add_friend:!1,max_friend_count:0,allow_app_login:!0,allow_web_login:!0,ip_whitelist_enabled:!1,enabled:!0,sort_order:0},Gj=()=>{var X,_e;const{admin:e}=pt(),t=!(e!=null&&e.tenant_id),[r,n]=g.useState(e==null?void 0:e.tenant_id),[s,i]=g.useState([]),[o,l]=g.useState(!1),[c,d]=g.useState(!1),[u,h]=g.useState(null),[m,_]=g.useState(!1),[x,f]=g.useState(!1),[p,I]=g.useState(null),[S]=b.useForm(),[w]=b.useForm(),v=async(B=r)=>{if(!B){i([]),I(null);return}l(!0);try{const[te,J]=await Promise.all([Fn.list(t?B:void 0),Fn.getIPWhitelist(t?B:void 0)]);(te.code===0||te.code===200)&&te.data?i(te.data):E.error(te.message||"获取用户分组失败"),(J.code===0||J.code===200)&&J.data&&I(J.data)}catch(te){E.error(te.message||"获取用户分组失败")}finally{l(!1)}};g.useEffect(()=>{v()},[r]);const y=B=>{h(B||null),S.setFieldsValue(B||_u),_(!0)},R=async()=>{if(r)try{const B=await S.validateFields();d(!0);const te={...B,tenant_id:r},J=u?await Fn.update(u.id,te):await Fn.create(te);J.code===0||J.code===200?(E.success(u?"分组已更新":"分组已创建"),_(!1),await v()):E.error(J.message||"保存失败")}catch(B){B!=null&&B.errorFields||E.error(B.message||"保存失败")}finally{d(!1)}},j=async B=>{try{const te=await Fn.delete(B.id,t?r:void 0);te.code===0||te.code===200?(E.success("分组已删除"),await v()):E.error(te.message||"删除失败")}catch(te){E.error(te.message||"删除失败")}},T=()=>{w.setFieldsValue(p||{app_login_ip_whitelist:"",web_login_ip_whitelist:""}),f(!0)},C=async()=>{if(r)try{const B=await w.validateFields();d(!0);const te=await Fn.updateIPWhitelist({tenant_id:r,...B});te.code===0||te.code===200?(E.success("IP 白名单已保存"),f(!1),await v()):E.error(te.message||"保存失败")}catch(B){B!=null&&B.errorFields||E.error(B.message||"保存失败")}finally{d(!1)}},F=g.useMemo(()=>[{title:"分组名称",dataIndex:"name",width:180,render:(B,te)=>a.jsxs(Ie,{children:[a.jsx("span",{children:B}),te.is_default&&a.jsx(Te,{color:"blue",children:"默认"})]})},{title:"用户数",dataIndex:"user_count",width:90},{title:"允许加好友",dataIndex:"allow_add_friend",width:110,render:B=>a.jsx(Te,{color:B?"green":"default",children:B?"允许":"禁止"})},{title:"允许建群",dataIndex:"allow_create_group",width:100,render:B=>a.jsx(Te,{color:B?"green":"default",children:B?"允许":"禁止"})},{title:"直接加好友",dataIndex:"direct_add_friend",width:110,render:B=>B?a.jsx(Te,{color:"cyan",children:"开启"}):"--"},{title:"好友上限",dataIndex:"max_friend_count",width:100,render:B=>B===0?"不限":B},{title:"APP 登录",dataIndex:"allow_app_login",width:100,render:B=>B?"允许":"禁止"},{title:"Web 登录",dataIndex:"allow_web_login",width:100,render:B=>B?"允许":"禁止"},{title:"IP 白名单",dataIndex:"ip_whitelist_enabled",width:110,render:B=>a.jsx(Te,{color:B?"gold":"default",children:B?"已启用":"未启用"})},{title:"状态",dataIndex:"enabled",width:90,render:B=>a.jsx(Te,{color:B?"green":"red",children:B?"启用":"停用"})},{title:"权重",dataIndex:"sort_order",width:80},{title:"操作",key:"actions",fixed:"right",width:145,render:(B,te)=>a.jsxs(Ie,{children:[a.jsx(Y,{type:"text",size:"small",icon:a.jsx(im,{}),onClick:()=>y(te),children:"编辑"}),a.jsx(js,{title:"确认删除该分组?",onConfirm:()=>j(te),disabled:te.is_default,children:a.jsx(Y,{type:"text",size:"small",danger:!0,disabled:te.is_default,children:"删除"})})]})}],[r,t]),P=!!((X=p==null?void 0:p.app_login_ip_whitelist)!=null&&X.trim()),V=!!((_e=p==null?void 0:p.web_login_ip_whitelist)!=null&&_e.trim());return a.jsxs("div",{className:"policy-groups-page",children:[a.jsx("div",{className:"policy-toolbar",children:a.jsxs(Ie,{children:[t&&a.jsx(ot,{value:r,onChange:B=>n(B),style:{width:260}}),a.jsx(Y,{type:"primary",icon:a.jsx(ua,{}),disabled:!r,onClick:()=>y(),children:"添加分组"}),a.jsx(Y,{icon:a.jsx(Ks,{}),disabled:!r,onClick:T,children:"IP 白名单"})]})}),r&&a.jsx(Zs,{className:"policy-ip-status",type:P&&V?"success":"warning",showIcon:!0,message:a.jsxs(Ie,{size:"large",children:[a.jsx("span",{children:"租户渠道 IP 白名单"}),a.jsxs("span",{children:["APP:",P?"已配置":"未配置"]}),a.jsxs("span",{children:["Web:",V?"已配置":"未配置"]})]})}),a.jsx(Ye,{rowKey:"id",loading:o,columns:F,dataSource:s,pagination:!1,scroll:{x:1450}}),a.jsx(Me,{title:u?"编辑分组":"添加分组",open:m,width:620,confirmLoading:c,onOk:R,onCancel:()=>_(!1),destroyOnClose:!0,children:a.jsxs(b,{form:S,layout:"vertical",initialValues:_u,className:"policy-editor-form",children:[a.jsx(b.Item,{label:"分组名称",name:"name",rules:[{required:!0,message:"请输入分组名称"},{max:50}],children:a.jsx(ve,{})}),a.jsxs("div",{className:"policy-switch-grid",children:[a.jsx(b.Item,{label:"默认用户组",name:"is_default",valuePropName:"checked",children:a.jsx(rt,{disabled:!!(u!=null&&u.is_default)})}),a.jsx(b.Item,{label:"启用状态",name:"enabled",valuePropName:"checked",children:a.jsx(rt,{})}),a.jsx(b.Item,{label:"允许加好友",name:"allow_add_friend",valuePropName:"checked",children:a.jsx(rt,{})}),a.jsx(b.Item,{label:"允许建群",name:"allow_create_group",valuePropName:"checked",children:a.jsx(rt,{})}),a.jsx(b.Item,{label:"直接添加好友",name:"direct_add_friend",valuePropName:"checked",children:a.jsx(rt,{})}),a.jsx(b.Item,{label:"允许 APP 登录",name:"allow_app_login",valuePropName:"checked",children:a.jsx(rt,{})}),a.jsx(b.Item,{label:"允许 Web 登录",name:"allow_web_login",valuePropName:"checked",children:a.jsx(rt,{})}),a.jsx(b.Item,{label:"启用 IP 白名单",name:"ip_whitelist_enabled",valuePropName:"checked",children:a.jsx(rt,{})})]}),a.jsxs("div",{className:"policy-number-grid",children:[a.jsx(b.Item,{label:"好友数量上限",name:"max_friend_count",rules:[{required:!0}],children:a.jsx(at,{min:0,max:1e5,precision:0,style:{width:"100%"},addonAfter:"0 为不限"})}),a.jsx(b.Item,{label:"排序权重",name:"sort_order",rules:[{required:!0}],children:a.jsx(at,{min:-1e5,max:1e5,precision:0,style:{width:"100%"}})})]})]})}),a.jsx(Me,{title:"租户渠道 IP 白名单",open:x,width:620,confirmLoading:c,onOk:C,onCancel:()=>f(!1),children:a.jsxs(b,{form:w,layout:"vertical",children:[a.jsx(b.Item,{label:"APP 登录白名单",name:"app_login_ip_whitelist",children:a.jsx(ve.TextArea,{rows:6,placeholder:`每行一个 IPv4、IPv6 或 CIDR +203.0.113.10 +2001:db8::/32`})}),a.jsx(b.Item,{label:"Web 登录白名单",name:"web_login_ip_whitelist",children:a.jsx(ve.TextArea,{rows:6,placeholder:`每行一个 IPv4、IPv6 或 CIDR +198.51.100.0/24`})})]})})]})},Yj={active:{color:"green",label:"正常"},disabled:{color:"red",label:"已封禁"}},qj=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,[r]=b.useForm(),[n,s]=g.useState(!1),[i,o]=g.useState([]),[l,c]=g.useState(1),[d,u]=g.useState(20),[h,m]=g.useState(0),[_,x]=g.useState({}),[f,p]=g.useState(!1),[I,S]=g.useState(""),[w,v]=g.useState([]),[y,R]=g.useState(!1),[j,T]=g.useState(1),[C,F]=g.useState(20),[P,V]=g.useState(0),X=g.useRef(0),_e=g.useRef(0),B=async(W=l,z=d,D=_)=>{const q=++X.current;if(t&&!D.tenant_id){o([]),m(0),s(!1);return}s(!0);try{const K=await rd.list({...D,page:W,page_size:z}),Z=K.code===0||K.code===200;if(q!==X.current)return;if(!Z||!K.data){E.error(K.message||"获取 IP 统计失败");return}o(K.data.items),m(K.data.total),c(K.data.page),u(K.data.size)}catch(K){q===X.current&&E.error(K.message||"获取 IP 统计失败")}finally{q===X.current&&s(!1)}};g.useEffect(()=>{e&&(t||B(1,d,{}))},[e,t]);const te=W=>{var D;const z={tenant_id:W.tenant_id?Number(W.tenant_id):void 0,ip:((D=W.ip)==null?void 0:D.trim())||void 0};p(!1),x(z),B(1,d,z)},J=()=>{r.resetFields(),p(!1),x({}),t?(o([]),m(0)):B(1,d,{})},G=async(W,z=1,D=C)=>{const q=++_e.current;R(!0);try{const K=await rd.users({tenant_id:_.tenant_id,ip:W,page:z,page_size:D}),Z=K.code===0||K.code===200;if(q!==_e.current)return;if(!Z||!K.data){E.error(K.message||"获取关联用户失败");return}v(K.data.items),V(K.data.total),T(K.data.page),F(K.data.size)}catch(K){q===_e.current&&E.error(K.message||"获取关联用户失败")}finally{q===_e.current&&R(!1)}},se=W=>{S(W.ip),p(!0),G(W.ip,1,C)},Q=W=>{const z=_.tenant_id;z&&Me.confirm({title:"封禁该 IP 关联用户",content:`确认封禁当前租户内使用 IP「${W.ip}」注册或登录的全部账号?命中的账号会立即撤销登录会话并强制下线。`,okText:"确认封禁并下线",okButtonProps:{danger:!0},cancelText:"取消",onOk:async()=>{var D;try{const q=await Lt.banByIP(W.ip,z);if(!(q.code===0||q.code===200)||!q.data){E.error(q.message||"按 IP 封禁失败");return}E.success(`命中 ${q.data.matched_count} 人,成功 ${q.data.success_count} 人`),B(l,d,_),f&&I===W.ip&&G(W.ip,j,C)}catch(q){if((D=q==null?void 0:q.message)!=null&&D.includes("timeout")){E.warning("请求超时,后台可能仍在处理,请稍后刷新确认状态");return}E.error(q.message||"按 IP 封禁失败")}}})},de=[{title:"IP 地址",dataIndex:"ip",width:260,render:W=>a.jsx("span",{style:{wordBreak:"break-all"},children:W})},{title:"归属地",dataIndex:"ip_location",width:140,render:W=>W||"未知"},{title:"关联用户",dataIndex:"user_count",width:120,render:W=>a.jsxs(Ie,{size:6,children:[a.jsx("span",{children:W}),W>1&&a.jsx(Te,{color:"red",children:"多账号"})]})},{title:"注册用户",dataIndex:"register_user_count",width:110},{title:"登录用户",dataIndex:"login_user_count",width:110},{title:"正常",dataIndex:"active_user_count",width:90},{title:"已封禁",dataIndex:"disabled_user_count",width:90},{title:"最近活动",dataIndex:"last_seen_at",width:180,render:W=>Ke(W)},{title:"操作",key:"actions",fixed:"right",width:t?190:100,render:(W,z)=>a.jsxs(Ie,{children:[a.jsx(Y,{size:"small",icon:a.jsx(xl,{}),onClick:()=>se(z),children:"用户列表"}),t&&a.jsx(Y,{size:"small",danger:!0,icon:a.jsx(ju,{}),onClick:()=>Q(z),children:"封禁 IP"})]})}],k=[...t?[{title:"用户 ID",dataIndex:"user_id",width:100}]:[],{title:"用户编号",dataIndex:"user_no",width:110},{title:"用户名",dataIndex:"username",width:150},{title:"昵称",dataIndex:"nickname",width:150},{title:"来源",key:"source",width:150,render:(W,z)=>a.jsxs(Ie,{size:4,children:[z.matched_register&&a.jsx(Te,{color:"blue",children:"注册"}),z.matched_login&&a.jsx(Te,{color:"green",children:"登录"})]})},{title:"状态",dataIndex:"status",width:100,render:W=>{const z=Yj[W];return a.jsx(Te,{color:z.color,children:z.label})}},{title:"最近活动",dataIndex:"last_seen_at",width:180,render:W=>Ke(W)}];return a.jsxs("div",{children:[a.jsx(be,{style:{marginBottom:16},children:a.jsxs(b,{form:r,layout:"inline",onFinish:te,children:[t&&a.jsx(b.Item,{label:"租户",name:"tenant_id",rules:[{required:!0,message:"请选择租户"}],children:a.jsx(ot,{style:{width:220}})}),a.jsx(b.Item,{label:"IP",name:"ip",children:a.jsx(ve,{placeholder:"IPv4 或 IPv6",allowClear:!0,style:{width:220}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:J,children:"重置"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:"ip",columns:de,dataSource:i,loading:n,scroll:{x:1390},pagination:{current:l,pageSize:d,total:h,showSizeChanger:!0,showTotal:W=>`共 ${W} 个 IP`,onChange:(W,z)=>{c(W),u(z),B(W,z)}}})}),a.jsx(Me,{title:`IP ${I} 的关联用户`,open:f,onCancel:()=>p(!1),footer:null,width:980,destroyOnClose:!0,children:a.jsx(Ye,{rowKey:"user_id",columns:k,dataSource:w,loading:y,scroll:{x:900},pagination:{current:j,pageSize:C,total:P,showSizeChanger:!0,onChange:(W,z)=>G(I,W,z)}})})]})},{RangePicker:Xj}=jr,Oh=[{label:"修改昵称",value:"change_nickname"},{label:"修改头像",value:"change_avatar"},{label:"修改性别",value:"change_gender"},{label:"修改签名",value:"change_signature"},{label:"修改生日",value:"change_birthday"},{label:"修改密码",value:"change_password"},{label:"主动注销",value:"deactivate_account"},{label:"管理员修改用户名",value:"update_username"},{label:"管理员更新状态",value:"update_status"},{label:"管理员重置密码",value:"reset_password"},{label:"管理员更新安全权限",value:"update_security_perm"},{label:"管理员强制下线",value:"kick_user"},{label:"管理员强制注销",value:"force_deactivate"},{label:"管理员调整分组",value:"assign_policy_group"},{label:"管理员批量封禁",value:"batch_ban_users"},{label:"管理员按 IP 封禁",value:"ban_users_by_ip"}],Rh=Object.fromEntries(Oh.map(e=>[e.value,e.label])),cn=e=>e==null||e===""?"空":String(e),Jj=e=>{var t,r,n,s,i,o,l,c,d;if(e.details)return e.details;switch(e.action){case"change_nickname":return`${cn((t=e.before_data)==null?void 0:t.nickname)} → ${cn((r=e.after_data)==null?void 0:r.nickname)}`;case"change_avatar":return"已修改头像";case"change_gender":return`${cn((n=e.before_data)==null?void 0:n.gender)} → ${cn((s=e.after_data)==null?void 0:s.gender)}`;case"change_signature":return`${cn((i=e.before_data)==null?void 0:i.signature)} → ${cn((o=e.after_data)==null?void 0:o.signature)}`;case"change_birthday":return`${cn((l=e.before_data)==null?void 0:l.birthday)} → ${cn((c=e.after_data)==null?void 0:c.birthday)}`;case"change_password":return"密码已修改";case"deactivate_account":return"账号已主动注销";default:return(d=e.after_data)!=null&&d.details?cn(e.after_data.details):Rh[e.action]||e.action}},Zj=()=>{const{admin:e}=pt(),t=!!e&&!e.tenant_id,[r]=b.useForm(),[n,s]=g.useState(!1),[i,o]=g.useState([]),[l,c]=g.useState(1),[d,u]=g.useState(20),[h,m]=g.useState(0),[_,x]=g.useState({}),f=g.useRef(0),p=async(v=l,y=d,R=_)=>{const j=++f.current;if(t&&!R.tenant_id){o([]),m(0),s(!1);return}s(!0);try{const T=await v_.list({...R,page:v,page_size:y});if(j!==f.current)return;if(!(T.code===0||T.code===200)||!T.data){E.error(T.message||"获取用户账号审计日志失败");return}o(T.data.items),m(T.data.total),c(T.data.page),u(T.data.size)}catch(T){j===f.current&&E.error(T.message||"获取用户账号审计日志失败")}finally{j===f.current&&s(!1)}};g.useEffect(()=>{e&&(t||p(1,d,{}))},[e,t]);const I=v=>{var j,T,C,F;const y=v.time_range,R={tenant_id:v.tenant_id?Number(v.tenant_id):void 0,user_id:t&&v.user_id?Number(v.user_id):void 0,user_no:!t&&v.user_no?Number(v.user_no):void 0,username:((j=v.username)==null?void 0:j.trim())||void 0,action:v.action||void 0,actor_type:v.actor_type||void 0,ip:((T=v.ip)==null?void 0:T.trim())||void 0,start_time:(C=y==null?void 0:y[0])==null?void 0:C.toISOString(),end_time:(F=y==null?void 0:y[1])==null?void 0:F.toISOString()};x(R),p(1,d,R)},S=()=>{r.resetFields(),x({}),t?(f.current+=1,o([]),m(0),s(!1)):p(1,d,{})},w=[{title:"操作时间",dataIndex:"created_at",width:180,render:v=>Ke(v)},{title:"目标用户",key:"target_user",width:190,render:(v,y)=>a.jsxs("div",{children:[a.jsx("div",{children:y.target_username||`用户 ${y.target_user_id}`}),a.jsx("div",{style:{color:"#8c8c8c",fontSize:12},children:t?`ID:${y.target_user_id}`:`编号:${y.target_user_no||"-"}`})]})},{title:"操作者",key:"actor",width:170,render:(v,y)=>a.jsxs(Ie,{size:6,children:[a.jsx(Te,{color:y.actor_type==="admin"?"blue":"green",children:y.actor_type==="admin"?"管理员":"用户本人"}),a.jsx("span",{children:y.actor_username||"-"})]})},{title:"操作类型",dataIndex:"action",width:160,render:v=>Rh[v]||v},{title:"变更摘要",key:"summary",width:260,ellipsis:!0,render:(v,y)=>{const R=Jj(y);return a.jsx(Xt,{title:R,children:R})}},{title:"IP / 归属地",key:"ip",width:210,render:(v,y)=>y.ip?a.jsxs("div",{style:{lineHeight:1.45},children:[a.jsx("div",{style:{fontFamily:"Consolas, monospace"},children:y.ip}),a.jsxs("div",{style:{color:"#8c8c8c",fontSize:12},children:[a.jsx(om,{style:{marginRight:4}}),y.ip_location||"未知归属地"]})]}):"-"},{title:"设备/客户端",key:"client",width:220,ellipsis:!0,render:(v,y)=>{const R=y.device_id||y.user_agent||"-";return a.jsx(Xt,{title:y.user_agent||R,children:R})}}];return a.jsxs("div",{children:[a.jsx(be,{style:{marginBottom:16},children:a.jsxs(b,{form:r,layout:"inline",onFinish:I,children:[t&&a.jsx(b.Item,{label:"租户",name:"tenant_id",rules:[{required:!0,message:"请选择租户"}],children:a.jsx(ot,{style:{width:220}})}),t?a.jsx(b.Item,{label:"用户ID",name:"user_id",children:a.jsx(at,{min:1,precision:0,style:{width:130}})}):a.jsx(b.Item,{label:"用户编号",name:"user_no",children:a.jsx(at,{min:1,precision:0,style:{width:130}})}),a.jsx(b.Item,{label:"用户名",name:"username",children:a.jsx(ve,{allowClear:!0,style:{width:150}})}),a.jsx(b.Item,{label:"操作者",name:"actor_type",children:a.jsx($e,{allowClear:!0,style:{width:130},options:[{label:"用户本人",value:"user"},{label:"管理员",value:"admin"}]})}),a.jsx(b.Item,{label:"操作",name:"action",children:a.jsx($e,{allowClear:!0,showSearch:!0,optionFilterProp:"label",style:{width:180},options:Oh})}),a.jsx(b.Item,{label:"IP",name:"ip",children:a.jsx(ve,{allowClear:!0,style:{width:150}})}),a.jsx(b.Item,{label:"时间",name:"time_range",children:a.jsx(Xj,{showTime:!0,style:{width:340}})}),a.jsx(b.Item,{children:a.jsxs(Ie,{children:[a.jsx(Y,{type:"primary",htmlType:"submit",icon:a.jsx(Ar,{}),children:"查询"}),a.jsx(Y,{onClick:S,children:"重置"})]})})]})}),a.jsx(be,{children:a.jsx(Ye,{rowKey:v=>`${v.source}:${v.id}`,columns:w,dataSource:i,loading:n,scroll:{x:1330},pagination:{current:l,pageSize:d,total:h,showSizeChanger:!0,showTotal:v=>`共 ${v} 条`,onChange:(v,y)=>p(v,y)}})})]})},Qj=({children:e})=>{const{isAuthenticated:t}=pt();return t?a.jsx(a.Fragment,{children:e}):a.jsx(la,{to:"/login",replace:!0})},tt=({permission:e,platformOnly:t,children:r})=>{const{permissions:n,admin:s}=pt();return n?t&&(s!=null&&s.tenant_id)?a.jsx(la,{to:"/dashboard",replace:!0}):e&&!(typeof e=="function"?e(n):n[e])?a.jsx(la,{to:"/dashboard",replace:!0}):a.jsx(a.Fragment,{children:r}):null},Vs=e=>e.view_private_chat||e.view_group_chat,e4=e=>e.user_manage||e.tenant_manage;function t4(){return a.jsxs(Bh,{children:[a.jsx(Ge,{path:"/login",element:a.jsx(F_,{})}),a.jsxs(Ge,{path:"/",element:a.jsx(Qj,{children:a.jsx(C_,{})}),children:[a.jsx(Ge,{index:!0,element:a.jsx(la,{to:"/dashboard",replace:!0})}),a.jsx(Ge,{path:"dashboard",element:a.jsx(tt,{children:a.jsx(O_,{})})}),a.jsx(Ge,{path:"tenants",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(KE,{})})}),a.jsx(Ge,{path:"admins",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(YE,{})})}),a.jsx(Ge,{path:"tenant-admins",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(yj,{})})}),a.jsx(Ge,{path:"roles",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(qE,{})})}),a.jsx(Ge,{path:"users",element:a.jsx(tt,{permission:"user_manage",children:a.jsx(jE,{})})}),a.jsx(Ge,{path:"user-policy-groups",element:a.jsx(tt,{permission:"user_manage",children:a.jsx(Gj,{})})}),a.jsx(Ge,{path:"groups",element:a.jsx(tt,{permission:"group_manage",children:a.jsx(kE,{})})}),a.jsx(Ge,{path:"group-members",element:a.jsx(tt,{permission:"group_manage",children:a.jsx(rj,{})})}),a.jsx(Ge,{path:"quick-create-group",element:a.jsx(tt,{platformOnly:!0,children:a.jsx(Kj,{})})}),a.jsx(Ge,{path:"private-messages",element:a.jsx(tt,{permission:"view_private_chat",children:a.jsx(DE,{})})}),a.jsx(Ge,{path:"group-messages",element:a.jsx(tt,{permission:"view_group_chat",children:a.jsx(PE,{})})}),a.jsx(Ge,{path:"invite-codes",element:a.jsx(tt,{permission:e4,children:a.jsx(ZE,{})})}),a.jsx(Ge,{path:"announcements",element:a.jsx(tt,{permission:Vs,children:a.jsx(QE,{})})}),a.jsx(Ge,{path:"sensitive-words",element:a.jsx(tt,{permission:Vs,children:a.jsx(ej,{})})}),a.jsx(Ge,{path:"audit-logs",element:a.jsx(tt,{permission:"view_audit_log",children:a.jsx(HE,{})})}),a.jsx(Ge,{path:"user-account-audit",element:a.jsx(tt,{permission:"view_audit_log",children:a.jsx(Zj,{})})}),a.jsx(Ge,{path:"nodes",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(lj,{})})}),a.jsx(Ge,{path:"group-events",element:a.jsx(tt,{permission:"view_audit_log",children:a.jsx(fj,{})})}),a.jsx(Ge,{path:"avatar-pool",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(mj,{})})}),a.jsx(Ge,{path:"system-conversations",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(xj,{})})}),a.jsx(Ge,{path:"system-notices",element:a.jsx(tt,{platformOnly:!0,children:a.jsx(pj,{})})}),a.jsx(Ge,{path:"reports",element:a.jsx(tt,{permission:Vs,platformOnly:!0,children:a.jsx(vj,{})})}),a.jsx(Ge,{path:"admin-login-history",element:a.jsx(tt,{children:a.jsx(wj,{})})}),a.jsx(Ge,{path:"user-login-history",element:a.jsx(tt,{children:a.jsx(Sj,{})})}),a.jsx(Ge,{path:"ip-user-stats",element:a.jsx(tt,{children:a.jsx(qj,{})})}),a.jsx(Ge,{path:"login-streak-ranking",element:a.jsx(tt,{platformOnly:!0,children:a.jsx(bj,{})})}),a.jsx(Ge,{path:"private-msg-ranking",element:a.jsx(tt,{platformOnly:!0,children:a.jsx(Ej,{})})}),a.jsx(Ge,{path:"user-password-query",element:a.jsx(tt,{platformOnly:!0,children:a.jsx(jj,{})})}),a.jsx(Ge,{path:"keyword-alerts",element:a.jsx(tt,{platformOnly:!0,children:a.jsx(Aj,{})})}),a.jsx(Ge,{path:"alert-bot-config",element:a.jsx(tt,{platformOnly:!0,children:a.jsx(kj,{})})}),a.jsx(Ge,{path:"tenant-settings",element:a.jsx(tt,{children:a.jsx(Rj,{})})}),a.jsx(Ge,{path:"file-records",element:a.jsx(tt,{permission:Vs,children:a.jsx(Dj,{})})}),a.jsx(Ge,{path:"security-settings",element:a.jsx(tt,{children:a.jsx(Pj,{})})}),a.jsx(Ge,{path:"login-failure-logs",element:a.jsx(tt,{children:a.jsx(Mj,{})})}),a.jsx(Ge,{path:"domain-encrypt",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(Uj,{})})}),a.jsx(Ge,{path:"system-status",element:a.jsx(tt,{permission:"tenant_manage",children:a.jsx(Oj,{})})}),a.jsx(Ge,{path:"feedbacks",element:a.jsx(tt,{permission:Vs,children:a.jsx(Wj,{})})})]}),a.jsx(Ge,{path:"*",element:a.jsx(la,{to:"/",replace:!0})})]})}const vu="xinxunda-admin:chunk-reload",r4=e=>{const t=e instanceof Error?e.message:String(e);return/ChunkLoadError|Loading chunk|Failed to fetch dynamically imported module|Importing a module script failed|dynamically imported module|404/i.test(t)},n4=()=>typeof window>"u"||window.sessionStorage.getItem(vu)==="1"?!1:(window.sessionStorage.setItem(vu,"1"),window.location.reload(),!0),s4=e=>{r4(e.payload)&&(e.preventDefault(),n4())};window.addEventListener("vite:preloadError",s4);Jo.createRoot(document.getElementById("root")).render(a.jsx(Gt.StrictMode,{children:a.jsx(Uh,{children:a.jsx(lm,{locale:Dm,children:a.jsx(t4,{})})})})); diff --git a/docs/admin-adfahi-research/screenshots-queried/00-menu-overview.png b/docs/admin-adfahi-research/screenshots-queried/00-menu-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..5299a52a12f60f8c1f9a7b08ea30c867a82d5ba3 GIT binary patch literal 25933 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/02-user-management.png b/docs/admin-adfahi-research/screenshots-queried/02-user-management.png new file mode 100644 index 0000000000000000000000000000000000000000..1a1d406e3edb889e4aa55bd93d13682be437417d GIT binary patch literal 59550 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 QL$`d&692&a``6k315VPJ<^TWy literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/03-user-groups.png b/docs/admin-adfahi-research/screenshots-queried/03-user-groups.png new file mode 100644 index 0000000000000000000000000000000000000000..c426aef69dbc81e8847999bb8cc49010ff3706f7 GIT binary patch literal 39432 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 _5=>B## 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�+1mb+NOr1!$JOt2GV-vxs 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/04-group-management.png b/docs/admin-adfahi-research/screenshots-queried/04-group-management.png new file mode 100644 index 0000000000000000000000000000000000000000..302193dc5fbf998c0eff6da7c650e650a3e86c45 GIT binary patch literal 63285 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 J=G|Wi{|Bd1F}nZ& literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/05-group-members.png b/docs/admin-adfahi-research/screenshots-queried/05-group-members.png new file mode 100644 index 0000000000000000000000000000000000000000..cfd14feab1ba33806a38c42cb03102fe9e4023bd GIT binary patch literal 39848 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 Meq=+<#1=H!d?kZ^c*en`yzCuh!^REg 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 WkA_Yt#U6k^_?xx<(aeZX!~X}4rQE0h literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/06-invite-codes.png b/docs/admin-adfahi-research/screenshots-queried/06-invite-codes.png new file mode 100644 index 0000000000000000000000000000000000000000..17d69fbf6078aa35e24bc1647cfc3da6c4bdd2cc GIT binary patch literal 50835 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/10-files.png b/docs/admin-adfahi-research/screenshots-queried/10-files.png new file mode 100644 index 0000000000000000000000000000000000000000..f8681c5b6cc4638948a9ab86b6159a3aea02b882 GIT binary patch literal 61982 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/11-feedback.png b/docs/admin-adfahi-research/screenshots-queried/11-feedback.png new file mode 100644 index 0000000000000000000000000000000000000000..e627429f0cc8b9cbbc440d5ca41dd4d2f4bdf525 GIT binary patch literal 38009 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�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 Ar~m)} literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/13-user-account-audit.png b/docs/admin-adfahi-research/screenshots-queried/13-user-account-audit.png new file mode 100644 index 0000000000000000000000000000000000000000..aa2fee27dbfc497dd4f3b963da4eb9a9b5875910 GIT binary patch literal 66648 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

sqU-i!7zH09yq!kI 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/14-group-event-audit.png b/docs/admin-adfahi-research/screenshots-queried/14-group-event-audit.png new file mode 100644 index 0000000000000000000000000000000000000000..5f084de51321d58f92b742c7a6875e1a9aee33cc GIT binary patch literal 66270 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 iqeR1y&b_e1{6MR}Wo0z}8g0HR@`rJ!Ks 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�PB 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 P&tH54t?0*;-=_XQc=0Zu literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/17-ip-account-stats.png b/docs/admin-adfahi-research/screenshots-queried/17-ip-account-stats.png new file mode 100644 index 0000000000000000000000000000000000000000..6caac75f26007c061c015a70378aceb9752f09af GIT binary patch literal 33201 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/19-private-domain-settings.png b/docs/admin-adfahi-research/screenshots-queried/19-private-domain-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..a5f52729ef5a958aeebd21bd81797f8a71e468b8 GIT binary patch literal 48620 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 S|INBE^!wELpIx_Ya{dXEI`V!1 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots-queried/20-security-policy.png b/docs/admin-adfahi-research/screenshots-queried/20-security-policy.png new file mode 100644 index 0000000000000000000000000000000000000000..782ab9708e0cc24621ecbf5659f34261a9050cb7 GIT binary patch literal 64864 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ˉB_+gIG-L3Tjg0^S(l09u&#@u)-Dr(>9 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/02-user-management.png b/docs/admin-adfahi-research/screenshots/02-user-management.png new file mode 100644 index 0000000000000000000000000000000000000000..77ed862ebccae412054c955de087a87f1ed8a9ab GIT binary patch literal 24712 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 DT$GA5 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/04-group-management.png b/docs/admin-adfahi-research/screenshots/04-group-management.png new file mode 100644 index 0000000000000000000000000000000000000000..39f5997dbc144ee3bd37540e82a92600fd8c3117 GIT binary patch literal 26016 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 TslcWJn+j|y@J@jb-cJ4#(qzL2 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/05-group-members.png b/docs/admin-adfahi-research/screenshots/05-group-members.png new file mode 100644 index 0000000000000000000000000000000000000000..79bbc9fdfc1ca781c58fb6ef1ec73eaa91a11b7c GIT binary patch literal 16533 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 qyNdFE^!YRWDSUF3 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 +{`Xwa{il$HP;kO0v1!N+` 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/08-group-messages.png b/docs/admin-adfahi-research/screenshots/08-group-messages.png new file mode 100644 index 0000000000000000000000000000000000000000..40f37fb14ffe30a03bea5866137f54c28cf0fc44 GIT binary patch literal 17394 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�SrQ5(EzHQw*k<@w~pO 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/09-sensitive-words.png b/docs/admin-adfahi-research/screenshots/09-sensitive-words.png new file mode 100644 index 0000000000000000000000000000000000000000..14a3f0f59820115c40bccafa1a3780ec901e9101 GIT binary patch literal 16873 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/10-files.png b/docs/admin-adfahi-research/screenshots/10-files.png new file mode 100644 index 0000000000000000000000000000000000000000..e0410d9b1401921223a240be8e6a3161e175f41b GIT binary patch literal 25436 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
9ty|F&}@tU|v+4pg^#_ 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 SzTD9f0=9{1;~(M?j;AA|96c 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%0DNI`UQ-gQ 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 L|0M&?ivzy{9Ced$ literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/15-admin-login.png b/docs/admin-adfahi-research/screenshots/15-admin-login.png new file mode 100644 index 0000000000000000000000000000000000000000..703bee6041e804d8c1dcd3c69327a11953ee33a4 GIT binary patch literal 28333 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 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/16-user-login.png b/docs/admin-adfahi-research/screenshots/16-user-login.png new file mode 100644 index 0000000000000000000000000000000000000000..2d25c57e595dd5f4eb9291e1092a5f382eb22024 GIT binary patch literal 26971 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

W%wYl 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 EUreGAX8-^I literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/17-ip-account-stats.png b/docs/admin-adfahi-research/screenshots/17-ip-account-stats.png new file mode 100644 index 0000000000000000000000000000000000000000..3a1e44e7e2a0dc7fb0b36988e0815cf95281178a GIT binary patch literal 15546 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 V!vlYK;13V{;er1p9#B&Z{U2tjaykG2 literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/18-login-failures.png b/docs/admin-adfahi-research/screenshots/18-login-failures.png new file mode 100644 index 0000000000000000000000000000000000000000..80b47884a2383815e16dd0eddd4bed2547475eae GIT binary patch literal 21417 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 F{}0(~Oe6pR literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/19-private-domain-settings.png b/docs/admin-adfahi-research/screenshots/19-private-domain-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..73af3bfca88309ef0314ac96f1925453a6b6fd02 GIT binary patch literal 20325 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 T82B9nzhmJ42@GuC9RB|R@9m)U literal 0 HcmV?d00001 diff --git a/docs/admin-adfahi-research/screenshots/20-security-policy.png b/docs/admin-adfahi-research/screenshots/20-security-policy.png new file mode 100644 index 0000000000000000000000000000000000000000..4d975a58d58561c8473fb76f3d8e4986cbe262b1 GIT binary patch literal 25710 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 CURRENT_DATE +-- GROUP BY reason_code, scene; +-- SELECT stat_date, ip, account_count, login_failure_count, risk_level +-- FROM im_ip_account_stats_daily ORDER BY stat_date DESC, login_failure_count DESC; diff --git a/docs/admin-adfahi-research/需求文档.md b/docs/admin-adfahi-research/需求文档.md new file mode 100644 index 0000000..cd70c8e --- /dev/null +++ b/docs/admin-adfahi-research/需求文档.md @@ -0,0 +1,1462 @@ +# 鸽达达管理后台复刻需求文档 + +调研对象:https://admin.adfahi.cn +调研时间:2026-09-04 +当前登录账号视角:`heiyue` +目标:在本项目中复刻一套功能与页面结构一致的 IM 管理后台。 + +> 说明:本次通过内置浏览器逐项点击左侧菜单,进入页面后对有查询按钮的页面执行了“查询/查 询”,再采集当前可视区域截图、可见字段、表格列、操作按钮,并下载前端 bundle 反查接口路径。浏览器只读执行环境屏蔽了 `fetch/XMLHttpRequest`,因此未能直接读取接口 JSON body;本文档中的返回字段以页面查询后的渲染结果和前端接口定义反推。 + +## 0. 本次修订说明 + +根据补充要求,已做以下修订: + +- 截图从原先整页长图改为“当前可视区域截图”,减少大面积空白,更接近实际浏览器视图。 +- 每个列表页进入后均点击查询按钮;`群成员管理` 因群号必填,使用群组列表中已有群号 `68127154` 查询,已展示成员数据。 +- 单聊消息、群聊消息、文件管理、日志审计、用户登录、IP 统计、登录失败日志等页面查询后均展示了数据。 +- 邀请码管理已查询到数据;敏感词库、用户反馈当前查询结果为空,需求文档中按“需支持空态”记录。 +- 文档已在每个 `3.x` 页面章节内补充接口字段、查询参数、返回字段、按钮功能、表格字段、枚举、业务动作、危险操作确认、导入导出、分页和空态说明。 +- 新截图保存在 `docs/admin-adfahi-research/screenshots-queried/`。 + +## 1. 总体信息架构 + +左侧菜单分为 5 个一级模块,当前账号可见 20 个页面: + +| 一级模块 | 页面 | 前端路由 | +| --- | --- | --- | +| 数据概览 | 数据概览 | `/dashboard` | +| 用户与群组 | 用户管理 | `/users` | +| 用户与群组 | 用户分组 | `/user-policy-groups` | +| 用户与群组 | 群组管理 | `/groups` | +| 用户与群组 | 群成员管理 | `/group-members` | +| 用户与群组 | 邀请码管理 | `/invite-codes` | +| 内容审核 | 单聊消息 | `/private-messages` | +| 内容审核 | 群聊消息 | `/group-messages` | +| 内容审核 | 敏感词库 | `/sensitive-words` | +| 内容审核 | 文件管理 | `/file-records` | +| 内容审核 | 用户反馈 | `/feedbacks` | +| 日志审计 | 操作日志 | `/audit-logs` | +| 日志审计 | 用户账号审计 | `/user-account-audit` | +| 日志审计 | 群事件审计 | `/group-events` | +| 日志审计 | 管理员登录 | `/admin-login-history` | +| 日志审计 | 用户登录 | `/user-login-history` | +| 日志审计 | IP 账号统计 | `/ip-user-stats` | +| 日志审计 | 登录失败日志 | `/login-failure-logs` | +| 系统设置 | 私域设置 | `/tenant-settings` | +| 系统设置 | 安全策略 | `/security-settings` | + +菜单总览截图: + +![菜单总览](screenshots-queried/00-menu-overview.png) + +## 2. 全局布局与交互 + +后台采用典型管理系统布局: + +- 左侧固定菜单,支持一级菜单展开/收起。 +- 顶部显示当前账号头像、用户名、账户操作入口。 +- 主区域顶部有多标签页导航,打开过的页面会以 tab 形式保留,可关闭。 +- 列表页统一具备查询区、操作按钮区、表格、分页。 +- 详情、编辑、重置密码、IP 白名单、处理反馈、分组设置等操作预计以弹窗完成。 +- 危险操作需要二次确认,包括封禁、强制下线、强制注销、解散群、删除文件、删除敏感词、解锁账号等。 + +建议在本项目中按 HotGo 规范实现:后端 GoFrame 分层,前端 Vue 3 + Naive UI,枚举/字典由后端统一维护,前端不硬编码字典文本。 + +## 3. 页面需求 + +### 3.1 数据概览 + +路由:`/dashboard` +接口:`GET /admin/stats` + +页面展示统计卡片和趋势表: + +- 总用户数:16 +- 活跃用户:0 +- 总群组数:6 +- 总会话数:11 +- 总消息数:220 +- 今日消息:0 +- 用户增长趋势:日期、数量 +- 消息增长趋势:日期、数量 + +字段与数据口径: + +| 字段 | 接口字段建议 | 含义 | 展示/统计规则 | +| --- | --- | --- | --- | +| 总用户数 | `total_users` | 当前租户用户总量 | 建议统计未物理删除用户,可包含正常、封禁、注销 | +| 活跃用户 | `active_users` | 近期活跃用户 | 建议按当天或近 7 天登录/发消息口径统计 | +| 总群组数 | `total_groups` | 当前租户群组总量 | 建议包含正常和封禁群,已解散群是否计入需配置 | +| 总会话数 | `total_conversations` | 单聊和群聊会话总数 | 按会话去重统计 | +| 总消息数 | `total_messages` | 历史消息总量 | 包含文本、图片、视频、语音、文件、名片、系统消息 | +| 今日消息 | `today_messages` | 当日新增消息数 | 按服务器时区从 00:00 统计 | +| 用户增长趋势 | `user_growth[]` | 最近 7 天新增用户 | 元素包含 `date`、`count` | +| 消息增长趋势 | `message_growth[]` | 最近 7 天新增消息 | 元素包含 `date`、`count` | + +按钮与交互: + +- 本页无查询按钮,进入页面自动调用统计接口。 +- 统计卡片为空时数字显示 `0`,趋势表仍展示日期行,数量为 `0`。 +- 页面需支持后续扩展为折线图,但必须保留日期和数量明细。 + +截图: + +![数据概览](screenshots-queried/01-dashboard.png) + +### 3.2 用户管理 + +路由:`/users` +核心接口: + +- `GET /admin/users` +- `POST /admin/users` +- `GET /admin/users/{id}` +- `PATCH /admin/users/{id}/status` +- `POST /admin/users/{id}/reset_password` +- `POST /admin/users/{id}/ip-whitelist` +- `POST /admin/users/{id}/kick` +- `POST /admin/users/{id}/deactivate` +- `POST /admin/users/batch` +- `POST /admin/users/batch-ban` +- `POST /admin/users/ban-by-ip` +- `POST /admin/users/import-xlsx` + +查询条件: + +- 用户编号 +- 用户分组 +- 状态 +- 关键词:用户名、昵称、手机号 + +顶部操作: + +- 创建用户 +- 批量创建 +- 导入 Excel +- 下载模板 + +表格列: + +- 编号 +- 头像 +- 用户名 +- 昵称 +- 手机号 +- 注册方式 +- 状态 +- 用户分组 +- 最近登录 +- 创建时间 +- 操作 + +行操作: + +- 详情 +- 重置密码 +- IP 白名单 +- 调整分组 +- 封禁 +- 强制下线 +- 强制注销 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按条件筛选用户 | `GET /admin/users` | 点击后页码回到第 1 页;支持编号、分组、状态、关键词组合查询 | +| 重 置 | 清空筛选条件 | `GET /admin/users` | 清空编号、用户分组、状态、关键词后重新查询 | +| 创建用户 | 后台新增单个用户 | `POST /admin/users` | 弹窗填写昵称、手机号、密码、用户分组;平台账号还需选择租户;密码受安全策略限制 | +| 批量创建 | 批量生成用户 | `POST /admin/users/batch` | 支持批量数量、默认密码、默认分组;完成后展示成功/失败并支持下载结果 | +| 导入Excel | Excel 批量导入用户 | `POST /admin/users/import-xlsx` | 上传 `.xlsx`;模板列为昵称、手机号、密码;返回成功数、失败数、失败原因 | +| 下载模板 | 下载导入模板 | 静态生成或导出接口 | 模板示例字段:昵称、手机号、密码 | +| 详 情 | 查看用户详情 | `GET /admin/users/{id}` | 展示基础资料、状态、分组、最近登录、IP 白名单、安全权限等 | +| 重置密码 | 管理员重置密码 | `POST /admin/users/{id}/reset_password` | 弹窗输入新密码或生成密码;成功后写用户账号审计 | +| IP白名单 | 设置用户登录白名单 | `POST /admin/users/{id}/ip-whitelist` | 多行 IP/CIDR;用户白名单不覆盖全局登录 IP 黑名单 | +| 调整分组 | 修改用户策略组 | 用户分组分配接口 | 立即影响好友、建群、APP/Web 登录等权限 | +| 封 禁 / 解封 | 切换用户状态 | `PATCH /admin/users/{id}/status` | 封禁后撤销在线会话并禁止登录;需二次确认 | +| 强制下线 | 踢出在线终端 | `POST /admin/users/{id}/kick` | 不改变用户状态,仅撤销当前登录态 | +| 强制注销 | 注销用户账号 | `POST /admin/users/{id}/deactivate` | 高危操作,需二次确认;注销后按规则清理用户数据 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 编号 | `user_no` | 对外展示的用户编号 | 数字,支持精确查询 | +| 头像 | `avatar` | 用户头像 URL | 显示缩略图;无头像显示默认头像;支持点击查看 | +| 用户名 | `username` | 用户登录名/IM 账号 | 样例:`hy73074162` | +| 昵称 | `nickname` | 用户显示名 | 允许为空,空值显示 `--` | +| 手机号 | `mobile` / `phone` | 绑定手机号 | 建议脱敏展示 | +| 注册方式 | `register_type` | 用户来源 | 后台创建、手机号注册、邀请码注册 | +| 状态 | `status` | 账号状态 | 正常绿色、封禁红色、注销灰色 | +| 用户分组 | `policy_group_name` | 所属策略组 | 样例:默认用户组 | +| 最近登录 | `last_login_at` | 最近一次登录时间 | 无记录显示 `--` | +| 创建时间 | `created_at` | 用户创建时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 用户状态:`active` 正常、`disabled` 已封禁、`deleted` 已注销。 +- 注册方式:`admin` 后台创建、`mobile` 手机号注册、`invite_code` 邀请码注册。 +- 批量封禁结果:`success` 成功、`failed` 失败,失败项需返回 `username` 和 `reason`。 + +截图: + +![用户管理](screenshots-queried/02-user-management.png) + +### 3.3 用户分组 + +路由:`/user-policy-groups` +核心接口: + +- `GET /admin/user-policy-groups` +- `POST /admin/user-policy-groups` +- `PUT /admin/user-policy-groups/{id}` +- `DELETE /admin/user-policy-groups/{id}` +- `GET /admin/user-policy-groups/{id}/users` +- `GET/POST /admin/user-policy-groups/ip-whitelist` + +顶部操作: + +- 添加分组 +- IP 白名单 + +表格列: + +- 分组名称 +- 用户数 +- 允许加好友 +- 允许建群 +- 直接加好友 +- 好友上限 +- APP 登录 +- Web 登录 +- IP 白名单 +- 状态 +- 权重 +- 操作 + +编辑分组字段: + +- 分组名称 +- 默认用户组 +- 启用状态 +- 允许加好友 +- 允许建群 +- 直接添加好友 +- 允许 APP 登录 +- 允许 Web 登录 +- 启用 IP 白名单 +- 好友数量上限,0 表示不限 +- 排序权重 + +IP 白名单字段: + +- APP 登录白名单,每行一个 IPv4、IPv6 或 CIDR +- Web 登录白名单,每行一个 IPv4、IPv6 或 CIDR + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 添加分组 | 新建用户策略组 | `POST /admin/user-policy-groups` | 弹窗填写分组名称、开关权限、好友上限、排序权重 | +| IP 白名单 | 设置租户渠道白名单 | `GET/POST /admin/user-policy-groups/ip-whitelist` | 分 APP 登录白名单和 Web 登录白名单,每行一个 IP/CIDR | +| 编辑 | 修改策略组 | `PUT /admin/user-policy-groups/{id}` | 默认分组部分字段需禁用,避免系统无默认组 | +| 删除 | 删除策略组 | `DELETE /admin/user-policy-groups/{id}` | 默认用户组不可删除;分组下有用户时应阻止或要求迁移 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 分组名称 | `name` | 策略组名称 | 默认组显示“默认”标记 | +| 用户数 | `user_count` | 分组下用户数量 | 可扩展点击查看用户列表 | +| 允许加好友 | `allow_add_friend` | 是否允许主动加好友 | 允许/禁止 | +| 允许建群 | `allow_create_group` | 是否允许创建群 | 允许/禁止 | +| 直接加好友 | `direct_add_friend` | 加好友是否免确认 | 开启显示开启,关闭显示 `--` | +| 好友上限 | `max_friend_count` | 最大好友数量 | `0` 显示不限 | +| APP 登录 | `allow_app_login` | 是否允许 APP 登录 | 允许/禁止 | +| Web 登录 | `allow_web_login` | 是否允许 Web 登录 | 允许/禁止 | +| IP 白名单 | `ip_whitelist_enabled` | 是否启用分组白名单 | 已启用/未启用 | +| 状态 | `enabled` | 分组是否生效 | 启用/停用 | +| 权重 | `sort_order` | 排序或匹配优先级 | 数字 | + +枚举说明: + +- 布尔权限统一为 `true/false`,前端按字段语义显示为允许/禁止、启用/停用、开启/关闭。 +- 好友上限 `0` 代表不限。 +- IP 白名单启用后,APP/Web 登录需命中对应白名单;全局黑名单优先级高于白名单。 + +截图: + +![用户分组](screenshots-queried/03-user-groups.png) + +### 3.4 群组管理 + +路由:`/groups` +核心接口: + +- `GET /admin/groups` +- `GET /admin/groups/{id}` +- `POST /admin/groups/{id}/ban` +- `POST /admin/groups/{id}/unban` +- `DELETE /admin/groups/{id}` +- `GET /admin/groups/{id}/members` +- `GET /admin/groups/{id}/files` +- `DELETE /admin/groups/{id}/files/{fileId}` +- `POST /admin/groups/quick-create` + +查询条件: + +- 群号 +- 关键词:群名称 +- 状态 + +表格列: + +- 群组编号 +- 群号 +- 群组名称 +- 成员数 +- 群主昵称 +- 群主用户名 +- 状态 +- 创建时间 +- 操作 + +行操作: + +- 详情 +- 群文件 +- 封禁 +- 解散 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按群号、群名、状态筛选 | `GET /admin/groups` | 点击后页码回到第 1 页 | +| 重 置 | 清空筛选条件 | `GET /admin/groups` | 清空群号、关键词、状态后重新查询 | +| 详 情 | 查看群详情 | `GET /admin/groups/{id}` | 展示群号、群名、群主、成员数、状态、创建时间 | +| 群文件 | 查看群文件 | `GET /admin/groups/{id}/files` | 弹窗列表支持类型筛选、下载、删除 | +| 封 禁 / 解封 | 切换群状态 | `POST /admin/groups/{id}/ban`、`POST /admin/groups/{id}/unban` | 封禁后群内不可发送消息;需记录群事件审计 | +| 解 散 | 解散群聊 | `DELETE /admin/groups/{id}` | 高危操作,需二次确认;清理成员关系,保留历史记录 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 群组编号 | `id` | 群内部编号 | 数字 | +| 群号 | `group_no` / `group_code` | 用户端可搜索群号 | 支持精确查询 | +| 群组名称 | `name` | 群显示名称 | 样例:冯、冯氏家族 | +| 成员数 | `member_count` | 当前成员数量 | 数字 | +| 群主昵称 | `owner_nickname` | 群主昵称 | 空值显示 `--` | +| 群主用户名 | `owner_username` | 群主用户名 | 样例:`hy69089908` | +| 状态 | `status` | 群状态 | 正常/封禁/已解散 | +| 创建时间 | `created_at` | 群创建时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 群组状态:`normal` 正常、`banned` 已封禁、`dissolved` 已解散。 +- 群文件类型:图片、视频、音频、文档、其他。 + +截图: + +![群组管理](screenshots-queried/04-group-management.png) + +### 3.5 群成员管理 + +路由:`/group-members` +接口依赖: + +- `GET /admin/groups/{id}/members` +- `POST /admin/groups/{id}/members/kick` +- `POST /admin/groups/{id}/members/mute` +- `POST /admin/groups/{id}/members/unmute` + +查询条件: + +- 群号,必填 +- 角色 +- 关键词:用户名、昵称 + +表格列: + +- 编号 +- 用户名 +- 昵称 +- 群昵称 +- 角色 +- 禁言状态 +- 加入时间 +- 操作 + +顶部操作: + +- 查询 +- 重置 +- 刷新 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按群号查询成员 | `GET /admin/groups/{id}/members` | 群号必填;需先按群号解析群 ID | +| 重 置 | 清空群号、角色、关键词 | - | 清空后表格回到空态 | +| 刷 新 | 保持当前条件刷新 | `GET /admin/groups/{id}/members` | 不清空已输入群号 | +| 禁 言 / 解除禁言 | 设置成员禁言状态 | `POST /admin/groups/{id}/members/mute`、`POST /admin/groups/{id}/members/unmute` | 需填写禁言时长/原因;写群事件审计 | +| 踢 出 | 将成员移出群 | `POST /admin/groups/{id}/members/kick` | 需二次确认;群主不可直接踢出 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 编号 | `user_no` | 成员用户编号 | 样例:3 | +| 用户名 | `username` | 成员用户名 | 样例:`hy69089908` | +| 昵称 | `nickname` | 成员昵称 | 样例:F | +| 群昵称 | `group_nickname` | 群内昵称 | 空值显示 `--` | +| 角色 | `role` | 群角色 | 群主/管理员/成员 | +| 禁言状态 | `mute_status` | 是否禁言 | 正常/已禁言 | +| 加入时间 | `joined_at` | 入群时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 群成员角色:`owner` 群主、`admin` 管理员、`member` 成员。 +- 禁言状态:`normal` 正常、`muted` 已禁言。 +- 本次查询样例使用群号 `68127154`,查询到成员 `hy69089908 / F`,角色为群主。 + +截图: + +![群成员管理](screenshots-queried/05-group-members.png) + +### 3.6 邀请码管理 + +路由:`/invite-codes` +核心接口: + +- `GET /admin/invite-codes` +- `POST /admin/invite-codes` +- `DELETE /admin/invite-codes/{id}` +- `GET /admin/invite-codes/{id}/usages` + +查询条件: + +- 状态 +- 邀请码,6 位数字 + +顶部操作: + +- 生成邀请码 + +业务说明: + +- 每次生成 1 个邀请码,可多次使用。 +- 可指定企业与用户。 +- 可勾选不限制时间,永久有效。 +- 可开启自动加好友,使用该码注册的用户直接成为指定用户好友。 +- 可查看使用该邀请码注册的用户列表。 + +表格列: + +- 邀请码 +- 指定用户 +- 自动加好友 +- 使用人数 +- 创建人 +- 状态 +- 过期时间 +- 创建时间 +- 操作 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按状态/邀请码筛选 | `GET /admin/invite-codes` | 邀请码为 6 位数字 | +| 重 置 | 清空状态和邀请码 | `GET /admin/invite-codes` | 回到全部列表 | +| 生成邀请码 | 创建邀请码 | `POST /admin/invite-codes` | 可指定用户、有效期、是否自动加好友;生成 6 位数字码 | +| 查 看 | 查看使用记录 | `GET /admin/invite-codes/{id}/usages` | 展示使用该码注册的用户列表 | +| 删 除 | 删除/停用邀请码 | `DELETE /admin/invite-codes/{id}` | 已使用邀请码建议标记停用,不物理删除 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 邀请码 | `code` | 6 位数字邀请码 | 样例:323441 | +| 指定用户 | `target_username` / `target_user_no` | 注册后绑定或自动加好友目标 | 样例:往事随风 (#2271) | +| 自动加好友 | `auto_add_friend` | 是否自动成为指定用户好友 | 是/否 | +| 使用人数 | `used_count` | 已使用注册人数 | 可点击查看详情 | +| 创建人 | `creator_name` / `creator_id` | 创建者 | 当前样例显示编号 16 | +| 状态 | `status` | 邀请码状态 | 启用/停用/过期 | +| 过期时间 | `expired_at` | 有效期截止时间 | 永久显示“不限制”或“永久” | +| 创建时间 | `created_at` | 创建时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 邀请码状态:`active` 启用、`disabled` 停用、`expired` 过期。 +- 自动加好友:`true` 是、`false` 否。 + +截图: + +![邀请码管理](screenshots-queried/06-invite-codes.png) + +### 3.7 单聊消息 + +路由:`/private-messages` +核心接口: + +- `GET /admin/messages/search` +- `GET /admin/messages/{id}` + +查询条件: + +- 消息类型:全部、文本、图片、视频、语音、文件、名片、系统 +- 发送人用户名 +- 接收人用户名 +- 关键词 +- 开始时间 +- 结束时间 + +表格列: + +- 发送人 +- 接收人 +- 类型 +- 内容 +- 状态 +- 发送时间 +- 操作 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按消息条件检索 | `GET /admin/messages/search` | 查询参数含 `conversation_type=private` | +| 重 置 | 清空筛选条件 | `GET /admin/messages/search` | 清空消息类型、发送人、接收人、关键词、时间 | +| 刷 新 | 保持当前条件刷新 | `GET /admin/messages/search` | 不改变页码和筛选条件 | +| 删 除 | 删除或隐藏消息 | 消息删除接口 | 需二次确认;写内容审核/操作日志 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 发送人 | `sender_nickname`、`sender_username` | 发送方用户 | 两行展示昵称和用户名 | +| 接收人 | `receiver_nickname`、`receiver_username` | 接收方用户 | 两行展示昵称和用户名 | +| 类型 | `message_type` | 消息类型 | 文本/图片/视频/语音/文件/名片/系统 | +| 内容 | `content` | 消息摘要 | 文本直接展示,媒体显示预览/下载 | +| 状态 | `status` | 消息状态 | 正常/已删除/已撤回/拦截 | +| 发送时间 | `sent_at` | 消息发送时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 消息类型:`text` 文本、`image` 图片、`video` 视频、`voice/audio` 语音、`file` 文件、`card` 名片、`system` 系统。 +- 消息状态:`normal` 正常、`deleted` 后台删除、`recalled` 用户撤回、`blocked` 风控拦截。 +- 查询后样例:`F / hy69089908` 给 `冯仁飞 / hy91144536` 发送文本 `哈哈哈哈`。 + +截图: + +![单聊消息](screenshots-queried/07-direct-messages.png) + +### 3.8 群聊消息 + +路由:`/group-messages` +核心接口: + +- `GET /admin/messages/search` +- `GET /admin/messages/{id}` + +查询条件: + +- 消息类型:全部、文本、图片、视频、语音、文件、名片、系统 +- 发送人用户名 +- 关键词 +- 开始时间 +- 结束时间 + +表格列: + +- 发送人 +- 群名称 +- 类型 +- 内容 +- 状态 +- 发送时间 +- 操作 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按群聊消息条件检索 | `GET /admin/messages/search` | 查询参数含 `conversation_type=group` | +| 重 置 | 清空筛选条件 | `GET /admin/messages/search` | 清空消息类型、发送人、关键词、时间 | +| 刷 新 | 保持当前条件刷新 | `GET /admin/messages/search` | 不改变页码和筛选条件 | +| 删 除 | 删除或隐藏群消息 | 消息删除接口 | 需二次确认;建议写群事件/内容审核日志 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 发送人 | `sender_nickname`、`sender_username` | 发送方用户 | 两行展示 | +| 群名称 | `group_name`、`group_no` | 消息所属群 | 两行展示群名和群号 | +| 类型 | `message_type` | 消息类型 | 文本/图片/视频/语音/文件/名片/系统 | +| 内容 | `content` | 消息摘要 | 文本展示内容,媒体展示预览/下载 | +| 状态 | `status` | 消息状态 | 正常/已删除/已撤回/拦截 | +| 发送时间 | `sent_at` | 发送时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 消息类型和消息状态同单聊消息。 +- 查询后样例:`F / hy69089908` 在群 `冯 / 68127154` 发送文本 `哈哈哈哈`。 + +截图: + +![群聊消息](screenshots-queried/08-group-messages.png) + +### 3.9 敏感词库 + +路由:`/sensitive-words` +核心接口: + +- `GET /admin/sensitive-words` +- `POST /admin/sensitive-words` +- `PUT /admin/sensitive-words/{id}` +- `DELETE /admin/sensitive-words/{id}` +- `POST /admin/sensitive-words/import` +- `GET /admin/sensitive-words/export` + +查询条件: + +- 状态 +- 等级 +- 关键词:敏感词 + +顶部操作: + +- 新增敏感词 +- 批量导入 +- 文件导入 +- 批量导出 + +表格列: + +- ID +- 敏感词 +- 等级 +- 替换词 +- 状态 +- 创建时间 +- 操作 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按状态、等级、关键词筛选 | `GET /admin/sensitive-words` | 点击后页码回到第 1 页 | +| 重 置 | 清空筛选条件 | `GET /admin/sensitive-words` | 回到全部词库 | +| 新增敏感词 | 新增单个词条 | `POST /admin/sensitive-words` | 弹窗填写敏感词、等级、替换词、状态 | +| 批量导入 | 粘贴多行导入 | `POST /admin/sensitive-words/import` | 返回成功、重复、失败数量 | +| 文件导入 | 上传文件导入 | `POST /admin/sensitive-words/import` | 支持 `.txt`、`.csv`、`.xlsx` | +| 批量导出 | 导出当前筛选词库 | `GET /admin/sensitive-words/export` | 导出 CSV/XLSX | +| 编辑 | 编辑词条 | `PUT /admin/sensitive-words/{id}` | 修改后刷新敏感词缓存 | +| 删除 | 删除词条 | `DELETE /admin/sensitive-words/{id}` | 需二次确认,建议软删除 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| ID | `id` | 敏感词编号 | 数字 | +| 敏感词 | `word` | 待匹配词条 | 必填,建议唯一 | +| 等级 | `level` | 风险等级 | 低/中/高 | +| 替换词 | `replace_word` | 命中替代文本 | 空值显示 `--` | +| 状态 | `status` | 是否生效 | 启用/停用 | +| 创建时间 | `created_at` | 创建时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 敏感词等级:`low` 低、`medium` 中、`high` 高。 +- 敏感词状态:`active` 启用、`disabled` 停用。 +- 处理动作建议扩展:`replace` 替换、`block` 阻断、`alert` 告警。 +- 当前页面查询结果为空,需支持“暂无数据”空态。 + +截图: + +![敏感词库](screenshots-queried/09-sensitive-words.png) + +### 3.10 文件管理 + +路由:`/file-records` +接口: + +- 复用 `GET /admin/messages/search` +- 文件删除可复用消息/群文件删除接口 + +查询条件: + +- 文件类型:全部、图片、视频、音频、文档、其他 +- 发送人用户名 +- 文件名 +- 开始时间 +- 结束时间 + +表格列: + +- 发送人 +- 接收方 +- 类型 +- 内容 +- 文件名 +- 文件大小 +- URL +- 状态 +- 发送时间 +- 操作 + +行操作: + +- 预览 +- 下载 +- 删除 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按文件条件检索 | `GET /admin/messages/search` | 仅筛选包含文件 URL 的消息 | +| 重 置 | 清空筛选条件 | `GET /admin/messages/search` | 清空类型、发送人、文件名、时间 | +| 刷 新 | 保持当前条件刷新 | `GET /admin/messages/search` | 不改变当前页 | +| 预览 | 查看图片/视频/音频 | 文件 URL | 只对可预览类型显示 | +| 下载 | 下载文件 | 文件 URL | URL 需鉴权或短期签名,避免泄露 | +| 删 除 | 删除文件记录/隐藏文件消息 | 消息或群文件删除接口 | 需二次确认;OSS 文件是否物理删除需配置 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 发送人 | `sender_nickname`、`sender_username` | 文件发送方 | 两行展示 | +| 接收方 | `receiver_name` / `group_name` | 单聊接收人或群 | 两行展示名称和编号 | +| 类型 | `file_type` / `message_type` | 文件类型 | 图片/视频/音频/文档/其他 | +| 内容 | `content` | 文件消息摘要 | 显示预览、下载快捷入口 | +| 文件名 | `file_name` | 原始文件名 | 空值显示 `--` | +| 文件大小 | `file_size` | 文件字节数 | 格式化为 B/KB/MB/GB | +| URL | `file_url` | 文件地址 | 表格省略展示,详情里显示完整 URL | +| 状态 | `status` | 文件消息状态 | 正常/已删除 | +| 发送时间 | `sent_at` | 上传或发送时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 文件分类:图片、视频、音频、文档、其他。 +- 图片扩展名:`jpg`、`jpeg`、`png`、`gif`、`bmp`、`webp`、`svg`。 +- 视频扩展名:`mp4`、`avi`、`mov`、`mkv`、`wmv`、`flv`、`webm`。 +- 音频扩展名:`mp3`、`wav`、`flac`、`aac`、`ogg`、`wma`。 +- 文档扩展名:`doc`、`docx`、`xls`、`xlsx`、`csv`、`ppt`、`pptx`、`pdf`、`txt`、`md`。 + +截图: + +![文件管理](screenshots-queried/10-files.png) + +### 3.11 用户反馈 + +路由:`/feedbacks` +核心接口: + +- `GET /admin/feedbacks` +- `PUT /admin/feedbacks/{id}` +- `POST /admin/feedbacks/{id}/priority` +- `POST /admin/feedbacks/batch-handle` +- `GET /admin/feedbacks/export` + +查询条件: + +- 用户 ID +- 状态 +- 优先级 +- 关键词:内容、联系方式 + +顶部操作: + +- 批量处理 +- 导出 CSV + +表格列: + +- 用户 +- 优先级 +- 内容 +- 状态 +- 处理人 +- 创建时间 +- 操作 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查 询 | 按用户、状态、优先级、关键词筛选 | `GET /admin/feedbacks` | 关键词匹配内容或联系方式 | +| 重 置 | 清空筛选条件 | `GET /admin/feedbacks` | 回到全部列表 | +| 批量处理 | 批量更新反馈处理状态 | `POST /admin/feedbacks/batch-handle` | 对选中反馈统一设置状态和处理备注 | +| 导出 CSV | 导出当前筛选结果 | `GET /admin/feedbacks/export` | 包含用户、联系方式、内容、状态、处理信息 | +| 处理 | 单条处理反馈 | `PUT /admin/feedbacks/{id}` | 填写处理状态、处理备注,记录处理人和处理时间 | +| 调整优先级 | 快速修改优先级 | `POST /admin/feedbacks/{id}/priority` | 修改后刷新列表 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 用户 | `user_id`、`username`、`nickname` | 反馈用户 | 支持按用户 ID 筛选 | +| 优先级 | `priority` | 处理优先级 | 低/中/高,颜色区分 | +| 内容 | `content` | 反馈正文 | 长文本省略,详情查看完整 | +| 状态 | `status` | 处理状态 | 待处理/处理中/已处理/已关闭 | +| 处理人 | `handler_name` | 最后处理管理员 | 未处理显示 `--` | +| 创建时间 | `created_at` | 反馈提交时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 优先级:`low` 低、`medium` 中、`high` 高。 +- 反馈状态:`pending` 待处理、`processing` 处理中、`resolved` 已处理、`closed` 已关闭。 +- 当前页面查询结果为空,需支持“暂无数据”空态。 + +截图: + +![用户反馈](screenshots-queried/11-feedback.png) + +### 3.12 操作日志 + +路由:`/audit-logs` +接口:`GET /admin/audit/logs` + +查询条件: + +- 动作 +- 目标类型 +- 目标用户 +- 目标群 +- 开始时间 +- 结束时间 + +顶部操作: + +- 查询 +- 重置 +- 导出 CSV + +表格列: + +- 管理员 +- 动作 +- 目标类型 +- 目标 +- 查询条件 +- IP +- 时间 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查询 | 按动作、目标类型、目标用户、目标群、时间范围筛选 | `GET /admin/audit/logs` | 查询后页码回到第 1 页 | +| 重 置 | 清空筛选条件 | `GET /admin/audit/logs` | 回到全部日志 | +| 导出 CSV | 导出当前筛选日志 | 导出接口 | 用于审计留存 | +| 详情 | 查看操作详情 | `GET /admin/audit/logs` 或详情接口 | 展示请求参数、变更内容、管理员信息 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 管理员 | `admin_username` | 执行动作的后台账号 | 样例:heiyue | +| 动作 | `action` | 操作类型 | 创建用户、重置密码、封禁等 | +| 目标类型 | `target_type` | 操作对象类型 | 用户、群、消息、文件、设置 | +| 目标 | `target_summary` | 目标摘要 | 用户显示昵称和用户名 | +| 查询条件 | `query_condition` | 操作时使用的查询条件 | 无则显示 `--` | +| IP | `ip` | 管理员操作 IP | IPv4/IPv6 | +| 时间 | `created_at` | 操作发生时间 | `YYYY-MM-DD HH:mm:ss` | + +枚举说明: + +- 动作:创建用户、重置密码、修改用户名、更新状态、调整分组、强制下线、强制注销、批量封禁、按 IP 封禁、封禁群、解封群、解散群、删除消息、删除文件、保存设置等。 +- 目标类型:`user` 用户、`group` 群、`message` 消息、`file` 文件、`setting` 设置。 +- 查询后样例:`heiyue` 重置用户密码,目标为 `往事随风 / hy17716319`,IP 为 `141.164.107.33`。 + +截图: + +![操作日志](screenshots-queried/12-operation-logs.png) + +### 3.13 用户账号审计 + +路由:`/user-account-audit` +接口:`GET /admin/audit/user-account-logs` + +查询条件: + +- 用户编号 +- 用户名 +- 操作者 +- 操作 +- IP +- 时间范围 + +操作类型包括: + +- 修改昵称、修改头像、修改性别、修改签名、修改生日、修改密码 +- 主动注销 +- 管理员修改用户名、管理员更新状态、管理员重置密码、管理员更新安全权限 +- 管理员强制下线、管理员强制注销、管理员调整分组、管理员批量封禁、管理员按 IP 封禁 + +表格列: + +- 操作时间 +- 目标用户 +- 操作者 +- 操作类型 +- 变更摘要 +- IP / 归属地 +- 设备/客户端 + +按钮功能说明: + +- 查询:按用户编号、用户名、操作者、操作、IP、时间范围筛选用户账号审计日志。 +- 重置:清空全部筛选条件并重新查询。 +- 本页不提供写操作,只用于审计追踪。 + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 操作时间 | `created_at` | 账号变更时间 | 倒序排列 | +| 目标用户 | `target_username`、`target_user_no` | 被操作用户 | 两行展示用户名和编号 | +| 操作者 | `actor_type`、`actor_username` | 管理员或用户本人 | 标签区分管理员/用户本人 | +| 操作类型 | `action` | 账号审计动作 | 字典化为中文 | +| 变更摘要 | `details` / `before_data` / `after_data` | 变更内容 | 长内容 tooltip 展示 | +| IP / 归属地 | `ip`、`ip_location` | 操作来源 | IP 和归属地分行展示 | +| 设备/客户端 | `device_id` / `user_agent` | 客户端信息 | 长文本省略,tooltip 查看 | + +操作类型枚举: + +| 值 | 中文 | +| --- | --- | +| `change_nickname` | 修改昵称 | +| `change_avatar` | 修改头像 | +| `change_gender` | 修改性别 | +| `change_signature` | 修改签名 | +| `change_birthday` | 修改生日 | +| `change_password` | 修改密码 | +| `deactivate_account` | 主动注销 | +| `update_username` | 管理员修改用户名 | +| `update_status` | 管理员更新状态 | +| `reset_password` | 管理员重置密码 | +| `update_security_perm` | 管理员更新安全权限 | +| `kick_user` | 管理员强制下线 | +| `force_deactivate` | 管理员强制注销 | +| `assign_policy_group` | 管理员调整分组 | +| `batch_ban_users` | 管理员批量封禁 | +| `ban_users_by_ip` | 管理员按 IP 封禁 | + +截图: + +![用户账号审计](screenshots-queried/13-user-account-audit.png) + +### 3.14 群事件审计 + +路由:`/group-events` +接口:`GET /admin/groups/events` + +查询条件: + +- 群号 +- 操作人 +- 目标用户 +- 事件类型 +- 开始时间 +- 结束时间 + +表格列: + +- 群名称 +- 事件类型 +- 操作人 +- 目标用户 +- 可见范围 +- 旧值 +- 新值 +- 时间 + +按钮功能说明: + +- 查询:按群号、操作人、目标用户、事件类型、时间范围筛选。 +- 重置:清空筛选项重新查询。 +- 本页不提供写操作,数据由群创建、成员加入、踢出、禁言、解散等业务自动写入。 + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 群名称 | `group_name`、`group_no` | 事件所属群 | 两行展示群名和群号 | +| 事件类型 | `event_type` | 群事件 | 成员加入、群创建等 | +| 操作人 | `operator_username`、`operator_nickname` | 发起事件用户 | 系统事件显示系统 | +| 目标用户 | `target_username`、`target_nickname` | 被操作用户 | 无目标显示 `--` | +| 可见范围 | `visibility` | 事件对谁可见 | 全员可见、管理员可见、仅自己 | +| 旧值 | `old_value` | 变更前值 | 无则 `--` | +| 新值 | `new_value` | 变更后值 | 无则 `--` | +| 时间 | `created_at` | 事件时间 | `YYYY-MM-DD HH:mm:ss` | + +事件类型枚举建议: + +- `group_created` 群创建。 +- `member_joined` 成员加入。 +- `member_left` 成员退出。 +- `member_kicked` 成员被踢。 +- `member_muted` 成员禁言。 +- `member_unmuted` 解除禁言。 +- `owner_transferred` 群主转让。 +- `admin_added` 设置管理员。 +- `admin_removed` 取消管理员。 +- `group_name_changed` 修改群名。 +- `group_banned` 群封禁。 +- `group_unbanned` 群解封。 +- `group_dissolved` 群解散。 + +截图: + +![群事件审计](screenshots-queried/14-group-event-audit.png) + +### 3.15 管理员登录历史 + +路由:`/admin-login-history` +接口:`GET /admin/admin-login-history` + +查询条件: + +- 开始时间 +- 结束时间 + +表格列: + +- 用户名 +- 登录时间 +- User-Agent +- IP 地址 + +按钮功能说明: + +- 查询:按开始时间、结束时间筛选管理员登录历史。 +- 分页:默认 `20 条/页`。 +- 本页不提供写操作。 + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 用户名 | `username` | 管理员账号 | 样例:heiyue | +| 登录时间 | `login_at` | 登录成功时间 | 倒序排列 | +| User-Agent | `user_agent` | 浏览器 UA | 长文本横向滚动或 tooltip | +| IP 地址 | `ip` | 登录 IP | IPv4/IPv6 | + +截图: + +![管理员登录](screenshots-queried/15-admin-login.png) + +### 3.16 用户登录历史 + +路由:`/user-login-history` +接口:`GET /admin/user-login-history` + +查询条件: + +- 用户编号 +- 用户名 +- 开始时间 +- 结束时间 +- IP + +表格列: + +- 用户编号 +- 用户名 +- 当前状态 +- 登录时间 +- 设备类型 +- 设备型号 +- 系统版本 +- App 版本 +- IP 地址 +- 归属地 +- 操作 + +行操作: + +- 快速封禁 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查询 | 按用户编号、用户名、时间、IP 筛选 | `GET /admin/user-login-history` | 查询后页码回到第 1 页 | +| 重 置 | 清空筛选条件 | `GET /admin/user-login-history` | 回到全部登录历史 | +| 快速封禁 | 从登录记录封禁用户 | `PATCH /admin/users/{id}/status` | 需二次确认;封禁后撤销在线会话 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 用户编号 | `user_no` | 用户对外编号 | 支持筛选 | +| 用户名 | `username` | 用户名 | 支持筛选 | +| 当前状态 | `status` | 用户当前状态 | 正常/已封禁/已注销 | +| 登录时间 | `login_at` | 本次登录时间 | 倒序排列 | +| 设备类型 | `device_type` | 登录终端 | web/android/ios | +| 设备型号 | `device_model` | 设备名称 | 样例:OPPO PCHM10 | +| 系统版本 | `os_version` | 操作系统版本 | 样例:Android 11 | +| App 版本 | `app_version` | 客户端版本 | web 可显示 `-` | +| IP 地址 | `ip` | 登录 IP | 支持筛选 | +| 归属地 | `ip_location` | IP 地理位置 | 无法解析显示未知 | + +枚举说明: + +- 设备类型:`web` Web 端、`android` Android APP、`ios` iOS APP、`unknown` 未知设备。 +- 用户状态同用户管理。 + +截图: + +![用户登录](screenshots-queried/16-user-login.png) + +### 3.17 IP 账号统计 + +路由:`/ip-user-stats` +核心接口: + +- `GET /admin/audit/ip-user-stats` +- `GET /admin/audit/ip-user-stats/users` +- `POST /admin/users/ban-by-ip` + +查询条件: + +- IP,支持 IPv4 或 IPv6 + +表格列: + +- IP 地址 +- 归属地 +- 关联用户 +- 注册用户 +- 登录用户 +- 正常 +- 已封禁 +- 最近活动 +- 操作 + +行操作: + +- 用户列表 +- 封禁 IP,平台级账号可见 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查询 | 按 IP 筛选统计 | `GET /admin/audit/ip-user-stats` | 支持 IPv4/IPv6 | +| 重 置 | 清空 IP | `GET /admin/audit/ip-user-stats` | 回到全部统计 | +| 用户列表 | 查看该 IP 关联用户 | `GET /admin/audit/ip-user-stats/users` | 弹窗展示注册/登录命中的用户 | +| 封禁 IP | 封禁该 IP 关联用户 | `POST /admin/users/ban-by-ip` | 平台账号可见;返回命中数、成功数、失败数 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| IP 地址 | `ip` | 统计 IP | IPv4/IPv6 | +| 归属地 | `ip_location` | IP 地理位置 | 样例:浙江 绍兴 | +| 关联用户 | `user_count` | 注册或登录命中过该 IP 的用户数 | 大于 1 显示“多账号”标签 | +| 注册用户 | `register_user_count` | 使用该 IP 注册的用户数 | 数字 | +| 登录用户 | `login_user_count` | 使用该 IP 登录的用户数 | 数字 | +| 正常 | `active_user_count` | 关联用户中正常数量 | 数字 | +| 已封禁 | `disabled_user_count` | 关联用户中封禁数量 | 数字 | +| 最近活动 | `last_seen_at` | 最近注册或登录时间 | `YYYY-MM-DD HH:mm:ss` | + +关联用户弹窗字段: + +- 用户 ID,平台账号可见。 +- 用户编号、用户名、昵称。 +- 来源:注册、登录,可同时命中。 +- 状态:正常、已封禁。 +- 最近活动。 + +截图: + +![IP 账号统计](screenshots-queried/17-ip-account-stats.png) + +### 3.18 登录失败日志 + +路由:`/login-failure-logs` +核心接口: + +- `GET /admin/login-failure-logs` +- `POST /admin/security/unlock` + +查询条件: + +- 类型 +- 登录账号 +- IP +- 开始时间 +- 结束时间 + +表格列: + +- 类型 +- 登录账号 +- 失败原因 +- IP 地址 +- User-Agent +- 时间 +- 操作 + +行操作: + +- 解锁 + +按钮功能说明: + +| 按钮 | 对应功能 | 接口 | 详细说明 | +| --- | --- | --- | --- | +| 查询 | 按类型、账号、IP、时间筛选 | `GET /admin/login-failure-logs` | 查询后页码回到第 1 页 | +| 重 置 | 清空筛选条件 | `GET /admin/login-failure-logs` | 回到全部失败记录 | +| 解锁 | 解除账号或 IP 登录锁定 | `POST /admin/security/unlock` | 需二次确认 | + +表格字段说明: + +| 表格字段 | 接口字段建议 | 含义 | 展示规则 | +| --- | --- | --- | --- | +| 类型 | `type` | 登录失败账号类型 | 用户/管理员 | +| 登录账号 | `account` | 输入的账号 | 手机号、用户名或管理员账号 | +| 失败原因 | `reason` | 失败说明 | 样例:密码错误 | +| IP 地址 | `ip` | 失败来源 IP | 支持筛选 | +| User-Agent | `user_agent` | 客户端 UA | 长文本省略 | +| 时间 | `created_at` | 失败时间 | 倒序排列 | + +枚举说明: + +- 类型:`user` 用户、`admin` 管理员。 +- 失败原因:`password_error` 密码错误、`account_not_found` 账号不存在、`account_disabled` 账号被封禁、`captcha_error` 验证码错误、`ip_blocked` IP 被拦截、`too_many_attempts` 连续失败次数过多。 + +截图: + +![登录失败日志](screenshots-queried/18-login-failures.png) + +### 3.19 私域设置 + +路由:`/tenant-settings` +核心接口: + +- `GET /admin/tenant-settings` +- `PUT /admin/tenant-settings` + +配置项: + +- 消息字符上限:范围 1 到 5000,仅允许调低 +- 图片大小上限:范围 1 到 1000 MB +- 文件大小上限:范围 1 到 1000 MB,默认 50 MB +- 最大撤回消息时间:范围 1 到 1440 分钟;群主/管理员可撤回自己或他人消息,普通用户撤回自己的消息固定为 2 分钟 +- 是否开启手机验证码:关闭后,注册仅支持邀请码,短信登录与忘记密码不可用 + +操作: + +- 保存设置 + +按钮与字段说明: + +| 字段/按钮 | 接口字段建议 | 范围/枚举 | 业务影响 | +| --- | --- | --- | --- | +| 消息字符上限 | `message_char_limit` | 1 到 5000,仅允许调低 | 用户发送文本消息时校验长度 | +| 图片大小上限(MB) | `image_size_limit_mb` | 1 到 1000 | 图片上传前后端双校验 | +| 文件大小上限(MB) | `file_size_limit_mb` | 1 到 1000,默认 50 | 文件上传前后端双校验 | +| 最大撤回消息时间(分钟) | `max_recall_minutes` | 1 到 1440 | 群主/管理员撤回自己或他人消息的最长时限 | +| 是否开启手机验证码 | `sms_code_enabled` | 开启/关闭 | 关闭后注册仅支持邀请码,短信登录与忘记密码不可用 | +| 保存设置 | - | - | 提交当前租户配置,后端校验后清理租户配置缓存 | + +枚举说明: + +- `sms_code_enabled=true`:开启手机验证码,支持短信登录、忘记密码、手机号验证码注册。 +- `sms_code_enabled=false`:关闭手机验证码,仅支持邀请码注册。 + +截图: + +![私域设置](screenshots-queried/19-private-domain-settings.png) + +### 3.20 安全策略 + +路由:`/security-settings` +核心接口: + +- `GET /admin/security-settings` +- `PUT /admin/security-settings` +- `POST /admin/security/unlock` + +配置分组与字段: + +- 用户安全 + - 验证码触发次数:连续密码错误该次数后要求验证码,范围 1 到 10 + - 密码最小位数:范围 6 到 32 + - 强制包含字母 +- 注册登录管控 + - 用户注册功能 + - 修改密码功能 + - 用户登录功能 + - Web 端多端登录 +- 聊天消息管控 + - 全局好友功能 + - 全局群消息 + - 全局私聊消息 + - 群聊发言间隔:0 表示不限制;1 到 1000 表示同一群内两次发言的最小间隔 +- 群组功能管控 + - 群号搜索功能 + - 群创建功能 + - 群解散功能 + - 群管理员功能 + - 是否显示群人数 +- 其他功能开关 + - 允许用户注销账号 +- IP 访问控制 + - 注册 IP 黑名单:每行一个 IPv4、IPv6 或 CIDR,命中后无法注册及获取注册短信验证码 + - 登录 IP 黑名单:命中后无法密码登录、短信登录及刷新 Token;黑名单优先级高于用户分组登录白名单 +- 高级功能 + - 消息已读状态 + +操作: + +- 保存设置 + +按钮与字段说明: + +| 分组 | 字段 | 接口字段建议 | 范围/枚举 | 业务影响 | +| --- | --- | --- | --- | --- | +| 用户安全 | 验证码触发次数 | `captcha_trigger_count` | 1 到 10 | 连续密码错误达到次数后要求验证码 | +| 用户安全 | 密码最小位数 | `password_min_length` | 6 到 32 | 注册、修改密码、后台重置密码均生效 | +| 用户安全 | 强制包含字母 | `password_require_letter` | 开启/关闭 | 开启后密码必须包含英文字母 | +| 注册登录管控 | 用户注册功能 | `user_register_enabled` | 开启/关闭 | 关闭后用户端隐藏注册入口 | +| 注册登录管控 | 修改密码功能 | `password_change_enabled` | 开启/关闭 | 关闭后用户无法自行修改密码 | +| 注册登录管控 | 用户登录功能 | `user_login_enabled` | 开启/关闭 | 关闭后用户无法登录,不影响已登录用户 | +| 注册登录管控 | Web 端多端登录 | `web_multi_login_enabled` | 开启/关闭 | 开启后同账号可多浏览器同时登录 | +| 聊天消息管控 | 全局好友功能 | `global_friend_enabled` | 开启/关闭 | 关闭后无法搜索和添加好友 | +| 聊天消息管控 | 全局群消息 | `global_group_message_enabled` | 开启/关闭 | 关闭后所有群无法发送消息 | +| 聊天消息管控 | 全局私聊消息 | `global_private_message_enabled` | 开启/关闭 | 关闭后所有私聊无法发送消息 | +| 聊天消息管控 | 群聊发言间隔(秒) | `group_message_interval_seconds` | 0 到 1000 | 0 不限制,其他值限制同群发言间隔 | +| 群组功能管控 | 群号搜索功能 | `group_search_enabled` | 开启/关闭 | 关闭后隐藏群号和群搜索入口 | +| 群组功能管控 | 群创建功能 | `group_create_enabled` | 开启/关闭 | 关闭后所有人无法新建群聊 | +| 群组功能管控 | 群解散功能 | `group_dissolve_enabled` | 开启/关闭 | 关闭后用户端无法解散群,不影响后台 | +| 群组功能管控 | 群管理员功能 | `group_admin_enabled` | 开启/关闭 | 关闭后无法设置群管理员 | +| 群组功能管控 | 是否显示群人数 | `show_group_member_count` | 开启/关闭 | 关闭后用户端群资料不显示总人数 | +| 其他功能开关 | 允许用户注销账号 | `account_deactivate_enabled` | 开启/关闭 | 关闭后隐藏注销账号按钮 | +| IP 访问控制 | 注册 IP 黑名单 | `register_ip_blacklist` | 多行 IP/CIDR | 命中后无法注册和获取注册短信验证码 | +| IP 访问控制 | 登录 IP 黑名单 | `login_ip_blacklist` | 多行 IP/CIDR | 命中后无法密码登录、短信登录和刷新 Token | +| 高级功能 | 消息已读状态 | `message_read_status_enabled` | 开启/关闭 | 开启后显示消息已读/未读标记 | +| 保存设置 | - | - | 保存安全配置,写操作日志,刷新配置缓存 | + +枚举说明: + +- 所有开关均使用布尔值:`true` 开启,`false` 关闭。 +- IP 黑名单每行一个 IPv4、IPv6 或 CIDR,保存时去空行、去重、校验格式。 +- 登录 IP 黑名单优先于用户分组白名单。 + +截图: + +![安全策略](screenshots-queried/20-security-policy.png) + +## 4. 接口清单 + +从前端静态资源反查到的接口如下,建议后端按 REST 风格补齐: + +| 模块 | 接口 | +| --- | --- | +| 认证 | `/admin/auth/login`, `/admin/auth/profile`, `/admin/auth/password`, `/admin/auth/totp/status`, `/admin/auth/totp/setup`, `/admin/auth/totp/bind`, `/admin/auth/totp/unbind` | +| 统计 | `/admin/stats` | +| 用户 | `/admin/users`, `/admin/users/{id}`, `/admin/users/{id}/status`, `/admin/users/{id}/username`, `/admin/users/{id}/reset_password`, `/admin/users/{id}/ip-whitelist`, `/admin/users/{id}/friend-privilege`, `/admin/users/{id}/security-perm`, `/admin/users/{id}/kick`, `/admin/users/{id}/deactivate`, `/admin/users/batch`, `/admin/users/batch-ban`, `/admin/users/ban-by-ip`, `/admin/users/import-xlsx` | +| 用户分组 | `/admin/user-policy-groups`, `/admin/user-policy-groups/{id}`, `/admin/user-policy-groups/{id}/users`, `/admin/user-policy-groups/ip-whitelist` | +| 群组 | `/admin/groups`, `/admin/groups/{id}`, `/admin/groups/{id}/ban`, `/admin/groups/{id}/unban`, `/admin/groups/{id}/members`, `/admin/groups/{id}/members/kick`, `/admin/groups/{id}/members/mute`, `/admin/groups/{id}/members/unmute`, `/admin/groups/{id}/files`, `/admin/groups/{id}/files/{fileId}`, `/admin/groups/events`, `/admin/groups/quick-create` | +| 消息与文件 | `/admin/messages/search`, `/admin/messages/{id}` | +| 邀请码 | `/admin/invite-codes`, `/admin/invite-codes/{id}`, `/admin/invite-codes/{id}/usages` | +| 敏感词 | `/admin/sensitive-words`, `/admin/sensitive-words/{id}`, `/admin/sensitive-words/import`, `/admin/sensitive-words/export` | +| 反馈 | `/admin/feedbacks`, `/admin/feedbacks/{id}`, `/admin/feedbacks/{id}/priority`, `/admin/feedbacks/batch-handle`, `/admin/feedbacks/export` | +| 审计 | `/admin/audit/logs`, `/admin/audit/user-account-logs`, `/admin/audit/ip-user-stats`, `/admin/audit/ip-user-stats/users`, `/admin/control/audit-logs` | +| 登录日志 | `/admin/admin-login-history`, `/admin/user-login-history`, `/admin/login-failure-logs` | +| 设置 | `/admin/tenant-settings`, `/admin/security-settings`, `/admin/security/unlock` | +| 当前菜单未展示但 bundle 存在 | `/admin/tenants`, `/admin/admins`, `/admin/tenant-admins`, `/admin/roles`, `/admin/nodes`, `/admin/system/nodes-status`, `/admin/avatar-pool`, `/admin/avatar-pool/backfill`, `/admin/system-conversations`, `/admin/system-conversations/send`, `/admin/conversation-notices`, `/admin/reports`, `/admin/login-streak/rank`, `/admin/private-msg/rank`, `/admin/user-password`, `/admin/keyword-alerts`, `/admin/alert-keywords`, `/admin/alert-bot-config`, `/admin/domain/encrypt`, `/admin/domain/decrypt`, `/admin/domain/obfuscate`, `/admin/domain/config`, `/admin/domain/push-update`, `/admin/domain/push-bucket-update` | + +通用响应结构建议: + +```json +{ + "code": 0, + "message": "ok", + "data": { + "items": [], + "total": 0, + "page": 1, + "size": 20 + } +} +``` + +列表接口统一分页参数: + +- `page` +- `page_size` +- 各页面查询条件 + +## 5. 核心数据模型建议 + +建议至少设计以下数据表或领域模型: + +- 管理员账号:账号、密码、TOTP、角色、权限、登录历史 +- 用户:用户编号、用户名、昵称、手机号、头像、状态、注册方式、用户分组、最近登录、创建时间 +- 用户分组:权限开关、好友上限、登录白名单、排序权重、默认分组标记 +- 群组:群号、名称、群主、成员数、状态、创建时间 +- 群成员:用户、群、角色、群昵称、禁言状态、加入时间 +- 消息:会话类型、发送人、接收人/群、消息类型、内容、文件信息、状态、发送时间 +- 文件记录:发送人、接收方、文件类型、文件名、大小、URL、消息关联、状态 +- 邀请码:邀请码、指定用户、自动加好友、使用人数、创建人、状态、有效期 +- 敏感词:词条、等级、替换词、状态、创建时间 +- 用户反馈:用户、联系方式、内容、优先级、状态、处理人、处理备注 +- 操作日志:管理员、动作、目标类型、目标、查询条件、IP、时间 +- 用户账号审计:目标用户、操作者、操作类型、变更前后、IP、归属地、设备 +- 群事件审计:群、事件类型、操作人、目标用户、可见范围、旧值、新值、时间 +- 登录历史:账号类型、账号、登录时间、设备信息、IP、归属地 +- 登录失败日志:类型、账号、失败原因、IP、User-Agent、锁定/解锁状态 +- 租户设置:消息、文件、验证码、撤回时间等私域配置 +- 安全策略:密码、注册登录、聊天、群组、注销、IP 黑名单、已读状态配置 + +## 6. 权限建议 + +前端 bundle 中能看到的权限点包括: + +- `tenant_manage` +- `user_manage` +- `group_manage` +- `view_private_chat` +- `view_group_chat` +- `view_audit_log` + +建议在 HotGo 中拆成更细的菜单/按钮权限: + +- 用户管理:查看、创建、批量创建、导入、详情、重置密码、调整分组、封禁、强制下线、注销、IP 白名单 +- 群组管理:查看、详情、群文件、封禁、解散、成员踢出、禁言/解除禁言 +- 内容审核:消息查看、文件预览下载删除、敏感词增删改导入导出、反馈处理导出 +- 日志审计:查看、导出、解锁、IP 关联用户查看、按 IP 封禁 +- 系统设置:私域设置保存、安全策略保存 + +## 7. 实现优先级 + +第一阶段建议先完成可见菜单: + +1. 后台登录、权限、菜单、布局。 +2. 数据概览统计。 +3. 用户管理、用户分组、群组管理、群成员管理、邀请码管理。 +4. 单聊/群聊消息、文件管理、敏感词库、用户反馈。 +5. 操作日志、用户账号审计、群事件审计、登录历史、IP 统计、失败日志。 +6. 私域设置、安全策略。 + +第二阶段再补 bundle 中存在但当前菜单未展示的能力: + +- 租户、管理员、角色、节点、头像池、系统会话、系统通知、报表、排行榜、关键词告警、域名加密等。 + +## 8. 采集产物 + +本次调研文件保存在: + +- 截图目录:`docs/admin-adfahi-research/screenshots-queried/` +- 每页结构化采集:`docs/admin-adfahi-research/*.json` +- 前端 bundle:`docs/admin-adfahi-research/index-RosMaKu2.js` +- 接口尝试结果:`docs/admin-adfahi-research/api-samples.json` diff --git a/server/api/admin/imdashboard/im_dashboard.go b/server/api/admin/imdashboard/im_dashboard.go new file mode 100644 index 0000000..81bbc59 --- /dev/null +++ b/server/api/admin/imdashboard/im_dashboard.go @@ -0,0 +1,25 @@ +package imdashboard + +import ( + "hotgo/internal/model/input/sysin" + + "github.com/gogf/gf/v2/frame/g" +) + +type OverviewReq struct { + g.Meta `path:"/imDashboard/overview" method:"get" tags:"IM数据概览" summary:"获取IM数据概览"` + sysin.ImDashboardOverviewInp +} + +type OverviewRes struct { + *sysin.ImDashboardOverviewModel +} + +type TrendsReq struct { + g.Meta `path:"/imDashboard/trends" method:"get" tags:"IM数据概览" summary:"获取IM增长趋势"` + sysin.ImDashboardTrendsInp +} + +type TrendsRes struct { + List []*sysin.ImDashboardTrendModel `json:"list" dc:"趋势数据"` +} diff --git a/server/api/admin/imgroupmessage/im_group_message.go b/server/api/admin/imgroupmessage/im_group_message.go new file mode 100644 index 0000000..bda8530 --- /dev/null +++ b/server/api/admin/imgroupmessage/im_group_message.go @@ -0,0 +1,37 @@ +package imgroupmessage + +import ( + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + + "github.com/gogf/gf/v2/frame/g" +) + +type ListReq struct { + g.Meta `path:"/imGroupMessage/list" method:"get" tags:"IM群聊消息" summary:"获取群聊消息列表"` + sysin.ImGroupMessageListInp +} +type ListRes struct { + form.PageRes + List []*sysin.ImMessageListModel `json:"list" dc:"数据列表"` +} +type ViewReq struct { + g.Meta `path:"/imGroupMessage/view" method:"get" tags:"IM群聊消息" summary:"获取群聊消息详情"` + sysin.ImMessageViewInp +} +type ViewRes struct{ *sysin.ImMessageViewModel } +type HideReq struct { + g.Meta `path:"/imGroupMessage/hide" method:"post" tags:"IM群聊消息" summary:"隐藏群聊消息"` + sysin.ImMessageActionInp +} +type HideRes struct{ *sysin.ImMessageCommandModel } +type DeleteReq struct { + g.Meta `path:"/imGroupMessage/delete" method:"post" tags:"IM群聊消息" summary:"删除群聊消息"` + sysin.ImMessageActionInp +} +type DeleteRes struct{ *sysin.ImMessageCommandModel } +type ExportReq struct { + g.Meta `path:"/imGroupMessage/export" method:"get" tags:"IM群聊消息" summary:"导出群聊消息"` + sysin.ImGroupMessageListInp +} +type ExportRes struct{} diff --git a/server/api/admin/imloginfailurelog/im_login_failure_log.go b/server/api/admin/imloginfailurelog/im_login_failure_log.go new file mode 100644 index 0000000..ce95a03 --- /dev/null +++ b/server/api/admin/imloginfailurelog/im_login_failure_log.go @@ -0,0 +1,37 @@ +package imloginfailurelog + +import ( + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + + "github.com/gogf/gf/v2/frame/g" +) + +type ListReq struct { + g.Meta `path:"/imLoginFailureLog/list" method:"get" tags:"IM登录失败日志" summary:"获取登录失败日志"` + sysin.ImLoginFailureLogListInp +} +type ListRes struct { + form.PageRes + List []*sysin.ImLoginFailureLogModel `json:"list" dc:"数据列表"` +} +type ViewReq struct { + g.Meta `path:"/imLoginFailureLog/view" method:"get" tags:"IM登录失败日志" summary:"获取登录失败详情"` + sysin.ImLoginFailureViewInp +} +type ViewRes struct{ *sysin.ImLoginFailureLogModel } +type ExportReq struct { + g.Meta `path:"/imLoginFailureLog/export" method:"get" tags:"IM登录失败日志" summary:"导出登录失败日志"` + sysin.ImLoginFailureLogListInp +} +type ExportRes struct{} +type AddBlacklistReq struct { + g.Meta `path:"/imLoginFailureLog/addBlacklist" method:"post" tags:"IM登录失败日志" summary:"将IP加入黑名单"` + sysin.ImLoginFailureAddBlacklistInp +} +type AddBlacklistRes struct{} +type BanUserReq struct { + g.Meta `path:"/imLoginFailureLog/banUser" method:"post" tags:"IM登录失败日志" summary:"封禁关联用户"` + sysin.ImLoginFailureBanUserInp +} +type BanUserRes struct{ *sysin.ImUserCommandModel } diff --git a/server/api/admin/imprivatemessage/im_private_message.go b/server/api/admin/imprivatemessage/im_private_message.go new file mode 100644 index 0000000..f3acd48 --- /dev/null +++ b/server/api/admin/imprivatemessage/im_private_message.go @@ -0,0 +1,37 @@ +package imprivatemessage + +import ( + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + + "github.com/gogf/gf/v2/frame/g" +) + +type ListReq struct { + g.Meta `path:"/imPrivateMessage/list" method:"get" tags:"IM单聊消息" summary:"获取单聊消息列表"` + sysin.ImPrivateMessageListInp +} +type ListRes struct { + form.PageRes + List []*sysin.ImMessageListModel `json:"list" dc:"数据列表"` +} +type ViewReq struct { + g.Meta `path:"/imPrivateMessage/view" method:"get" tags:"IM单聊消息" summary:"获取单聊消息详情"` + sysin.ImMessageViewInp +} +type ViewRes struct{ *sysin.ImMessageViewModel } +type HideReq struct { + g.Meta `path:"/imPrivateMessage/hide" method:"post" tags:"IM单聊消息" summary:"隐藏单聊消息"` + sysin.ImMessageActionInp +} +type HideRes struct{ *sysin.ImMessageCommandModel } +type DeleteReq struct { + g.Meta `path:"/imPrivateMessage/delete" method:"post" tags:"IM单聊消息" summary:"删除单聊消息"` + sysin.ImMessageActionInp +} +type DeleteRes struct{ *sysin.ImMessageCommandModel } +type ExportReq struct { + g.Meta `path:"/imPrivateMessage/export" method:"get" tags:"IM单聊消息" summary:"导出单聊消息"` + sysin.ImPrivateMessageListInp +} +type ExportRes struct{} diff --git a/server/api/admin/imsecuritypolicy/im_security_policy.go b/server/api/admin/imsecuritypolicy/im_security_policy.go new file mode 100644 index 0000000..5042a88 --- /dev/null +++ b/server/api/admin/imsecuritypolicy/im_security_policy.go @@ -0,0 +1,59 @@ +package imsecuritypolicy + +import ( + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + + "github.com/gogf/gf/v2/frame/g" +) + +type ListReq struct { + g.Meta `path:"/imSecurityPolicy/list" method:"get" tags:"IM安全策略" summary:"获取安全策略历史"` + sysin.ImSecurityPolicyListInp +} +type ListRes struct { + form.PageRes + List []*sysin.ImSecurityPolicyModel `json:"list"` +} +type ViewReq struct { + g.Meta `path:"/imSecurityPolicy/view" method:"get" tags:"IM安全策略" summary:"获取安全策略详情"` + sysin.ImSecurityPolicyViewInp +} +type ViewRes struct{ *sysin.ImSecurityPolicyModel } +type SaveReq struct { + g.Meta `path:"/imSecurityPolicy/save" method:"post" tags:"IM安全策略" summary:"保存安全策略草稿"` + sysin.ImSecurityPolicySaveInp +} +type SaveRes struct { + Id int64 `json:"id"` +} +type PublishReq struct { + g.Meta `path:"/imSecurityPolicy/publish" method:"post" tags:"IM安全策略" summary:"发布安全策略"` + sysin.ImSecurityPolicyPublishInp +} +type PublishRes struct{} +type RestoreDefaultReq struct { + g.Meta `path:"/imSecurityPolicy/restoreDefault" method:"post" tags:"IM安全策略" summary:"恢复默认安全策略"` + sysin.ImSecurityPolicyRestoreInp +} +type RestoreDefaultRes struct { + Id int64 `json:"id"` +} +type IPRuleListReq struct { + g.Meta `path:"/imSecurityPolicy/ipRuleList" method:"get" tags:"IM安全策略" summary:"获取IP黑白名单"` + sysin.ImSecurityIPRuleListInp +} +type IPRuleListRes struct { + form.PageRes + List []*sysin.ImSecurityIPRuleModel `json:"list"` +} +type IPRuleEditReq struct { + g.Meta `path:"/imSecurityPolicy/ipRuleEdit" method:"post" tags:"IM安全策略" summary:"新增或编辑IP规则"` + sysin.ImSecurityIPRuleEditInp +} +type IPRuleEditRes struct{} +type IPRuleDeleteReq struct { + g.Meta `path:"/imSecurityPolicy/ipRuleDelete" method:"post" tags:"IM安全策略" summary:"删除IP规则"` + sysin.ImSecurityIPRuleDeleteInp +} +type IPRuleDeleteRes struct{} diff --git a/server/api/admin/imsensitiveword/im_sensitive_word.go b/server/api/admin/imsensitiveword/im_sensitive_word.go new file mode 100644 index 0000000..2b993cb --- /dev/null +++ b/server/api/admin/imsensitiveword/im_sensitive_word.go @@ -0,0 +1,51 @@ +package imsensitiveword + +import ( + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + + "github.com/gogf/gf/v2/frame/g" +) + +type ListReq struct { + g.Meta `path:"/imSensitiveWord/list" method:"get" tags:"IM敏感词" summary:"获取敏感词列表"` + sysin.ImSensitiveWordListInp +} +type ListRes struct { + form.PageRes + List []*sysin.ImSensitiveWordListModel `json:"list"` +} +type EditReq struct { + g.Meta `path:"/imSensitiveWord/edit" method:"post" tags:"IM敏感词" summary:"新增或编辑敏感词"` + sysin.ImSensitiveWordEditInp +} +type EditRes struct{} +type DeleteReq struct { + g.Meta `path:"/imSensitiveWord/delete" method:"post" tags:"IM敏感词" summary:"删除敏感词"` + sysin.ImSensitiveWordDeleteInp +} +type DeleteRes struct{} +type StatusReq struct { + g.Meta `path:"/imSensitiveWord/status" method:"post" tags:"IM敏感词" summary:"更新敏感词状态"` + sysin.ImSensitiveWordStatusInp +} +type StatusRes struct{} +type BatchImportReq struct { + g.Meta `path:"/imSensitiveWord/batchImport" method:"post" tags:"IM敏感词" summary:"批量导入敏感词"` + sysin.ImSensitiveWordBatchImportInp +} +type BatchImportRes struct { + *sysin.ImSensitiveWordBatchImportModel +} +type GroupListReq struct { + g.Meta `path:"/imSensitiveWord/groupList" method:"get" tags:"IM敏感词" summary:"获取敏感词分组"` + sysin.ImSensitiveWordGroupListInp +} +type GroupListRes struct { + List []*sysin.ImSensitiveWordGroupModel `json:"list"` +} +type GroupEditReq struct { + g.Meta `path:"/imSensitiveWord/groupEdit" method:"post" tags:"IM敏感词" summary:"新增或编辑敏感词分组"` + sysin.ImSensitiveWordGroupEditInp +} +type GroupEditRes struct{} diff --git a/server/api/admin/imuserloginhistory/im_user_login_history.go b/server/api/admin/imuserloginhistory/im_user_login_history.go new file mode 100644 index 0000000..3665840 --- /dev/null +++ b/server/api/admin/imuserloginhistory/im_user_login_history.go @@ -0,0 +1,22 @@ +package imuserloginhistory + +import ( + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + + "github.com/gogf/gf/v2/frame/g" +) + +type ListReq struct { + g.Meta `path:"/imUserLoginHistory/list" method:"get" tags:"IM用户登录历史" summary:"获取用户登录历史"` + sysin.ImUserLoginHistoryListInp +} +type ListRes struct { + form.PageRes + List []*sysin.ImUserLoginHistoryModel `json:"list" dc:"数据列表"` +} +type ExportReq struct { + g.Meta `path:"/imUserLoginHistory/export" method:"get" tags:"IM用户登录历史" summary:"导出用户登录历史"` + sysin.ImUserLoginHistoryListInp +} +type ExportRes struct{} diff --git a/server/api/admin/imuserpolicygroup/im_user_policy_group.go b/server/api/admin/imuserpolicygroup/im_user_policy_group.go new file mode 100644 index 0000000..fc6b0ac --- /dev/null +++ b/server/api/admin/imuserpolicygroup/im_user_policy_group.go @@ -0,0 +1,57 @@ +package imuserpolicygroup + +import ( + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + + "github.com/gogf/gf/v2/frame/g" +) + +type ListReq struct { + g.Meta `path:"/imUserPolicyGroup/list" method:"get" tags:"IM用户策略分组" summary:"获取用户策略分组列表"` + sysin.ImUserPolicyGroupListInp +} +type ListRes struct { + form.PageRes + List []*sysin.ImUserPolicyGroupListModel `json:"list"` +} +type ViewReq struct { + g.Meta `path:"/imUserPolicyGroup/view" method:"get" tags:"IM用户策略分组" summary:"获取用户策略分组详情"` + sysin.ImUserPolicyGroupViewInp +} +type ViewRes struct { + *sysin.ImUserPolicyGroupViewModel +} +type EditReq struct { + g.Meta `path:"/imUserPolicyGroup/edit" method:"post" tags:"IM用户策略分组" summary:"新增或编辑用户策略分组"` + sysin.ImUserPolicyGroupEditInp +} +type EditRes struct{} +type DeleteReq struct { + g.Meta `path:"/imUserPolicyGroup/delete" method:"post" tags:"IM用户策略分组" summary:"删除用户策略分组"` + sysin.ImUserPolicyGroupDeleteInp +} +type DeleteRes struct{} +type StatusReq struct { + g.Meta `path:"/imUserPolicyGroup/status" method:"post" tags:"IM用户策略分组" summary:"更新用户策略分组状态"` + sysin.ImUserPolicyGroupStatusInp +} +type StatusRes struct{} +type MemberListReq struct { + g.Meta `path:"/imUserPolicyGroup/memberList" method:"get" tags:"IM用户策略分组" summary:"获取策略分组成员"` + sysin.ImUserPolicyGroupMemberListInp +} +type MemberListRes struct { + form.PageRes + List []*sysin.ImUserPolicyGroupMemberModel `json:"list"` +} +type MemberAddReq struct { + g.Meta `path:"/imUserPolicyGroup/memberAdd" method:"post" tags:"IM用户策略分组" summary:"添加策略分组成员"` + sysin.ImUserPolicyGroupMemberAddInp +} +type MemberAddRes struct{} +type MemberRemoveReq struct { + g.Meta `path:"/imUserPolicyGroup/memberRemove" method:"post" tags:"IM用户策略分组" summary:"移除策略分组成员"` + sysin.ImUserPolicyGroupMemberRemoveInp +} +type MemberRemoveRes struct{} diff --git a/server/internal/consts/im_content_audit.go b/server/internal/consts/im_content_audit.go new file mode 100644 index 0000000..7ad3e2d --- /dev/null +++ b/server/internal/consts/im_content_audit.go @@ -0,0 +1,84 @@ +package consts + +import ( + "hotgo/internal/library/dict" + "hotgo/internal/model" +) + +const ( + ImMessageContentText = "text" + ImMessageContentImage = "image" + ImMessageContentVideo = "video" + ImMessageContentAudio = "audio" + ImMessageContentVoice = "voice" + ImMessageContentFile = "file" + ImMessageContentCard = "card" + ImMessageContentSystem = "system" + + ImMessageStatusNormal = "normal" + ImMessageStatusDeleted = "deleted" + ImMessageStatusRecalled = "recalled" + ImMessageStatusBlocked = "blocked" + ImMessageStatusHidden = "hidden" +) + +var ImMessageContentTypeOptions = []*model.Option{ + dict.GenInfoOption(ImMessageContentText, "文本"), + dict.GenPrimaryOption(ImMessageContentImage, "图片"), + dict.GenPrimaryOption(ImMessageContentVideo, "视频"), + dict.GenPrimaryOption(ImMessageContentAudio, "语音"), + dict.GenPrimaryOption(ImMessageContentVoice, "语音"), + dict.GenDefaultOption(ImMessageContentFile, "文件"), + dict.GenDefaultOption(ImMessageContentCard, "名片"), + dict.GenWarningOption(ImMessageContentSystem, "系统"), +} + +var ImMessageStatusOptions = []*model.Option{ + dict.GenSuccessOption(ImMessageStatusNormal, "正常"), + dict.GenErrorOption(ImMessageStatusDeleted, "后台删除"), + dict.GenWarningOption(ImMessageStatusRecalled, "用户撤回"), + dict.GenErrorOption(ImMessageStatusBlocked, "风控拦截"), + dict.GenWarningOption(ImMessageStatusHidden, "已隐藏"), +} + +var ImLoginTypeOptions = []*model.Option{ + dict.GenPrimaryOption("password", "密码"), + dict.GenPrimaryOption("sms_code", "短信验证码"), + dict.GenInfoOption("sso", "单点登录"), + dict.GenInfoOption("qr_code", "二维码"), + dict.GenDefaultOption("token_refresh", "令牌刷新"), +} + +var ImLoginEventTypeOptions = []*model.Option{ + dict.GenSuccessOption("login", "登录"), + dict.GenInfoOption("refresh", "刷新会话"), + dict.GenDefaultOption("logout", "主动退出"), + dict.GenWarningOption("kicked", "被踢下线"), + dict.GenWarningOption("session_expired", "会话过期"), +} + +var ImClientPlatformOptions = []*model.Option{ + dict.GenPrimaryOption("ios", "iOS"), + dict.GenSuccessOption("android", "Android"), + dict.GenInfoOption("web", "Web"), + dict.GenDefaultOption("desktop", "桌面端"), + dict.GenDefaultOption("unknown", "未知"), +} + +var ImLoginFailureTypeOptions = []*model.Option{ + dict.GenErrorOption("password_error", "密码错误"), + dict.GenErrorOption("code_error", "验证码错误"), + dict.GenWarningOption("account_not_found", "账号不存在"), + dict.GenErrorOption("account_disabled", "账号已禁用"), + dict.GenWarningOption("rate_limited", "访问频率受限"), + dict.GenErrorOption("risk_blocked", "风控拦截"), +} + +func init() { + dict.RegisterEnums("ImMessageContentTypeOptions", "IM消息内容类型选项", ImMessageContentTypeOptions) + dict.RegisterEnums("ImMessageStatusOptions", "IM消息状态选项", ImMessageStatusOptions) + dict.RegisterEnums("ImLoginTypeOptions", "IM登录方式选项", ImLoginTypeOptions) + dict.RegisterEnums("ImLoginEventTypeOptions", "IM登录事件选项", ImLoginEventTypeOptions) + dict.RegisterEnums("ImClientPlatformOptions", "IM客户端平台选项", ImClientPlatformOptions) + dict.RegisterEnums("ImLoginFailureTypeOptions", "IM登录失败类型选项", ImLoginFailureTypeOptions) +} diff --git a/server/internal/consts/im_kafka.go b/server/internal/consts/im_kafka.go index 4d26cfa..7622bcf 100644 --- a/server/internal/consts/im_kafka.go +++ b/server/internal/consts/im_kafka.go @@ -47,6 +47,8 @@ const ( ImAdminCommandUserCancel = "user.account.cancel" ImAdminCommandUserDelete = "user.account.delete" ImAdminCommandUserPasswordReset = "user.password.reset" + ImAdminCommandMessageHide = "message.hide" + ImAdminCommandMessageDelete = "message.delete" ImAdminCommandKafkaDeadReplay = "kafka.dead_letter.replay" ImAdminCommandKafkaDeadIgnore = "kafka.dead_letter.ignore" ImAdminCommandKafkaDeadResolve = "kafka.dead_letter.resolve" diff --git a/server/internal/consts/im_policy.go b/server/internal/consts/im_policy.go new file mode 100644 index 0000000..0d2814b --- /dev/null +++ b/server/internal/consts/im_policy.go @@ -0,0 +1,118 @@ +package consts + +import ( + "hotgo/internal/library/dict" + "hotgo/internal/model" +) + +const ( + ImPolicyActionAllow = "allow" + ImPolicyActionDeny = "deny" + ImPolicyActionChallenge = "challenge" + ImPolicyActionAuditOnly = "audit_only" + ImSecurityActionBlock = "block" + + ImSensitiveMatchExact = "exact" + ImSensitiveMatchContains = "contains" + ImSensitiveMatchRegex = "regex" + ImSensitiveMatchPinyin = "pinyin" + + ImSensitiveActionReplace = "replace" + ImSensitiveActionBlock = "block" + ImSensitiveActionAuditOnly = "audit_only" + ImSensitiveActionManualReview = "manual_review" + + ImRiskLevelLow = "low" + ImRiskLevelMedium = "medium" + ImRiskLevelHigh = "high" + + ImSecurityPublishDraft = "draft" + ImSecurityPublishPublished = "published" + ImSecurityPublishArchived = "archived" + ImSecurityPublishFailed = "failed" + + ImCurfewDateDaily = "daily" + ImCurfewDateWeekday = "weekday" + ImCurfewDateWeekend = "weekend" + ImCurfewDateCustom = "custom" + + ImCurfewScopePrivate = "private_message" + ImCurfewScopeGroup = "group_message" +) + +var ( + ImPolicyActionOptions = []*model.Option{ + dict.GenSuccessOption(ImPolicyActionAllow, "放行"), + dict.GenErrorOption(ImPolicyActionDeny, "拦截"), + dict.GenWarningOption(ImPolicyActionChallenge, "二次验证"), + dict.GenInfoOption(ImPolicyActionAuditOnly, "仅审计"), + } + ImSecurityActionOptions = []*model.Option{ + dict.GenSuccessOption(ImPolicyActionAllow, "放行"), + dict.GenWarningOption(ImPolicyActionChallenge, "二次验证"), + dict.GenErrorOption(ImSecurityActionBlock, "阻断"), + dict.GenInfoOption(ImPolicyActionAuditOnly, "仅审计"), + } + ImSensitiveMatchTypeOptions = []*model.Option{ + dict.GenPrimaryOption(ImSensitiveMatchExact, "精确匹配"), + dict.GenDefaultOption(ImSensitiveMatchContains, "包含匹配"), + dict.GenWarningOption(ImSensitiveMatchRegex, "正则匹配"), + dict.GenInfoOption(ImSensitiveMatchPinyin, "拼音匹配"), + } + ImSensitiveActionOptions = []*model.Option{ + dict.GenWarningOption(ImSensitiveActionReplace, "替换"), + dict.GenErrorOption(ImSensitiveActionBlock, "拦截"), + dict.GenInfoOption(ImSensitiveActionAuditOnly, "仅审计"), + dict.GenPrimaryOption(ImSensitiveActionManualReview, "人工审核"), + } + ImRiskLevelOptions = []*model.Option{ + dict.GenSuccessOption(ImRiskLevelLow, "低风险"), + dict.GenWarningOption(ImRiskLevelMedium, "中风险"), + dict.GenErrorOption(ImRiskLevelHigh, "高风险"), + } + ImSecurityPublishStatusOptions = []*model.Option{ + dict.GenWarningOption(ImSecurityPublishDraft, "草稿"), + dict.GenSuccessOption(ImSecurityPublishPublished, "已发布"), + dict.GenDefaultOption(ImSecurityPublishArchived, "已归档"), + dict.GenErrorOption(ImSecurityPublishFailed, "发布失败"), + } + ImCurfewDateTypeOptions = []*model.Option{ + dict.GenDefaultOption(ImCurfewDateDaily, "每天"), + dict.GenPrimaryOption(ImCurfewDateWeekday, "工作日"), + dict.GenInfoOption(ImCurfewDateWeekend, "周末"), + dict.GenWarningOption(ImCurfewDateCustom, "自定义日期"), + } + ImCurfewScopeOptions = []*model.Option{ + dict.GenErrorOption(ImCurfewScopePrivate, "单聊/私聊"), + dict.GenWarningOption(ImCurfewScopeGroup, "群聊"), + } + ImSensitiveSceneOptions = []*model.Option{ + dict.GenPrimaryOption("private_message", "单聊消息"), + dict.GenPrimaryOption("group_message", "群聊消息"), + dict.GenInfoOption("user_profile", "用户资料"), + dict.GenInfoOption("group_profile", "群资料"), + dict.GenWarningOption("feedback", "用户反馈"), + dict.GenWarningOption("report", "举报内容"), + } + ImFriendEntryOptions = []*model.Option{ + dict.GenDefaultOption("search", "用户搜索"), + dict.GenDefaultOption("profile_card", "个人名片"), + dict.GenDefaultOption("group_member", "群成员"), + dict.GenDefaultOption("qrcode", "二维码"), + dict.GenDefaultOption("invite_auto_add", "邀请注册自动添加"), + dict.GenDefaultOption("recommendation", "推荐联系人"), + } +) + +func init() { + dict.RegisterEnums("ImPolicyActionOptions", "IM策略动作", ImPolicyActionOptions) + dict.RegisterEnums("ImSecurityActionOptions", "IM安全策略动作", ImSecurityActionOptions) + dict.RegisterEnums("ImSensitiveMatchTypeOptions", "IM敏感词匹配类型", ImSensitiveMatchTypeOptions) + dict.RegisterEnums("ImSensitiveActionOptions", "IM敏感词动作", ImSensitiveActionOptions) + dict.RegisterEnums("ImRiskLevelOptions", "IM风险等级", ImRiskLevelOptions) + dict.RegisterEnums("ImSecurityPublishStatusOptions", "IM安全策略发布状态", ImSecurityPublishStatusOptions) + dict.RegisterEnums("ImCurfewDateTypeOptions", "IM宵禁日期类型", ImCurfewDateTypeOptions) + dict.RegisterEnums("ImCurfewScopeOptions", "IM宵禁范围", ImCurfewScopeOptions) + dict.RegisterEnums("ImSensitiveSceneOptions", "IM敏感词场景", ImSensitiveSceneOptions) + dict.RegisterEnums("ImFriendEntryOptions", "IM好友入口", ImFriendEntryOptions) +} diff --git a/server/internal/controller/admin/sys/im_dashboard.go b/server/internal/controller/admin/sys/im_dashboard.go new file mode 100644 index 0000000..40bac67 --- /dev/null +++ b/server/internal/controller/admin/sys/im_dashboard.go @@ -0,0 +1,31 @@ +package sys + +import ( + "context" + "hotgo/api/admin/imdashboard" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +var ImDashboard = cImDashboard{} + +type cImDashboard struct{} + +func (c *cImDashboard) Overview(ctx context.Context, req *imdashboard.OverviewReq) (res *imdashboard.OverviewRes, err error) { + data, err := service.SysImDashboard().Overview(ctx, &req.ImDashboardOverviewInp) + if err != nil { + return nil, err + } + return &imdashboard.OverviewRes{ImDashboardOverviewModel: data}, nil +} + +func (c *cImDashboard) Trends(ctx context.Context, req *imdashboard.TrendsReq) (res *imdashboard.TrendsRes, err error) { + list, err := service.SysImDashboard().Trends(ctx, &req.ImDashboardTrendsInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImDashboardTrendModel{} + } + return &imdashboard.TrendsRes{List: list}, nil +} diff --git a/server/internal/controller/admin/sys/im_group_message.go b/server/internal/controller/admin/sys/im_group_message.go new file mode 100644 index 0000000..2e4aa0b --- /dev/null +++ b/server/internal/controller/admin/sys/im_group_message.go @@ -0,0 +1,40 @@ +package sys + +import ( + "context" + "hotgo/api/admin/imgroupmessage" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +var ImGroupMessage = cImGroupMessage{} + +type cImGroupMessage struct{} + +func (c *cImGroupMessage) List(ctx context.Context, req *imgroupmessage.ListReq) (res *imgroupmessage.ListRes, err error) { + list, total, err := service.SysImGroupMessage().List(ctx, &req.ImGroupMessageListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImMessageListModel{} + } + res = &imgroupmessage.ListRes{List: list} + res.PageRes.Pack(req, total) + return +} +func (c *cImGroupMessage) View(ctx context.Context, req *imgroupmessage.ViewReq) (*imgroupmessage.ViewRes, error) { + data, err := service.SysImGroupMessage().View(ctx, &req.ImMessageViewInp) + return &imgroupmessage.ViewRes{ImMessageViewModel: data}, err +} +func (c *cImGroupMessage) Hide(ctx context.Context, req *imgroupmessage.HideReq) (*imgroupmessage.HideRes, error) { + data, err := service.SysImGroupMessage().Hide(ctx, &req.ImMessageActionInp) + return &imgroupmessage.HideRes{ImMessageCommandModel: data}, err +} +func (c *cImGroupMessage) Delete(ctx context.Context, req *imgroupmessage.DeleteReq) (*imgroupmessage.DeleteRes, error) { + data, err := service.SysImGroupMessage().Delete(ctx, &req.ImMessageActionInp) + return &imgroupmessage.DeleteRes{ImMessageCommandModel: data}, err +} +func (c *cImGroupMessage) Export(ctx context.Context, req *imgroupmessage.ExportReq) (*imgroupmessage.ExportRes, error) { + return &imgroupmessage.ExportRes{}, service.SysImGroupMessage().Export(ctx, &req.ImGroupMessageListInp) +} diff --git a/server/internal/controller/admin/sys/im_login_failure_log.go b/server/internal/controller/admin/sys/im_login_failure_log.go new file mode 100644 index 0000000..e6693b1 --- /dev/null +++ b/server/internal/controller/admin/sys/im_login_failure_log.go @@ -0,0 +1,39 @@ +package sys + +import ( + "context" + "hotgo/api/admin/imloginfailurelog" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +var ImLoginFailureLog = cImLoginFailureLog{} + +type cImLoginFailureLog struct{} + +func (c *cImLoginFailureLog) List(ctx context.Context, req *imloginfailurelog.ListReq) (res *imloginfailurelog.ListRes, err error) { + list, total, err := service.SysImLoginFailureLog().List(ctx, &req.ImLoginFailureLogListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImLoginFailureLogModel{} + } + res = &imloginfailurelog.ListRes{List: list} + res.PageRes.Pack(req, total) + return +} +func (c *cImLoginFailureLog) View(ctx context.Context, req *imloginfailurelog.ViewReq) (*imloginfailurelog.ViewRes, error) { + data, err := service.SysImLoginFailureLog().View(ctx, &req.ImLoginFailureViewInp) + return &imloginfailurelog.ViewRes{ImLoginFailureLogModel: data}, err +} +func (c *cImLoginFailureLog) Export(ctx context.Context, req *imloginfailurelog.ExportReq) (*imloginfailurelog.ExportRes, error) { + return &imloginfailurelog.ExportRes{}, service.SysImLoginFailureLog().Export(ctx, &req.ImLoginFailureLogListInp) +} +func (c *cImLoginFailureLog) AddBlacklist(ctx context.Context, req *imloginfailurelog.AddBlacklistReq) (*imloginfailurelog.AddBlacklistRes, error) { + return &imloginfailurelog.AddBlacklistRes{}, service.SysImLoginFailureLog().AddBlacklist(ctx, &req.ImLoginFailureAddBlacklistInp) +} +func (c *cImLoginFailureLog) BanUser(ctx context.Context, req *imloginfailurelog.BanUserReq) (*imloginfailurelog.BanUserRes, error) { + data, err := service.SysImLoginFailureLog().BanUser(ctx, &req.ImLoginFailureBanUserInp) + return &imloginfailurelog.BanUserRes{ImUserCommandModel: data}, err +} diff --git a/server/internal/controller/admin/sys/im_private_message.go b/server/internal/controller/admin/sys/im_private_message.go new file mode 100644 index 0000000..01d2c15 --- /dev/null +++ b/server/internal/controller/admin/sys/im_private_message.go @@ -0,0 +1,40 @@ +package sys + +import ( + "context" + "hotgo/api/admin/imprivatemessage" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +var ImPrivateMessage = cImPrivateMessage{} + +type cImPrivateMessage struct{} + +func (c *cImPrivateMessage) List(ctx context.Context, req *imprivatemessage.ListReq) (res *imprivatemessage.ListRes, err error) { + list, total, err := service.SysImPrivateMessage().List(ctx, &req.ImPrivateMessageListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImMessageListModel{} + } + res = &imprivatemessage.ListRes{List: list} + res.PageRes.Pack(req, total) + return +} +func (c *cImPrivateMessage) View(ctx context.Context, req *imprivatemessage.ViewReq) (*imprivatemessage.ViewRes, error) { + data, err := service.SysImPrivateMessage().View(ctx, &req.ImMessageViewInp) + return &imprivatemessage.ViewRes{ImMessageViewModel: data}, err +} +func (c *cImPrivateMessage) Hide(ctx context.Context, req *imprivatemessage.HideReq) (*imprivatemessage.HideRes, error) { + data, err := service.SysImPrivateMessage().Hide(ctx, &req.ImMessageActionInp) + return &imprivatemessage.HideRes{ImMessageCommandModel: data}, err +} +func (c *cImPrivateMessage) Delete(ctx context.Context, req *imprivatemessage.DeleteReq) (*imprivatemessage.DeleteRes, error) { + data, err := service.SysImPrivateMessage().Delete(ctx, &req.ImMessageActionInp) + return &imprivatemessage.DeleteRes{ImMessageCommandModel: data}, err +} +func (c *cImPrivateMessage) Export(ctx context.Context, req *imprivatemessage.ExportReq) (*imprivatemessage.ExportRes, error) { + return &imprivatemessage.ExportRes{}, service.SysImPrivateMessage().Export(ctx, &req.ImPrivateMessageListInp) +} diff --git a/server/internal/controller/admin/sys/im_security_policy.go b/server/internal/controller/admin/sys/im_security_policy.go new file mode 100644 index 0000000..a1e87cb --- /dev/null +++ b/server/internal/controller/admin/sys/im_security_policy.go @@ -0,0 +1,72 @@ +package sys + +import ( + "context" + "hotgo/api/admin/imsecuritypolicy" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +var ImSecurityPolicy = cImSecurityPolicy{} + +type cImSecurityPolicy struct{} + +func (c *cImSecurityPolicy) List(ctx context.Context, req *imsecuritypolicy.ListReq) (res *imsecuritypolicy.ListRes, err error) { + list, total, err := service.SysImSecurityPolicy().List(ctx, &req.ImSecurityPolicyListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImSecurityPolicyModel{} + } + res = new(imsecuritypolicy.ListRes) + res.List = list + res.PageRes.Pack(req, total) + return +} +func (c *cImSecurityPolicy) View(ctx context.Context, req *imsecuritypolicy.ViewReq) (res *imsecuritypolicy.ViewRes, err error) { + data, err := service.SysImSecurityPolicy().View(ctx, &req.ImSecurityPolicyViewInp) + if err != nil { + return nil, err + } + return &imsecuritypolicy.ViewRes{ImSecurityPolicyModel: data}, nil +} +func (c *cImSecurityPolicy) Save(ctx context.Context, req *imsecuritypolicy.SaveReq) (res *imsecuritypolicy.SaveRes, err error) { + id, err := service.SysImSecurityPolicy().Save(ctx, &req.ImSecurityPolicySaveInp) + if err != nil { + return nil, err + } + return &imsecuritypolicy.SaveRes{Id: id}, nil +} +func (c *cImSecurityPolicy) Publish(ctx context.Context, req *imsecuritypolicy.PublishReq) (res *imsecuritypolicy.PublishRes, err error) { + err = service.SysImSecurityPolicy().Publish(ctx, &req.ImSecurityPolicyPublishInp) + return +} +func (c *cImSecurityPolicy) RestoreDefault(ctx context.Context, req *imsecuritypolicy.RestoreDefaultReq) (res *imsecuritypolicy.RestoreDefaultRes, err error) { + id, err := service.SysImSecurityPolicy().RestoreDefault(ctx, &req.ImSecurityPolicyRestoreInp) + if err != nil { + return nil, err + } + return &imsecuritypolicy.RestoreDefaultRes{Id: id}, nil +} +func (c *cImSecurityPolicy) IPRuleList(ctx context.Context, req *imsecuritypolicy.IPRuleListReq) (res *imsecuritypolicy.IPRuleListRes, err error) { + list, total, err := service.SysImSecurityPolicy().IPRuleList(ctx, &req.ImSecurityIPRuleListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImSecurityIPRuleModel{} + } + res = new(imsecuritypolicy.IPRuleListRes) + res.List = list + res.PageRes.Pack(req, total) + return +} +func (c *cImSecurityPolicy) IPRuleEdit(ctx context.Context, req *imsecuritypolicy.IPRuleEditReq) (res *imsecuritypolicy.IPRuleEditRes, err error) { + err = service.SysImSecurityPolicy().IPRuleEdit(ctx, &req.ImSecurityIPRuleEditInp) + return +} +func (c *cImSecurityPolicy) IPRuleDelete(ctx context.Context, req *imsecuritypolicy.IPRuleDeleteReq) (res *imsecuritypolicy.IPRuleDeleteRes, err error) { + err = service.SysImSecurityPolicy().IPRuleDelete(ctx, &req.ImSecurityIPRuleDeleteInp) + return +} diff --git a/server/internal/controller/admin/sys/im_sensitive_word.go b/server/internal/controller/admin/sys/im_sensitive_word.go new file mode 100644 index 0000000..cee5752 --- /dev/null +++ b/server/internal/controller/admin/sys/im_sensitive_word.go @@ -0,0 +1,59 @@ +package sys + +import ( + "context" + "hotgo/api/admin/imsensitiveword" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +var ImSensitiveWord = cImSensitiveWord{} + +type cImSensitiveWord struct{} + +func (c *cImSensitiveWord) List(ctx context.Context, req *imsensitiveword.ListReq) (res *imsensitiveword.ListRes, err error) { + list, total, err := service.SysImSensitiveWord().List(ctx, &req.ImSensitiveWordListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImSensitiveWordListModel{} + } + res = new(imsensitiveword.ListRes) + res.List = list + res.PageRes.Pack(req, total) + return +} +func (c *cImSensitiveWord) Edit(ctx context.Context, req *imsensitiveword.EditReq) (res *imsensitiveword.EditRes, err error) { + err = service.SysImSensitiveWord().Edit(ctx, &req.ImSensitiveWordEditInp) + return +} +func (c *cImSensitiveWord) Delete(ctx context.Context, req *imsensitiveword.DeleteReq) (res *imsensitiveword.DeleteRes, err error) { + err = service.SysImSensitiveWord().Delete(ctx, &req.ImSensitiveWordDeleteInp) + return +} +func (c *cImSensitiveWord) Status(ctx context.Context, req *imsensitiveword.StatusReq) (res *imsensitiveword.StatusRes, err error) { + err = service.SysImSensitiveWord().Status(ctx, &req.ImSensitiveWordStatusInp) + return +} +func (c *cImSensitiveWord) BatchImport(ctx context.Context, req *imsensitiveword.BatchImportReq) (res *imsensitiveword.BatchImportRes, err error) { + data, err := service.SysImSensitiveWord().BatchImport(ctx, &req.ImSensitiveWordBatchImportInp) + if err != nil { + return nil, err + } + return &imsensitiveword.BatchImportRes{ImSensitiveWordBatchImportModel: data}, nil +} +func (c *cImSensitiveWord) GroupList(ctx context.Context, req *imsensitiveword.GroupListReq) (res *imsensitiveword.GroupListRes, err error) { + list, err := service.SysImSensitiveWord().GroupList(ctx, &req.ImSensitiveWordGroupListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImSensitiveWordGroupModel{} + } + return &imsensitiveword.GroupListRes{List: list}, nil +} +func (c *cImSensitiveWord) GroupEdit(ctx context.Context, req *imsensitiveword.GroupEditReq) (res *imsensitiveword.GroupEditRes, err error) { + err = service.SysImSensitiveWord().GroupEdit(ctx, &req.ImSensitiveWordGroupEditInp) + return +} diff --git a/server/internal/controller/admin/sys/im_user_login_history.go b/server/internal/controller/admin/sys/im_user_login_history.go new file mode 100644 index 0000000..27c4464 --- /dev/null +++ b/server/internal/controller/admin/sys/im_user_login_history.go @@ -0,0 +1,28 @@ +package sys + +import ( + "context" + "hotgo/api/admin/imuserloginhistory" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +var ImUserLoginHistory = cImUserLoginHistory{} + +type cImUserLoginHistory struct{} + +func (c *cImUserLoginHistory) List(ctx context.Context, req *imuserloginhistory.ListReq) (res *imuserloginhistory.ListRes, err error) { + list, total, err := service.SysImUserLoginHistory().List(ctx, &req.ImUserLoginHistoryListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImUserLoginHistoryModel{} + } + res = &imuserloginhistory.ListRes{List: list} + res.PageRes.Pack(req, total) + return +} +func (c *cImUserLoginHistory) Export(ctx context.Context, req *imuserloginhistory.ExportReq) (*imuserloginhistory.ExportRes, error) { + return &imuserloginhistory.ExportRes{}, service.SysImUserLoginHistory().Export(ctx, &req.ImUserLoginHistoryListInp) +} diff --git a/server/internal/controller/admin/sys/im_user_policy_group.go b/server/internal/controller/admin/sys/im_user_policy_group.go new file mode 100644 index 0000000..5e70617 --- /dev/null +++ b/server/internal/controller/admin/sys/im_user_policy_group.go @@ -0,0 +1,66 @@ +package sys + +import ( + "context" + "hotgo/api/admin/imuserpolicygroup" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" +) + +var ImUserPolicyGroup = cImUserPolicyGroup{} + +type cImUserPolicyGroup struct{} + +func (c *cImUserPolicyGroup) List(ctx context.Context, req *imuserpolicygroup.ListReq) (res *imuserpolicygroup.ListRes, err error) { + list, total, err := service.SysImUserPolicyGroup().List(ctx, &req.ImUserPolicyGroupListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImUserPolicyGroupListModel{} + } + res = new(imuserpolicygroup.ListRes) + res.List = list + res.PageRes.Pack(req, total) + return +} +func (c *cImUserPolicyGroup) View(ctx context.Context, req *imuserpolicygroup.ViewReq) (res *imuserpolicygroup.ViewRes, err error) { + data, err := service.SysImUserPolicyGroup().View(ctx, &req.ImUserPolicyGroupViewInp) + if err != nil { + return nil, err + } + return &imuserpolicygroup.ViewRes{ImUserPolicyGroupViewModel: data}, nil +} +func (c *cImUserPolicyGroup) Edit(ctx context.Context, req *imuserpolicygroup.EditReq) (res *imuserpolicygroup.EditRes, err error) { + err = service.SysImUserPolicyGroup().Edit(ctx, &req.ImUserPolicyGroupEditInp) + return +} +func (c *cImUserPolicyGroup) Delete(ctx context.Context, req *imuserpolicygroup.DeleteReq) (res *imuserpolicygroup.DeleteRes, err error) { + err = service.SysImUserPolicyGroup().Delete(ctx, &req.ImUserPolicyGroupDeleteInp) + return +} +func (c *cImUserPolicyGroup) Status(ctx context.Context, req *imuserpolicygroup.StatusReq) (res *imuserpolicygroup.StatusRes, err error) { + err = service.SysImUserPolicyGroup().Status(ctx, &req.ImUserPolicyGroupStatusInp) + return +} +func (c *cImUserPolicyGroup) MemberList(ctx context.Context, req *imuserpolicygroup.MemberListReq) (res *imuserpolicygroup.MemberListRes, err error) { + list, total, err := service.SysImUserPolicyGroup().MemberList(ctx, &req.ImUserPolicyGroupMemberListInp) + if err != nil { + return nil, err + } + if list == nil { + list = []*sysin.ImUserPolicyGroupMemberModel{} + } + res = new(imuserpolicygroup.MemberListRes) + res.List = list + res.PageRes.Pack(req, total) + return +} +func (c *cImUserPolicyGroup) MemberAdd(ctx context.Context, req *imuserpolicygroup.MemberAddReq) (res *imuserpolicygroup.MemberAddRes, err error) { + err = service.SysImUserPolicyGroup().MemberAdd(ctx, &req.ImUserPolicyGroupMemberAddInp) + return +} +func (c *cImUserPolicyGroup) MemberRemove(ctx context.Context, req *imuserpolicygroup.MemberRemoveReq) (res *imuserpolicygroup.MemberRemoveRes, err error) { + err = service.SysImUserPolicyGroup().MemberRemove(ctx, &req.ImUserPolicyGroupMemberRemoveInp) + return +} diff --git a/server/internal/dao/im_message_curfew_rules.go b/server/internal/dao/im_message_curfew_rules.go new file mode 100644 index 0000000..5120dcf --- /dev/null +++ b/server/internal/dao/im_message_curfew_rules.go @@ -0,0 +1,22 @@ +// ================================================================================= +// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed. +// ================================================================================= + +package dao + +import ( + "hotgo/internal/dao/internal" +) + +// imMessageCurfewRulesDao is the data access object for the table im_message_curfew_rules. +// You can define custom methods on it to extend its functionality as needed. +type imMessageCurfewRulesDao struct { + *internal.ImMessageCurfewRulesDao +} + +var ( + // ImMessageCurfewRules is a globally accessible object for table im_message_curfew_rules operations. + ImMessageCurfewRules = imMessageCurfewRulesDao{internal.NewImMessageCurfewRulesDao()} +) + +// Add your custom methods and functionality below. diff --git a/server/internal/dao/im_security_ip_rules.go b/server/internal/dao/im_security_ip_rules.go new file mode 100644 index 0000000..9d5a7ff --- /dev/null +++ b/server/internal/dao/im_security_ip_rules.go @@ -0,0 +1,22 @@ +// ================================================================================= +// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed. +// ================================================================================= + +package dao + +import ( + "hotgo/internal/dao/internal" +) + +// imSecurityIpRulesDao is the data access object for the table im_security_ip_rules. +// You can define custom methods on it to extend its functionality as needed. +type imSecurityIpRulesDao struct { + *internal.ImSecurityIpRulesDao +} + +var ( + // ImSecurityIpRules is a globally accessible object for table im_security_ip_rules operations. + ImSecurityIpRules = imSecurityIpRulesDao{internal.NewImSecurityIpRulesDao()} +) + +// Add your custom methods and functionality below. diff --git a/server/internal/dao/im_security_policy.go b/server/internal/dao/im_security_policy.go new file mode 100644 index 0000000..3fd9249 --- /dev/null +++ b/server/internal/dao/im_security_policy.go @@ -0,0 +1,22 @@ +// ================================================================================= +// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed. +// ================================================================================= + +package dao + +import ( + "hotgo/internal/dao/internal" +) + +// imSecurityPolicyDao is the data access object for the table im_security_policy. +// You can define custom methods on it to extend its functionality as needed. +type imSecurityPolicyDao struct { + *internal.ImSecurityPolicyDao +} + +var ( + // ImSecurityPolicy is a globally accessible object for table im_security_policy operations. + ImSecurityPolicy = imSecurityPolicyDao{internal.NewImSecurityPolicyDao()} +) + +// Add your custom methods and functionality below. diff --git a/server/internal/dao/im_sensitive_word_groups.go b/server/internal/dao/im_sensitive_word_groups.go new file mode 100644 index 0000000..bd5d607 --- /dev/null +++ b/server/internal/dao/im_sensitive_word_groups.go @@ -0,0 +1,22 @@ +// ================================================================================= +// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed. +// ================================================================================= + +package dao + +import ( + "hotgo/internal/dao/internal" +) + +// imSensitiveWordGroupsDao is the data access object for the table im_sensitive_word_groups. +// You can define custom methods on it to extend its functionality as needed. +type imSensitiveWordGroupsDao struct { + *internal.ImSensitiveWordGroupsDao +} + +var ( + // ImSensitiveWordGroups is a globally accessible object for table im_sensitive_word_groups operations. + ImSensitiveWordGroups = imSensitiveWordGroupsDao{internal.NewImSensitiveWordGroupsDao()} +) + +// Add your custom methods and functionality below. diff --git a/server/internal/dao/im_sensitive_words.go b/server/internal/dao/im_sensitive_words.go new file mode 100644 index 0000000..be86128 --- /dev/null +++ b/server/internal/dao/im_sensitive_words.go @@ -0,0 +1,22 @@ +// ================================================================================= +// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed. +// ================================================================================= + +package dao + +import ( + "hotgo/internal/dao/internal" +) + +// imSensitiveWordsDao is the data access object for the table im_sensitive_words. +// You can define custom methods on it to extend its functionality as needed. +type imSensitiveWordsDao struct { + *internal.ImSensitiveWordsDao +} + +var ( + // ImSensitiveWords is a globally accessible object for table im_sensitive_words operations. + ImSensitiveWords = imSensitiveWordsDao{internal.NewImSensitiveWordsDao()} +) + +// Add your custom methods and functionality below. diff --git a/server/internal/dao/im_user_policy_group_members.go b/server/internal/dao/im_user_policy_group_members.go new file mode 100644 index 0000000..6dff14d --- /dev/null +++ b/server/internal/dao/im_user_policy_group_members.go @@ -0,0 +1,22 @@ +// ================================================================================= +// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed. +// ================================================================================= + +package dao + +import ( + "hotgo/internal/dao/internal" +) + +// imUserPolicyGroupMembersDao is the data access object for the table im_user_policy_group_members. +// You can define custom methods on it to extend its functionality as needed. +type imUserPolicyGroupMembersDao struct { + *internal.ImUserPolicyGroupMembersDao +} + +var ( + // ImUserPolicyGroupMembers is a globally accessible object for table im_user_policy_group_members operations. + ImUserPolicyGroupMembers = imUserPolicyGroupMembersDao{internal.NewImUserPolicyGroupMembersDao()} +) + +// Add your custom methods and functionality below. diff --git a/server/internal/dao/im_user_policy_groups.go b/server/internal/dao/im_user_policy_groups.go new file mode 100644 index 0000000..0fffda4 --- /dev/null +++ b/server/internal/dao/im_user_policy_groups.go @@ -0,0 +1,22 @@ +// ================================================================================= +// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed. +// ================================================================================= + +package dao + +import ( + "hotgo/internal/dao/internal" +) + +// imUserPolicyGroupsDao is the data access object for the table im_user_policy_groups. +// You can define custom methods on it to extend its functionality as needed. +type imUserPolicyGroupsDao struct { + *internal.ImUserPolicyGroupsDao +} + +var ( + // ImUserPolicyGroups is a globally accessible object for table im_user_policy_groups operations. + ImUserPolicyGroups = imUserPolicyGroupsDao{internal.NewImUserPolicyGroupsDao()} +) + +// Add your custom methods and functionality below. diff --git a/server/internal/dao/internal/im_message_curfew_rules.go b/server/internal/dao/internal/im_message_curfew_rules.go new file mode 100644 index 0000000..c796a5b --- /dev/null +++ b/server/internal/dao/internal/im_message_curfew_rules.go @@ -0,0 +1,123 @@ +// ========================================================================== +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// ImMessageCurfewRulesDao is the data access object for the table im_message_curfew_rules. +type ImMessageCurfewRulesDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns ImMessageCurfewRulesColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. +} + +// ImMessageCurfewRulesColumns defines and stores column names for the table im_message_curfew_rules. +type ImMessageCurfewRulesColumns struct { + Id string // + TenantId string // + PolicyId string // + RuleCode string // + RuleName string // + DateType string // daily, weekday, weekend, custom + CustomDates string // YYYY-MM-DD values for custom date type + Weekdays string // ISO weekdays 1 through 7 + Timezone string // + StartTime string // + EndTime string // Less than start_time means crossing midnight + Scope string // private_message or group_message + WhitelistUserIds string // + WhitelistGroupIds string // + Message string // + Status string // 1 enabled, 2 disabled + Sort string // + CreatedAt string // + CreatedBy string // + UpdatedAt string // + UpdatedBy string // + DeletedAt string // + DeletedBy string // +} + +// imMessageCurfewRulesColumns holds the columns for the table im_message_curfew_rules. +var imMessageCurfewRulesColumns = ImMessageCurfewRulesColumns{ + Id: "id", + TenantId: "tenant_id", + PolicyId: "policy_id", + RuleCode: "rule_code", + RuleName: "rule_name", + DateType: "date_type", + CustomDates: "custom_dates", + Weekdays: "weekdays", + Timezone: "timezone", + StartTime: "start_time", + EndTime: "end_time", + Scope: "scope", + WhitelistUserIds: "whitelist_user_ids", + WhitelistGroupIds: "whitelist_group_ids", + Message: "message", + Status: "status", + Sort: "sort", + CreatedAt: "created_at", + CreatedBy: "created_by", + UpdatedAt: "updated_at", + UpdatedBy: "updated_by", + DeletedAt: "deleted_at", + DeletedBy: "deleted_by", +} + +// NewImMessageCurfewRulesDao creates and returns a new DAO object for table data access. +func NewImMessageCurfewRulesDao(handlers ...gdb.ModelHandler) *ImMessageCurfewRulesDao { + return &ImMessageCurfewRulesDao{ + group: "default", + table: "im_message_curfew_rules", + columns: imMessageCurfewRulesColumns, + handlers: handlers, + } +} + +// DB retrieves and returns the underlying raw database management object of the current DAO. +func (dao *ImMessageCurfewRulesDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of the current DAO. +func (dao *ImMessageCurfewRulesDao) Table() string { + return dao.table +} + +// Columns returns all column names of the current DAO. +func (dao *ImMessageCurfewRulesDao) Columns() ImMessageCurfewRulesColumns { + return dao.columns +} + +// Group returns the database configuration group name of the current DAO. +func (dao *ImMessageCurfewRulesDao) Group() string { + return dao.group +} + +// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. +func (dao *ImMessageCurfewRulesDao) Ctx(ctx context.Context) *gdb.Model { + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rolls back the transaction and returns the error if function f returns a non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note: Do not commit or roll back the transaction in function f, +// as it is automatically handled by this function. +func (dao *ImMessageCurfewRulesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/server/internal/dao/internal/im_security_ip_rules.go b/server/internal/dao/internal/im_security_ip_rules.go new file mode 100644 index 0000000..5e67561 --- /dev/null +++ b/server/internal/dao/internal/im_security_ip_rules.go @@ -0,0 +1,109 @@ +// ========================================================================== +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// ImSecurityIpRulesDao is the data access object for the table im_security_ip_rules. +type ImSecurityIpRulesDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns ImSecurityIpRulesColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. +} + +// ImSecurityIpRulesColumns defines and stores column names for the table im_security_ip_rules. +type ImSecurityIpRulesColumns struct { + Id string // + TenantId string // + RuleType string // whitelist or blacklist + IpCidr string // IPv4, IPv6 or CIDR + Action string // allow, challenge, block, audit_only + SceneJson string // login, register, message, upload and other scenes + RiskLevel string // + Status string // 1 enabled, 2 disabled + ExpiresAt string // + Remark string // + CreatedAt string // + CreatedBy string // + UpdatedAt string // + UpdatedBy string // + DeletedAt string // + DeletedBy string // +} + +// imSecurityIpRulesColumns holds the columns for the table im_security_ip_rules. +var imSecurityIpRulesColumns = ImSecurityIpRulesColumns{ + Id: "id", + TenantId: "tenant_id", + RuleType: "rule_type", + IpCidr: "ip_cidr", + Action: "action", + SceneJson: "scene_json", + RiskLevel: "risk_level", + Status: "status", + ExpiresAt: "expires_at", + Remark: "remark", + CreatedAt: "created_at", + CreatedBy: "created_by", + UpdatedAt: "updated_at", + UpdatedBy: "updated_by", + DeletedAt: "deleted_at", + DeletedBy: "deleted_by", +} + +// NewImSecurityIpRulesDao creates and returns a new DAO object for table data access. +func NewImSecurityIpRulesDao(handlers ...gdb.ModelHandler) *ImSecurityIpRulesDao { + return &ImSecurityIpRulesDao{ + group: "default", + table: "im_security_ip_rules", + columns: imSecurityIpRulesColumns, + handlers: handlers, + } +} + +// DB retrieves and returns the underlying raw database management object of the current DAO. +func (dao *ImSecurityIpRulesDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of the current DAO. +func (dao *ImSecurityIpRulesDao) Table() string { + return dao.table +} + +// Columns returns all column names of the current DAO. +func (dao *ImSecurityIpRulesDao) Columns() ImSecurityIpRulesColumns { + return dao.columns +} + +// Group returns the database configuration group name of the current DAO. +func (dao *ImSecurityIpRulesDao) Group() string { + return dao.group +} + +// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. +func (dao *ImSecurityIpRulesDao) Ctx(ctx context.Context) *gdb.Model { + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rolls back the transaction and returns the error if function f returns a non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note: Do not commit or roll back the transaction in function f, +// as it is automatically handled by this function. +func (dao *ImSecurityIpRulesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/server/internal/dao/internal/im_security_policy.go b/server/internal/dao/internal/im_security_policy.go new file mode 100644 index 0000000..12b402a --- /dev/null +++ b/server/internal/dao/internal/im_security_policy.go @@ -0,0 +1,123 @@ +// ========================================================================== +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// ImSecurityPolicyDao is the data access object for the table im_security_policy. +type ImSecurityPolicyDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns ImSecurityPolicyColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. +} + +// ImSecurityPolicyColumns defines and stores column names for the table im_security_policy. +type ImSecurityPolicyColumns struct { + Id string // + TenantId string // 0 means global fallback policy + PolicyVersion string // + PolicyName string // + PublishStatus string // + PasswordPolicy string // + LoginRateLimit string // + SensitiveWordPolicy string // + FileReviewPolicy string // + RealnamePolicy string // + RiskChallengePolicy string // + GlobalFriendEnabled string // Backend master switch for every add-friend entry + FriendDisabledPolicy string // Profile masking, QR and group-member restrictions + MessageCurfewEnabled string // Backend master switch for message curfew + Remark string // + PublishedAt string // + PublishedBy string // + CreatedAt string // + CreatedBy string // + UpdatedAt string // + UpdatedBy string // + DeletedAt string // + DeletedBy string // +} + +// imSecurityPolicyColumns holds the columns for the table im_security_policy. +var imSecurityPolicyColumns = ImSecurityPolicyColumns{ + Id: "id", + TenantId: "tenant_id", + PolicyVersion: "policy_version", + PolicyName: "policy_name", + PublishStatus: "publish_status", + PasswordPolicy: "password_policy", + LoginRateLimit: "login_rate_limit", + SensitiveWordPolicy: "sensitive_word_policy", + FileReviewPolicy: "file_review_policy", + RealnamePolicy: "realname_policy", + RiskChallengePolicy: "risk_challenge_policy", + GlobalFriendEnabled: "global_friend_enabled", + FriendDisabledPolicy: "friend_disabled_policy", + MessageCurfewEnabled: "message_curfew_enabled", + Remark: "remark", + PublishedAt: "published_at", + PublishedBy: "published_by", + CreatedAt: "created_at", + CreatedBy: "created_by", + UpdatedAt: "updated_at", + UpdatedBy: "updated_by", + DeletedAt: "deleted_at", + DeletedBy: "deleted_by", +} + +// NewImSecurityPolicyDao creates and returns a new DAO object for table data access. +func NewImSecurityPolicyDao(handlers ...gdb.ModelHandler) *ImSecurityPolicyDao { + return &ImSecurityPolicyDao{ + group: "default", + table: "im_security_policy", + columns: imSecurityPolicyColumns, + handlers: handlers, + } +} + +// DB retrieves and returns the underlying raw database management object of the current DAO. +func (dao *ImSecurityPolicyDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of the current DAO. +func (dao *ImSecurityPolicyDao) Table() string { + return dao.table +} + +// Columns returns all column names of the current DAO. +func (dao *ImSecurityPolicyDao) Columns() ImSecurityPolicyColumns { + return dao.columns +} + +// Group returns the database configuration group name of the current DAO. +func (dao *ImSecurityPolicyDao) Group() string { + return dao.group +} + +// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. +func (dao *ImSecurityPolicyDao) Ctx(ctx context.Context) *gdb.Model { + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rolls back the transaction and returns the error if function f returns a non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note: Do not commit or roll back the transaction in function f, +// as it is automatically handled by this function. +func (dao *ImSecurityPolicyDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/server/internal/dao/internal/im_sensitive_word_groups.go b/server/internal/dao/internal/im_sensitive_word_groups.go new file mode 100644 index 0000000..c130c56 --- /dev/null +++ b/server/internal/dao/internal/im_sensitive_word_groups.go @@ -0,0 +1,103 @@ +// ========================================================================== +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// ImSensitiveWordGroupsDao is the data access object for the table im_sensitive_word_groups. +type ImSensitiveWordGroupsDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns ImSensitiveWordGroupsColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. +} + +// ImSensitiveWordGroupsColumns defines and stores column names for the table im_sensitive_word_groups. +type ImSensitiveWordGroupsColumns struct { + Id string // + TenantId string // 0 means global dictionary + GroupCode string // + GroupName string // + Priority string // + Status string // 1 enabled, 2 disabled + Remark string // + CreatedAt string // + CreatedBy string // + UpdatedAt string // + UpdatedBy string // + DeletedAt string // + DeletedBy string // +} + +// imSensitiveWordGroupsColumns holds the columns for the table im_sensitive_word_groups. +var imSensitiveWordGroupsColumns = ImSensitiveWordGroupsColumns{ + Id: "id", + TenantId: "tenant_id", + GroupCode: "group_code", + GroupName: "group_name", + Priority: "priority", + Status: "status", + Remark: "remark", + CreatedAt: "created_at", + CreatedBy: "created_by", + UpdatedAt: "updated_at", + UpdatedBy: "updated_by", + DeletedAt: "deleted_at", + DeletedBy: "deleted_by", +} + +// NewImSensitiveWordGroupsDao creates and returns a new DAO object for table data access. +func NewImSensitiveWordGroupsDao(handlers ...gdb.ModelHandler) *ImSensitiveWordGroupsDao { + return &ImSensitiveWordGroupsDao{ + group: "default", + table: "im_sensitive_word_groups", + columns: imSensitiveWordGroupsColumns, + handlers: handlers, + } +} + +// DB retrieves and returns the underlying raw database management object of the current DAO. +func (dao *ImSensitiveWordGroupsDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of the current DAO. +func (dao *ImSensitiveWordGroupsDao) Table() string { + return dao.table +} + +// Columns returns all column names of the current DAO. +func (dao *ImSensitiveWordGroupsDao) Columns() ImSensitiveWordGroupsColumns { + return dao.columns +} + +// Group returns the database configuration group name of the current DAO. +func (dao *ImSensitiveWordGroupsDao) Group() string { + return dao.group +} + +// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. +func (dao *ImSensitiveWordGroupsDao) Ctx(ctx context.Context) *gdb.Model { + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rolls back the transaction and returns the error if function f returns a non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note: Do not commit or roll back the transaction in function f, +// as it is automatically handled by this function. +func (dao *ImSensitiveWordGroupsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/server/internal/dao/internal/im_sensitive_words.go b/server/internal/dao/internal/im_sensitive_words.go new file mode 100644 index 0000000..aa1b7ed --- /dev/null +++ b/server/internal/dao/internal/im_sensitive_words.go @@ -0,0 +1,115 @@ +// ========================================================================== +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// ImSensitiveWordsDao is the data access object for the table im_sensitive_words. +type ImSensitiveWordsDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns ImSensitiveWordsColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. +} + +// ImSensitiveWordsColumns defines and stores column names for the table im_sensitive_words. +type ImSensitiveWordsColumns struct { + Id string // + TenantId string // 0 means global dictionary + GroupId string // + Word string // + WordHash string // SHA-256 of normalized word + MatchType string // + SceneJson string // Enabled scenes + Action string // + Replacement string // + RiskLevel string // + Priority string // + Status string // 1 enabled, 2 disabled + Remark string // + CreatedAt string // + CreatedBy string // + UpdatedAt string // + UpdatedBy string // + DeletedAt string // + DeletedBy string // +} + +// imSensitiveWordsColumns holds the columns for the table im_sensitive_words. +var imSensitiveWordsColumns = ImSensitiveWordsColumns{ + Id: "id", + TenantId: "tenant_id", + GroupId: "group_id", + Word: "word", + WordHash: "word_hash", + MatchType: "match_type", + SceneJson: "scene_json", + Action: "action", + Replacement: "replacement", + RiskLevel: "risk_level", + Priority: "priority", + Status: "status", + Remark: "remark", + CreatedAt: "created_at", + CreatedBy: "created_by", + UpdatedAt: "updated_at", + UpdatedBy: "updated_by", + DeletedAt: "deleted_at", + DeletedBy: "deleted_by", +} + +// NewImSensitiveWordsDao creates and returns a new DAO object for table data access. +func NewImSensitiveWordsDao(handlers ...gdb.ModelHandler) *ImSensitiveWordsDao { + return &ImSensitiveWordsDao{ + group: "default", + table: "im_sensitive_words", + columns: imSensitiveWordsColumns, + handlers: handlers, + } +} + +// DB retrieves and returns the underlying raw database management object of the current DAO. +func (dao *ImSensitiveWordsDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of the current DAO. +func (dao *ImSensitiveWordsDao) Table() string { + return dao.table +} + +// Columns returns all column names of the current DAO. +func (dao *ImSensitiveWordsDao) Columns() ImSensitiveWordsColumns { + return dao.columns +} + +// Group returns the database configuration group name of the current DAO. +func (dao *ImSensitiveWordsDao) Group() string { + return dao.group +} + +// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. +func (dao *ImSensitiveWordsDao) Ctx(ctx context.Context) *gdb.Model { + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rolls back the transaction and returns the error if function f returns a non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note: Do not commit or roll back the transaction in function f, +// as it is automatically handled by this function. +func (dao *ImSensitiveWordsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/server/internal/dao/internal/im_tenant_config.go b/server/internal/dao/internal/im_tenant_config.go index 3e60943..16bc159 100644 --- a/server/internal/dao/internal/im_tenant_config.go +++ b/server/internal/dao/internal/im_tenant_config.go @@ -21,28 +21,36 @@ type ImTenantConfigDao struct { // ImTenantConfigColumns defines and stores column names for the table im_tenant_config. type ImTenantConfigColumns struct { - Id string // - TenantId string // - MaxUsers string // 0 means unlimited - MaxGroups string // 0 means unlimited - MaxGroupMembers string // 0 means unlimited - CreatedAt string // - CreatedBy string // - UpdatedAt string // - UpdatedBy string // + Id string // + TenantId string // + MaxUsers string // 0 means unlimited + MaxGroups string // 0 means unlimited + MaxGroupMembers string // 0 means unlimited + DefaultPolicyGroupId string // Default user policy group + SecurityPolicyVersion string // Published security policy version + GlobalFriendEnabled string // Published global friend switch + MessageCurfewEnabled string // Published message curfew switch + CreatedAt string // + CreatedBy string // + UpdatedAt string // + UpdatedBy string // } // imTenantConfigColumns holds the columns for the table im_tenant_config. var imTenantConfigColumns = ImTenantConfigColumns{ - Id: "id", - TenantId: "tenant_id", - MaxUsers: "max_users", - MaxGroups: "max_groups", - MaxGroupMembers: "max_group_members", - CreatedAt: "created_at", - CreatedBy: "created_by", - UpdatedAt: "updated_at", - UpdatedBy: "updated_by", + Id: "id", + TenantId: "tenant_id", + MaxUsers: "max_users", + MaxGroups: "max_groups", + MaxGroupMembers: "max_group_members", + DefaultPolicyGroupId: "default_policy_group_id", + SecurityPolicyVersion: "security_policy_version", + GlobalFriendEnabled: "global_friend_enabled", + MessageCurfewEnabled: "message_curfew_enabled", + CreatedAt: "created_at", + CreatedBy: "created_by", + UpdatedAt: "updated_at", + UpdatedBy: "updated_by", } // NewImTenantConfigDao creates and returns a new DAO object for table data access. diff --git a/server/internal/dao/internal/im_user_policy_group_members.go b/server/internal/dao/internal/im_user_policy_group_members.go new file mode 100644 index 0000000..17b3ccd --- /dev/null +++ b/server/internal/dao/internal/im_user_policy_group_members.go @@ -0,0 +1,105 @@ +// ========================================================================== +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// ImUserPolicyGroupMembersDao is the data access object for the table im_user_policy_group_members. +type ImUserPolicyGroupMembersDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns ImUserPolicyGroupMembersColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. +} + +// ImUserPolicyGroupMembersColumns defines and stores column names for the table im_user_policy_group_members. +type ImUserPolicyGroupMembersColumns struct { + Id string // + TenantId string // + GroupId string // + UserId string // User ID in the tenant database + Status string // 1 enabled, 2 disabled + ValidFrom string // + ValidUntil string // + Remark string // + CreatedAt string // + CreatedBy string // + UpdatedAt string // + UpdatedBy string // + DeletedAt string // + DeletedBy string // +} + +// imUserPolicyGroupMembersColumns holds the columns for the table im_user_policy_group_members. +var imUserPolicyGroupMembersColumns = ImUserPolicyGroupMembersColumns{ + Id: "id", + TenantId: "tenant_id", + GroupId: "group_id", + UserId: "user_id", + Status: "status", + ValidFrom: "valid_from", + ValidUntil: "valid_until", + Remark: "remark", + CreatedAt: "created_at", + CreatedBy: "created_by", + UpdatedAt: "updated_at", + UpdatedBy: "updated_by", + DeletedAt: "deleted_at", + DeletedBy: "deleted_by", +} + +// NewImUserPolicyGroupMembersDao creates and returns a new DAO object for table data access. +func NewImUserPolicyGroupMembersDao(handlers ...gdb.ModelHandler) *ImUserPolicyGroupMembersDao { + return &ImUserPolicyGroupMembersDao{ + group: "default", + table: "im_user_policy_group_members", + columns: imUserPolicyGroupMembersColumns, + handlers: handlers, + } +} + +// DB retrieves and returns the underlying raw database management object of the current DAO. +func (dao *ImUserPolicyGroupMembersDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of the current DAO. +func (dao *ImUserPolicyGroupMembersDao) Table() string { + return dao.table +} + +// Columns returns all column names of the current DAO. +func (dao *ImUserPolicyGroupMembersDao) Columns() ImUserPolicyGroupMembersColumns { + return dao.columns +} + +// Group returns the database configuration group name of the current DAO. +func (dao *ImUserPolicyGroupMembersDao) Group() string { + return dao.group +} + +// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. +func (dao *ImUserPolicyGroupMembersDao) Ctx(ctx context.Context) *gdb.Model { + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rolls back the transaction and returns the error if function f returns a non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note: Do not commit or roll back the transaction in function f, +// as it is automatically handled by this function. +func (dao *ImUserPolicyGroupMembersDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/server/internal/dao/internal/im_user_policy_groups.go b/server/internal/dao/internal/im_user_policy_groups.go new file mode 100644 index 0000000..8cbbe72 --- /dev/null +++ b/server/internal/dao/internal/im_user_policy_groups.go @@ -0,0 +1,111 @@ +// ========================================================================== +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// ImUserPolicyGroupsDao is the data access object for the table im_user_policy_groups. +type ImUserPolicyGroupsDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns ImUserPolicyGroupsColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. +} + +// ImUserPolicyGroupsColumns defines and stores column names for the table im_user_policy_groups. +type ImUserPolicyGroupsColumns struct { + Id string // + TenantId string // 0 means global default + GroupCode string // Stable policy group code + GroupName string // Policy group name + Priority string // Higher value has higher priority + Status string // 1 enabled, 2 disabled + PolicyJson string // Login, friend, message, group and file policies + IpWhitelist string // IPv4/IPv6 or CIDR list + IpBlacklist string // IPv4/IPv6 or CIDR list + Version string // Optimistic-lock/config version + Remark string // + CreatedAt string // + CreatedBy string // + UpdatedAt string // + UpdatedBy string // + DeletedAt string // + DeletedBy string // +} + +// imUserPolicyGroupsColumns holds the columns for the table im_user_policy_groups. +var imUserPolicyGroupsColumns = ImUserPolicyGroupsColumns{ + Id: "id", + TenantId: "tenant_id", + GroupCode: "group_code", + GroupName: "group_name", + Priority: "priority", + Status: "status", + PolicyJson: "policy_json", + IpWhitelist: "ip_whitelist", + IpBlacklist: "ip_blacklist", + Version: "version", + Remark: "remark", + CreatedAt: "created_at", + CreatedBy: "created_by", + UpdatedAt: "updated_at", + UpdatedBy: "updated_by", + DeletedAt: "deleted_at", + DeletedBy: "deleted_by", +} + +// NewImUserPolicyGroupsDao creates and returns a new DAO object for table data access. +func NewImUserPolicyGroupsDao(handlers ...gdb.ModelHandler) *ImUserPolicyGroupsDao { + return &ImUserPolicyGroupsDao{ + group: "default", + table: "im_user_policy_groups", + columns: imUserPolicyGroupsColumns, + handlers: handlers, + } +} + +// DB retrieves and returns the underlying raw database management object of the current DAO. +func (dao *ImUserPolicyGroupsDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of the current DAO. +func (dao *ImUserPolicyGroupsDao) Table() string { + return dao.table +} + +// Columns returns all column names of the current DAO. +func (dao *ImUserPolicyGroupsDao) Columns() ImUserPolicyGroupsColumns { + return dao.columns +} + +// Group returns the database configuration group name of the current DAO. +func (dao *ImUserPolicyGroupsDao) Group() string { + return dao.group +} + +// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. +func (dao *ImUserPolicyGroupsDao) Ctx(ctx context.Context) *gdb.Model { + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rolls back the transaction and returns the error if function f returns a non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note: Do not commit or roll back the transaction in function f, +// as it is automatically handled by this function. +func (dao *ImUserPolicyGroupsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/server/internal/library/casbin/casbin_test.go b/server/internal/library/casbin/casbin_test.go index 6dafe7a..ef05df9 100644 --- a/server/internal/library/casbin/casbin_test.go +++ b/server/internal/library/casbin/casbin_test.go @@ -1,67 +1,66 @@ -// Package casbin -// @Link https://github.com/bufanyun/hotgo -// @Copyright Copyright (c) 2023 HotGo CLI -// @Author Ms <133814250@qq.com> -// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE package casbin import ( - "context" "net/http" "testing" + + casbinv2 "github.com/casbin/casbin/v2" + "github.com/casbin/casbin/v2/model" ) -// TestNew description -func TestNew(t *testing.T) { +const testModel = ` +[request_definition] +r = sub, obj, act - InitEnforcer(context.TODO()) +[policy_definition] +p = sub, obj, act - user := "admin" - path := "/" - method := http.MethodGet - t.Logf("\nuser:%v\npath:%v\nmethod:%v", user, path, method) +[role_definition] +g = _, _ - ok, err := Enforcer.DeletePermissionsForUser(user) +[policy_effect] +e = some(where (p.eft == allow)) + +[matchers] +m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act) +` + +func TestEnforcerPermissions(t *testing.T) { + m, err := model.NewModelFromString(testModel) if err != nil { - t.Error(err) + t.Fatalf("创建Casbin测试模型失败: %v", err) } - t.Logf("delete user premission:%v", ok) - CheckPremission(t, user, path, method) - AddPremission(t, user, "*", ActionAll) - CheckPremission(t, user, path, method) - - user1 := "user1" - path1 := "/api/v1/*" - checkPathTrue := "/api/v1/user/list" - checkPathFalse := "/api/v2/user/list" - AddPremission(t, user1, path1, ActionAll) - CheckPremission(t, user1, checkPathTrue, ActionPost) - CheckPremission(t, user1, checkPathFalse, http.MethodGet) - CheckPremission(t, user1, checkPathTrue, http.MethodGet) - CheckPremission(t, user1, "/api/v1/user/list2", http.MethodGet) - - ok, err = Enforcer.DeletePermissionsForUser(user1) + enforcer, err := casbinv2.NewEnforcer(m) if err != nil { - t.Error(err) + t.Fatalf("创建Casbin测试实例失败: %v", err) } - t.Logf("delete user premission:%v", ok) - CheckPremission(t, user1, "/api/v1/user1/list", http.MethodGet) + + assertPermission(t, enforcer, "admin", "/", http.MethodGet, false) + if ok, addErr := enforcer.AddPolicy("admin", "*", ActionAll); addErr != nil || !ok { + t.Fatalf("添加管理员策略失败: ok=%v err=%v", ok, addErr) + } + assertPermission(t, enforcer, "admin", "/", http.MethodGet, true) + + if ok, addErr := enforcer.AddPolicy("user1", "/api/v1/*", ActionAll); addErr != nil || !ok { + t.Fatalf("添加用户策略失败: ok=%v err=%v", ok, addErr) + } + assertPermission(t, enforcer, "user1", "/api/v1/user/list", http.MethodPost, true) + assertPermission(t, enforcer, "user1", "/api/v1/user/list", http.MethodGet, true) + assertPermission(t, enforcer, "user1", "/api/v2/user/list", http.MethodGet, false) + + if ok, deleteErr := enforcer.DeletePermissionsForUser("user1"); deleteErr != nil || !ok { + t.Fatalf("删除用户策略失败: ok=%v err=%v", ok, deleteErr) + } + assertPermission(t, enforcer, "user1", "/api/v1/user/list", http.MethodGet, false) } -// CheckPremission description -func CheckPremission(t *testing.T, user string, path string, method string) { - ok, err := Enforcer.Enforce(user, path, method) +func assertPermission(t *testing.T, enforcer *casbinv2.Enforcer, user, path, method string, expected bool) { + t.Helper() + actual, err := enforcer.Enforce(user, path, method) if err != nil { - t.Error(err) + t.Fatalf("检查权限失败: %v", err) } - t.Logf("check \tuser[%s] \tpremission[%s] \tpath[%s] \tallow[%v]", user, method, path, ok) -} - -// Add description -func AddPremission(t *testing.T, user string, path string, method string) { - ok, err := Enforcer.AddPolicy(user, path, method) - if err != nil { - t.Error(err) + if actual != expected { + t.Fatalf("权限结果不符 user=%s path=%s method=%s expected=%v actual=%v", user, path, method, expected, actual) } - t.Logf("add \tuser[%s] \tpremission[%s] \tpath[%s] \tresult[%v]", user, method, path, ok) } diff --git a/server/internal/library/network/tcp/client.go b/server/internal/library/network/tcp/client.go index ad0a1f9..b3f6d4d 100644 --- a/server/internal/library/network/tcp/client.go +++ b/server/internal/library/network/tcp/client.go @@ -281,6 +281,8 @@ func (client *Client) handleRoutineTask(ctx context.Context, task func()) { // Conn 获取当前连接 func (client *Client) Conn() *Conn { + client.mutex.Lock() + defer client.mutex.Unlock() return client.conn } diff --git a/server/internal/library/network/tcp/rpc.go b/server/internal/library/network/tcp/rpc.go index 2ebd5bf..5c1e3c8 100644 --- a/server/internal/library/network/tcp/rpc.go +++ b/server/internal/library/network/tcp/rpc.go @@ -43,7 +43,6 @@ func (r *RPC) Request(ctx context.Context, msgId string, send func()) (res inter defer func() { isClose.Set(true) - close(resCh) r.popCallback(msgId) }() @@ -57,8 +56,13 @@ func (r *RPC) Request(ctx context.Context, msgId string, send func()) (res inter r.task(ctx, send) + timer := time.NewTimer(time.Second * RPCTimeout) + defer timer.Stop() select { - case <-time.After(time.Second * RPCTimeout): + case <-ctx.Done(): + err = gerror.Wrap(ctx.Err(), "RPC request canceled") + return + case <-timer.C: err = gerror.New("RPC response timeout") return case got := <-resCh: diff --git a/server/internal/library/network/tcp/tcp_example_test.go b/server/internal/library/network/tcp/tcp_example_test.go index b23ef20..8d5e0ce 100644 --- a/server/internal/library/network/tcp/tcp_example_test.go +++ b/server/internal/library/network/tcp/tcp_example_test.go @@ -1,21 +1,14 @@ -// Package tcp_test -// @Link https://github.com/bufanyun/hotgo -// @Copyright Copyright (c) 2023 HotGo CLI -// @Author Ms <133814250@qq.com> -// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE package tcp_test import ( "context" "fmt" - "github.com/gogf/gf/v2/os/gctx" - "github.com/gogf/gf/v2/test/gtest" - "hotgo/internal/library/network/tcp" + "net" "testing" "time" -) -var T *testing.T // 声明一个全局的 *testing.T 变量 + "hotgo/internal/library/network/tcp" +) type TestMsgReq struct { Name string `json:"name"` @@ -33,101 +26,95 @@ type TestRPCMsgRes struct { tcp.ServerRes } -func onTestMsg(ctx context.Context, req *TestMsgReq) { - fmt.Printf("服务器收到消息 ==> onTestMsg:%+v\n", req) - conn := tcp.ConnFromCtx(ctx) - gtest.C(T, func(t *gtest.T) { - t.AssertNE(conn, nil) - }) - - res := new(TestMsgRes) - res.Message = fmt.Sprintf("你的名字:%v", req.Name) - conn.Send(ctx, res) -} - -func onResponseTestMsg(ctx context.Context, req *TestMsgRes) { - fmt.Printf("客户端收到响应消息 ==> TestMsgRes:%+v\n", req) - err := req.GetError() - gtest.C(T, func(t *gtest.T) { - t.AssertNil(err) - }) -} - -func onTestRPCMsg(ctx context.Context, req *TestRPCMsgReq) (res *TestRPCMsgRes, err error) { - fmt.Printf("服务器收到消息 ==> onTestRPCMsg:%+v\n", req) - res = new(TestRPCMsgRes) - res.Message = fmt.Sprintf("你的名字:%v", req.Name) - return -} - -func startTCPServer() { - serv := tcp.NewServer(&tcp.ServerConfig{ - Name: "hotgo", - Addr: ":8002", - }) - - // 注册路由 - serv.RegisterRouter( - onTestMsg, - ) - - // 注册RPC路由 - serv.RegisterRPCRouter( - onTestRPCMsg, - ) - - // 服务监听 - err := serv.Listen() - gtest.C(T, func(t *gtest.T) { - t.AssertNil(err) - }) -} - -// 一个基本的消息收发 func TestSendMsg(t *testing.T) { - T = t - go startTCPServer() - - ctx := gctx.New() - client := tcp.NewClient(&tcp.ClientConfig{ - Addr: "127.0.0.1:8002", + address := freeTCPAddress(t) + messageResponse := make(chan string, 1) + server := tcp.NewServer(&tcp.ServerConfig{Name: "hotgo-test", Addr: address}) + server.RegisterRouter(func(ctx context.Context, req *TestMsgReq) { + res := &TestMsgRes{} + res.SetMessage(fmt.Sprintf("你的名字:%s", req.Name)) + if err := tcp.ConnFromCtx(ctx).Send(ctx, res); err != nil { + messageResponse <- "send-error:" + err.Error() + } }) - - // 注册路由 - client.RegisterRouter( - onResponseTestMsg, - ) - + server.RegisterRPCRouter(func(ctx context.Context, req *TestRPCMsgReq) (*TestRPCMsgRes, error) { + res := &TestRPCMsgRes{} + res.SetMessage(fmt.Sprintf("你的名字:%s", req.Name)) + return res, nil + }) + serverErrors := make(chan error, 1) go func() { - err := client.Start() - gtest.C(T, func(t *gtest.T) { - t.AssertNil(err) - }) + serverErrors <- server.Listen() }() + defer server.Close() - // 确保服务都启动完成 - time.Sleep(time.Second * 1) - - // 拿到客户端的连接 - conn := client.Conn() - gtest.C(T, func(t *gtest.T) { - t.AssertNE(conn, nil) + client := tcp.NewClient(&tcp.ClientConfig{ + Addr: address, + Timeout: time.Second, + ConnectInterval: 10 * time.Millisecond, + MaxConnectCount: 100, }) - - // 向服务器发送tcp消息,不会阻塞程序执行 - err := conn.Send(ctx, &TestMsgReq{Name: "Tom"}) - gtest.C(T, func(t *gtest.T) { - t.AssertNil(err) + client.RegisterRouter(func(ctx context.Context, res *TestMsgRes) { + messageResponse <- res.Message }) + if err := client.Start(); err != nil { + t.Fatalf("启动TCP客户端失败: %v", err) + } + defer client.Stop() - // 向服务器发送rpc消息,会等待服务器响应结果,直到拿到结果或响应超时才会继续 - var res TestRPCMsgRes - if err = conn.RequestScan(ctx, &TestRPCMsgReq{Name: "Tony"}, &res); err != nil { - gtest.C(T, func(t *gtest.T) { - t.AssertNil(err) - }) + conn := waitForConnection(t, client, serverErrors) + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + if err := conn.Send(ctx, &TestMsgReq{Name: "Tom"}); err != nil { + t.Fatalf("发送TCP消息失败: %v", err) + } + select { + case message := <-messageResponse: + if message != "你的名字:Tom" { + t.Fatalf("TCP响应不符: %s", message) + } + case <-ctx.Done(): + t.Fatal("等待TCP响应超时") } - fmt.Printf("客户端收到RPC消息响应 ==> TestRPCMsgRes:%+v\n", res) - time.Sleep(time.Second * 1) + var rpcResponse TestRPCMsgRes + if err := conn.RequestScan(ctx, &TestRPCMsgReq{Name: "Tony"}, &rpcResponse); err != nil { + t.Fatalf("发送RPC消息失败: %v", err) + } + if rpcResponse.Message != "你的名字:Tony" { + t.Fatalf("RPC响应不符: %s", rpcResponse.Message) + } +} + +func freeTCPAddress(t *testing.T) string { + t.Helper() + listener, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("申请测试端口失败: %v", err) + } + address := listener.Addr().String() + if err = listener.Close(); err != nil { + t.Fatalf("释放测试端口失败: %v", err) + } + return address +} + +func waitForConnection(t *testing.T, client *tcp.Client, serverErrors <-chan error) *tcp.Conn { + t.Helper() + deadline := time.NewTimer(2 * time.Second) + defer deadline.Stop() + ticker := time.NewTicker(10 * time.Millisecond) + defer ticker.Stop() + for { + select { + case err := <-serverErrors: + t.Fatalf("TCP服务启动失败: %v", err) + case <-deadline.C: + t.Fatal("等待TCP连接超时") + case <-ticker.C: + if conn := client.Conn(); conn != nil { + return conn + } + } + } } diff --git a/server/internal/library/storager/upload_local.go b/server/internal/library/storager/upload_local.go index 3f7fa93..a5032d9 100644 --- a/server/internal/library/storager/upload_local.go +++ b/server/internal/library/storager/upload_local.go @@ -13,6 +13,7 @@ import ( "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" + "io" "os" "path/filepath" "sort" @@ -137,20 +138,53 @@ func (d *LocalDrive) UploadPart(ctx context.Context, in *UploadPartParams) (res // MergePartFile 合并分片文件 func MergePartFile(srcPath, dstPath string) (err error) { - dir, err := os.ReadDir(srcPath) + entries, err := os.ReadDir(srcPath) if err != nil { return err } - sort.Slice(dir, func(i, j int) bool { - fiIndex, _ := strconv.Atoi(dir[i].Name()) - fjIndex, _ := strconv.Atoi(dir[j].Name()) - return fiIndex < fjIndex + type filePart struct { + index int + path string + } + parts := make([]filePart, 0, len(entries)) + for _, entry := range entries { + if entry.IsDir() { + continue + } + index, parseErr := strconv.Atoi(entry.Name()) + if parseErr != nil || index <= 0 { + return gerror.Newf("无效的分片文件名:%s", entry.Name()) + } + parts = append(parts, filePart{index: index, path: filepath.Join(srcPath, entry.Name())}) + } + if len(parts) == 0 { + return gerror.New("没有可合并的分片文件") + } + sort.Slice(parts, func(i, j int) bool { + return parts[i].index < parts[j].index }) - for _, file := range dir { - filePath := filepath.Join(srcPath, file.Name()) - if err = gfile.PutBytesAppend(dstPath, gfile.GetBytes(filePath)); err != nil { - return err + if err = os.MkdirAll(filepath.Dir(dstPath), 0o755); err != nil { + return gerror.Wrap(err, "创建目标目录失败") + } + dstFile, err := os.OpenFile(dstPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644) + if err != nil { + return gerror.Wrap(err, "创建合并文件失败") + } + defer dstFile.Close() + + for _, part := range parts { + srcFile, openErr := os.Open(part.path) + if openErr != nil { + return gerror.Wrapf(openErr, "打开分片%d失败", part.index) + } + _, copyErr := io.Copy(dstFile, srcFile) + closeErr := srcFile.Close() + if copyErr != nil { + return gerror.Wrapf(copyErr, "合并分片%d失败", part.index) + } + if closeErr != nil { + return gerror.Wrapf(closeErr, "关闭分片%d失败", part.index) } } - return + return dstFile.Sync() } diff --git a/server/internal/library/storager/upload_local_test.go b/server/internal/library/storager/upload_local_test.go index 8dea7bf..1891b37 100644 --- a/server/internal/library/storager/upload_local_test.go +++ b/server/internal/library/storager/upload_local_test.go @@ -1,61 +1,52 @@ package storager import ( - "crypto/md5" - "errors" - "fmt" - "io" + "bytes" "os" + "path/filepath" "testing" ) func TestMergePartFile(t *testing.T) { - srcFile, _ := os.Open("1.zip") - defer srcFile.Close() - fileInfo, err := srcFile.Stat() - if err != nil { - t.Error(err) + tempDir := t.TempDir() + partDir := filepath.Join(tempDir, "parts") + if err := os.MkdirAll(partDir, 0o755); err != nil { + t.Fatal(err) } - hash := md5.New() - _, err = io.Copy(hash, srcFile) - sum := hash.Sum(nil) - fileHash := fmt.Sprintf("%x", sum) - var singleSize = int64(1024 * 1024 * 100) - chunks := int(fileInfo.Size() / singleSize) - if fileInfo.Size()%singleSize != 0 { - chunks += 1 + parts := map[string][]byte{ + "1": []byte("first-"), + "2": []byte("second-"), + "10": []byte("tenth"), } - srcFile.Seek(0, io.SeekStart) - for j := 0; j < chunks; j++ { - partSize := singleSize - if j == chunks-1 { - partSize = fileInfo.Size() - int64(j)*singleSize + for name, content := range parts { + if err := os.WriteFile(filepath.Join(partDir, name), content, 0o644); err != nil { + t.Fatal(err) } - partData := make([]byte, partSize) - _, err = io.ReadFull(srcFile, partData) - pf, _ := os.Create(fmt.Sprintf("tmp/%d", j+1)) - _, err = pf.Write(partData) - if err != nil { - t.Error(err) - return - } - pf.Close() } - err = MergePartFile("tmp/", "2.zip") + destination := filepath.Join(tempDir, "merged.bin") + if err := os.WriteFile(destination, []byte("stale-data"), 0o644); err != nil { + t.Fatal(err) + } + if err := MergePartFile(partDir, destination); err != nil { + t.Fatalf("合并分片失败: %v", err) + } + + actual, err := os.ReadFile(destination) if err != nil { - t.Error(err) - return + t.Fatal(err) } + expected := []byte("first-second-tenth") + if !bytes.Equal(actual, expected) { + t.Fatalf("合并内容不符 expected=%q actual=%q", expected, actual) + } +} - f2, _ := os.Open("2.zip") - hash2 := md5.New() - _, err = io.Copy(hash2, f2) - sum2 := hash.Sum(nil) - fileHash2 := fmt.Sprintf("%x", sum2) - if fileHash != fileHash2 { - t.Error(errors.New("hash mismatch")) +func TestMergePartFileRejectsEmptyDirectory(t *testing.T) { + partDir := t.TempDir() + err := MergePartFile(partDir, filepath.Join(t.TempDir(), "merged.bin")) + if err == nil { + t.Fatal("空分片目录应返回错误") } - } diff --git a/server/internal/logic/sys/im_admin_query_client.go b/server/internal/logic/sys/im_admin_query_client.go index efeeb8f..3a460d2 100644 --- a/server/internal/logic/sys/im_admin_query_client.go +++ b/server/internal/logic/sys/im_admin_query_client.go @@ -150,7 +150,7 @@ func normalizeImAdminValue(target string, value any) any { parts = append(parts, text) } return strings.Join(parts, ", ") - case "profileJson", "trustedJson", "accessJson": + case "profileJson", "trustedJson", "accessJson", "head", "content", "metadata", "atUsers": return normalizeImAdminJSONString(value) default: return value diff --git a/server/internal/logic/sys/im_dashboard.go b/server/internal/logic/sys/im_dashboard.go new file mode 100644 index 0000000..b9b4e9b --- /dev/null +++ b/server/internal/logic/sys/im_dashboard.go @@ -0,0 +1,38 @@ +package sys + +import ( + "context" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" + "net/url" +) + +type sSysImDashboard struct{} + +func NewSysImDashboard() *sSysImDashboard { return &sSysImDashboard{} } + +func init() { service.RegisterSysImDashboard(NewSysImDashboard()) } + +func (s *sSysImDashboard) Overview(ctx context.Context, in *sysin.ImDashboardOverviewInp) (*sysin.ImDashboardOverviewModel, error) { + tenant, err := resolveImAdminTenant(ctx, in.TenantId) + if err != nil { + return nil, err + } + return imAdminQueryOne[sysin.ImDashboardOverviewModel](ctx, tenant, + "/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/dashboard/overview", nil) +} + +func (s *sSysImDashboard) Trends(ctx context.Context, in *sysin.ImDashboardTrendsInp) ([]*sysin.ImDashboardTrendModel, error) { + if err := in.Filter(ctx); err != nil { + return nil, err + } + tenant, err := resolveImAdminTenant(ctx, in.TenantId) + if err != nil { + return nil, err + } + values := addPageQuery(url.Values{}, 1, in.Days) + values.Set("days", intToString(in.Days)) + list, _, err := imAdminQueryList[sysin.ImDashboardTrendModel](ctx, tenant, + "/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/dashboard/trends", values, nil) + return list, err +} diff --git a/server/internal/logic/sys/im_login_audit.go b/server/internal/logic/sys/im_login_audit.go new file mode 100644 index 0000000..e82854a --- /dev/null +++ b/server/internal/logic/sys/im_login_audit.go @@ -0,0 +1,155 @@ +package sys + +import ( + "context" + "fmt" + "hotgo/internal/consts" + "hotgo/internal/library/contexts" + "hotgo/internal/library/imkafka" + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" + "hotgo/utility/convert" + "hotgo/utility/excel" + "net/url" + "strconv" + + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/os/gctx" +) + +type sSysImUserLoginHistory struct{} +type sSysImLoginFailureLog struct{} + +func NewSysImUserLoginHistory() *sSysImUserLoginHistory { return &sSysImUserLoginHistory{} } +func NewSysImLoginFailureLog() *sSysImLoginFailureLog { return &sSysImLoginFailureLog{} } + +func init() { + service.RegisterSysImUserLoginHistory(NewSysImUserLoginHistory()) + service.RegisterSysImLoginFailureLog(NewSysImLoginFailureLog()) +} + +func (s *sSysImUserLoginHistory) List(ctx context.Context, in *sysin.ImUserLoginHistoryListInp) ([]*sysin.ImUserLoginHistoryModel, int, error) { + if err := in.Filter(ctx); err != nil { + return nil, 0, err + } + tenant, err := resolveImAdminTenant(ctx, in.TenantId) + if err != nil { + return nil, 0, err + } + values := addPageQuery(url.Values{}, in.Page, in.PerPage) + setQuery(values, "user_id", in.UserId) + setQuery(values, "account", in.Account) + setQuery(values, "login_type", in.LoginType) + setQuery(values, "event_type", in.EventType) + setQuery(values, "platform", in.Platform) + setQuery(values, "ip", in.Ip) + addTimeRangeQuery(values, "login_at", in.LoginAt) + return imAdminQueryList[sysin.ImUserLoginHistoryModel](ctx, tenant, + "/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/user-login-logs", values, nil) +} + +func (s *sSysImUserLoginHistory) Export(ctx context.Context, in *sysin.ImUserLoginHistoryListInp) error { + list, total, err := s.List(ctx, in) + if err != nil { + return err + } + exports := make([]sysin.ImLoginAuditExportModel, 0, len(list)) + for _, item := range list { + exports = append(exports, sysin.ImLoginAuditExportModel{Id: item.Id, UserId: item.UserId, AccountMask: item.AccountMask, EventType: item.EventType, Platform: item.Platform, Ip: item.Ip, Region: item.Region, RiskLevel: item.RiskLevel, OccurredAt: item.LoginAt}) + } + return exportLoginAudit(ctx, exports, total, in.Page, in.PerPage, "用户登录历史") +} + +func (s *sSysImLoginFailureLog) List(ctx context.Context, in *sysin.ImLoginFailureLogListInp) ([]*sysin.ImLoginFailureLogModel, int, error) { + if err := in.Filter(ctx); err != nil { + return nil, 0, err + } + tenant, err := resolveImAdminTenant(ctx, in.TenantId) + if err != nil { + return nil, 0, err + } + values := addPageQuery(url.Values{}, in.Page, in.PerPage) + setQuery(values, "user_id", in.UserId) + setQuery(values, "account", in.Account) + setQuery(values, "failure_type", in.FailureType) + setQuery(values, "platform", in.Platform) + setQuery(values, "ip", in.Ip) + addTimeRangeQuery(values, "attempt_at", in.AttemptAt) + return imAdminQueryList[sysin.ImLoginFailureLogModel](ctx, tenant, + "/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/login-failure-logs", values, nil) +} + +func (s *sSysImLoginFailureLog) View(ctx context.Context, in *sysin.ImLoginFailureViewInp) (*sysin.ImLoginFailureLogModel, error) { + if err := in.Filter(ctx); err != nil { + return nil, err + } + tenant, err := resolveImAdminTenant(ctx, in.TenantId) + if err != nil { + return nil, err + } + return imAdminQueryOne[sysin.ImLoginFailureLogModel](ctx, tenant, + "/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/login-failure-logs/"+strconv.FormatInt(in.Id, 10), nil) +} + +func (s *sSysImLoginFailureLog) Export(ctx context.Context, in *sysin.ImLoginFailureLogListInp) error { + list, total, err := s.List(ctx, in) + if err != nil { + return err + } + exports := make([]sysin.ImLoginAuditExportModel, 0, len(list)) + for _, item := range list { + exports = append(exports, sysin.ImLoginAuditExportModel{Id: item.Id, UserId: item.UserId, AccountMask: item.AccountMask, EventType: item.FailureType, Platform: item.Platform, Ip: item.Ip, Region: item.Region, RiskLevel: item.RiskLevel, Reason: item.Reason, OccurredAt: item.AttemptAt}) + } + return exportLoginAudit(ctx, exports, total, in.Page, in.PerPage, "登录失败日志") +} + +func exportLoginAudit(ctx context.Context, exports []sysin.ImLoginAuditExportModel, total int, page int, perPage int, label string) error { + tags, err := convert.GetEntityDescTags(sysin.ImLoginAuditExportModel{}) + if err != nil { + return err + } + fileName := "导出" + label + "-" + gctx.CtxId(ctx) + sheetName := fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", total, form.CalPageCount(total, perPage), page, len(exports)) + return excel.ExportByStructs(ctx, tags, exports, fileName, sheetName) +} + +func (s *sSysImLoginFailureLog) AddBlacklist(ctx context.Context, in *sysin.ImLoginFailureAddBlacklistInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + remark := in.Remark + if remark == "" { + remark = "由登录失败日志加入" + } + return service.SysImSecurityPolicy().IPRuleEdit(ctx, &sysin.ImSecurityIPRuleEditInp{ + TenantId: in.TenantId, RuleType: "blacklist", IpCidr: in.Ip, Action: "deny", + SceneJson: gjson.New([]string{"login"}), RiskLevel: "high", Status: consts.StatusEnabled, Remark: remark, + }) +} + +func (s *sSysImLoginFailureLog) BanUser(ctx context.Context, in *sysin.ImLoginFailureBanUserInp) (*sysin.ImUserCommandModel, error) { + if err := in.Filter(ctx); err != nil { + return nil, err + } + tenant, err := resolveImAdminTenant(ctx, in.TenantId) + if err != nil { + return nil, err + } + user := contexts.GetUser(ctx) + actorName := "" + if user != nil { + actorName = user.RealName + } + command, err := imkafka.PublishAdminCommand(ctx, imkafka.AdminCommandInput{ + TenantID: tenant.Id, TenantCode: tenant.Code, EventType: consts.ImAdminCommandUserBan, + BizType: "user", BizID: strconv.FormatInt(in.UserId, 10), + Actor: &imkafka.Actor{Type: "admin", ID: strconv.FormatInt(contexts.GetUserId(ctx), 10), DisplayName: actorName}, + Payload: map[string]any{"user_id": strconv.FormatInt(in.UserId, 10), "target_user_id": strconv.FormatInt(in.UserId, 10), "reason": in.Reason}, + CreatedBy: contexts.GetUserId(ctx), + }) + if err != nil { + return nil, err + } + return &sysin.ImUserCommandModel{CommandID: command.CommandID, EventID: command.EventID, Status: command.Status, TenantID: command.TenantID, TenantCode: command.TenantCode, EventType: command.EventType, IdempotencyKey: command.IdempotencyKey}, nil +} diff --git a/server/internal/logic/sys/im_message_admin.go b/server/internal/logic/sys/im_message_admin.go new file mode 100644 index 0000000..34f6c9c --- /dev/null +++ b/server/internal/logic/sys/im_message_admin.go @@ -0,0 +1,173 @@ +package sys + +import ( + "context" + "fmt" + "hotgo/internal/consts" + "hotgo/internal/library/contexts" + "hotgo/internal/library/imkafka" + "hotgo/internal/model/input/form" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" + "hotgo/utility/convert" + "hotgo/utility/excel" + "net/url" + "strconv" + + "github.com/gogf/gf/v2/os/gctx" + "github.com/gogf/gf/v2/util/gconv" +) + +type sSysImPrivateMessage struct{} +type sSysImGroupMessage struct{} + +func NewSysImPrivateMessage() *sSysImPrivateMessage { return &sSysImPrivateMessage{} } +func NewSysImGroupMessage() *sSysImGroupMessage { return &sSysImGroupMessage{} } + +func init() { + service.RegisterSysImPrivateMessage(NewSysImPrivateMessage()) + service.RegisterSysImGroupMessage(NewSysImGroupMessage()) +} + +func (s *sSysImPrivateMessage) List(ctx context.Context, in *sysin.ImPrivateMessageListInp) ([]*sysin.ImMessageListModel, int, error) { + if err := in.Filter(ctx); err != nil { + return nil, 0, err + } + values := addPageQuery(url.Values{}, in.Page, in.PerPage) + setQuery(values, "topic", in.Topic) + setQuery(values, "from_user_id", in.FromUserId) + setQuery(values, "to_user_id", in.ToUserId) + setQuery(values, "content_type", in.ContentType) + setQuery(values, "status", in.Status) + setQuery(values, "keyword", in.Keyword) + addTimeRangeQuery(values, "created_at", in.CreatedAt) + return queryImMessages(ctx, in.TenantId, "private-messages", values) +} + +func (s *sSysImGroupMessage) List(ctx context.Context, in *sysin.ImGroupMessageListInp) ([]*sysin.ImMessageListModel, int, error) { + if err := in.Filter(ctx); err != nil { + return nil, 0, err + } + values := addPageQuery(url.Values{}, in.Page, in.PerPage) + setQuery(values, "topic", in.Topic) + setQuery(values, "sender_user_id", in.SenderUserId) + setQuery(values, "content_type", in.ContentType) + setQuery(values, "status", in.Status) + setQuery(values, "keyword", in.Keyword) + addTimeRangeQuery(values, "created_at", in.CreatedAt) + return queryImMessages(ctx, in.TenantId, "group-messages", values) +} + +func queryImMessages(ctx context.Context, tenantId int64, resource string, values url.Values) ([]*sysin.ImMessageListModel, int, error) { + tenant, err := resolveImAdminTenant(ctx, tenantId) + if err != nil { + return nil, 0, err + } + return imAdminQueryList[sysin.ImMessageListModel](ctx, tenant, + "/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/"+resource, values, + map[string]string{"sender_user_id": "fromUserId", "sent_at": "createdAt", "message_type": "contentType", "content_summary": "contentExcerpt"}) +} + +func (s *sSysImPrivateMessage) View(ctx context.Context, in *sysin.ImMessageViewInp) (*sysin.ImMessageViewModel, error) { + return viewImMessage(ctx, in) +} + +func (s *sSysImGroupMessage) View(ctx context.Context, in *sysin.ImMessageViewInp) (*sysin.ImMessageViewModel, error) { + return viewImMessage(ctx, in) +} + +func viewImMessage(ctx context.Context, in *sysin.ImMessageViewInp) (*sysin.ImMessageViewModel, error) { + if err := in.Filter(ctx); err != nil { + return nil, err + } + tenant, err := resolveImAdminTenant(ctx, in.TenantId) + if err != nil { + return nil, err + } + path := "/internal/admin-query/tenants/" + url.PathEscape(tenant.Code) + "/messages/" + url.PathEscape(in.Topic) + "/" + strconv.FormatInt(in.SeqId, 10) + return imAdminQueryOne[sysin.ImMessageViewModel](ctx, tenant, path, + map[string]string{"sender_user_id": "fromUserId", "sent_at": "createdAt", "message_type": "contentType"}) +} + +func (s *sSysImPrivateMessage) Hide(ctx context.Context, in *sysin.ImMessageActionInp) (*sysin.ImMessageCommandModel, error) { + return publishMessageCommand(ctx, in, "private", consts.ImAdminCommandMessageHide) +} + +func (s *sSysImPrivateMessage) Delete(ctx context.Context, in *sysin.ImMessageActionInp) (*sysin.ImMessageCommandModel, error) { + return publishMessageCommand(ctx, in, "private", consts.ImAdminCommandMessageDelete) +} + +func (s *sSysImGroupMessage) Hide(ctx context.Context, in *sysin.ImMessageActionInp) (*sysin.ImMessageCommandModel, error) { + return publishMessageCommand(ctx, in, "group", consts.ImAdminCommandMessageHide) +} + +func (s *sSysImGroupMessage) Delete(ctx context.Context, in *sysin.ImMessageActionInp) (*sysin.ImMessageCommandModel, error) { + return publishMessageCommand(ctx, in, "group", consts.ImAdminCommandMessageDelete) +} + +func publishMessageCommand(ctx context.Context, in *sysin.ImMessageActionInp, conversationType string, eventType string) (*sysin.ImMessageCommandModel, error) { + if err := in.Filter(ctx); err != nil { + return nil, err + } + tenant, err := resolveImAdminTenant(ctx, in.TenantId) + if err != nil { + return nil, err + } + user := contexts.GetUser(ctx) + actorName := "" + if user != nil { + actorName = user.RealName + } + bizId := in.Topic + ":" + strconv.FormatInt(in.SeqId, 10) + command, err := imkafka.PublishAdminCommand(ctx, imkafka.AdminCommandInput{ + TenantID: tenant.Id, TenantCode: tenant.Code, EventType: eventType, BizType: "message", BizID: bizId, + Actor: &imkafka.Actor{Type: "admin", ID: strconv.FormatInt(contexts.GetUserId(ctx), 10), DisplayName: actorName}, + Payload: map[string]any{"conversation_type": conversationType, "topic": in.Topic, "seq_id": in.SeqId, "reason": in.Reason}, + CreatedBy: contexts.GetUserId(ctx), + }) + result := "success" + if err != nil { + result = "failed" + } + _ = writeImAdminAudit(ctx, tenant.Id, eventType, "message", in.SeqId, result, map[string]any{"conversation_type": conversationType, "topic": in.Topic, "reason": in.Reason}) + if err != nil { + return nil, err + } + return &sysin.ImMessageCommandModel{CommandId: command.CommandID, EventId: command.EventID, Status: command.Status}, nil +} + +func (s *sSysImPrivateMessage) Export(ctx context.Context, in *sysin.ImPrivateMessageListInp) error { + list, total, err := s.List(ctx, in) + if err != nil { + return err + } + return exportImMessages(ctx, list, total, in.Page, in.PerPage, "单聊消息") +} + +func (s *sSysImGroupMessage) Export(ctx context.Context, in *sysin.ImGroupMessageListInp) error { + list, total, err := s.List(ctx, in) + if err != nil { + return err + } + return exportImMessages(ctx, list, total, in.Page, in.PerPage, "群聊消息") +} + +func exportImMessages(ctx context.Context, list []*sysin.ImMessageListModel, total int, page int, perPage int, label string) error { + tags, err := convert.GetEntityDescTags(sysin.ImMessageExportModel{}) + if err != nil { + return err + } + var exports []sysin.ImMessageExportModel + if err = gconv.Scan(list, &exports); err != nil { + return err + } + fileName := "导出" + label + "-" + gctx.CtxId(ctx) + sheetName := fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", total, form.CalPageCount(total, perPage), page, len(list)) + return excel.ExportByStructs(ctx, tags, exports, fileName, sheetName) +} + +func setQuery(values url.Values, key string, value string) { + if value != "" { + values.Set(key, value) + } +} diff --git a/server/internal/logic/sys/im_policy_support.go b/server/internal/logic/sys/im_policy_support.go new file mode 100644 index 0000000..ab6c025 --- /dev/null +++ b/server/internal/logic/sys/im_policy_support.go @@ -0,0 +1,60 @@ +package sys + +import ( + "context" + "fmt" + "strconv" + + "hotgo/internal/dao" + "hotgo/internal/library/contexts" + "hotgo/internal/library/imkafka" + "hotgo/internal/library/imtenant" + "hotgo/internal/model/entity" + "hotgo/internal/service" + + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/errors/gerror" +) + +func resolveImPolicyTenant(ctx context.Context, selectedTenantID int64) (tenantID int64, tenantCode string, err error) { + operatorID := contexts.GetUserId(ctx) + if service.AdminMember().VerifySuperId(ctx, operatorID) && selectedTenantID == 0 { + return 0, "*", nil + } + scope, err := resolveImAdminScope(ctx, selectedTenantID) + if err != nil { + return 0, "", err + } + var tenant *entity.ImTenant + if err = imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx). + Where(dao.ImTenant.Columns().Id, scope.TenantId).Scan(&tenant); err != nil { + return 0, "", gerror.Wrap(err, "获取IM租户失败") + } + if tenant == nil { + return 0, "", gerror.New("IM租户不存在") + } + return tenant.Id, tenant.Code, nil +} + +func policyJSON(value *gjson.Json, fallback string) string { + if value == nil || value.String() == "" || value.String() == "null" { + return fallback + } + return value.String() +} + +func publishImPolicyEvent(ctx context.Context, tenantID int64, tenantCode, eventType, group string, version uint) error { + return imkafka.PublishConfigEvent(ctx, imkafka.ConfigEventInput{ + TenantID: tenantID, + TenantCode: tenantCode, + EventType: eventType, + Group: group, + Keys: []string{"version", "payload"}, + BizID: fmt.Sprintf("%s:%d:%d", group, tenantID, version), + Actor: &imkafka.Actor{ + Type: "admin", + ID: strconv.FormatInt(contexts.GetUserId(ctx), 10), + }, + CreatedBy: contexts.GetUserId(ctx), + }) +} diff --git a/server/internal/logic/sys/im_security_policy.go b/server/internal/logic/sys/im_security_policy.go new file mode 100644 index 0000000..eec3393 --- /dev/null +++ b/server/internal/logic/sys/im_security_policy.go @@ -0,0 +1,331 @@ +package sys + +import ( + "context" + "net" + + "hotgo/internal/consts" + "hotgo/internal/dao" + "hotgo/internal/library/contexts" + "hotgo/internal/library/imtenant" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +type sSysImSecurityPolicy struct{} + +func NewSysImSecurityPolicy() *sSysImSecurityPolicy { return &sSysImSecurityPolicy{} } +func init() { service.RegisterSysImSecurityPolicy(NewSysImSecurityPolicy()) } + +func securityPolicyFields(alias string) []any { + c := dao.ImSecurityPolicy.Columns() + p := alias + if p != "" { + p += "." + } + return []any{p + c.Id, p + c.TenantId, p + c.PolicyVersion, p + c.PolicyName, p + c.PublishStatus, "CAST(" + p + c.PasswordPolicy + " AS CHAR) password_policy", "CAST(" + p + c.LoginRateLimit + " AS CHAR) login_rate_limit", "CAST(" + p + c.SensitiveWordPolicy + " AS CHAR) sensitive_word_policy", "CAST(" + p + c.FileReviewPolicy + " AS CHAR) file_review_policy", "CAST(" + p + c.RealnamePolicy + " AS CHAR) realname_policy", "CAST(" + p + c.RiskChallengePolicy + " AS CHAR) risk_challenge_policy", p + c.GlobalFriendEnabled, "CAST(" + p + c.FriendDisabledPolicy + " AS CHAR) friend_disabled_policy", p + c.MessageCurfewEnabled, p + c.Remark, p + c.PublishedAt, p + c.PublishedBy, p + c.CreatedAt, p + c.UpdatedAt} +} + +func (s *sSysImSecurityPolicy) List(ctx context.Context, in *sysin.ImSecurityPolicyListInp) (list []*sysin.ImSecurityPolicyModel, total int, err error) { + if err = in.Filter(ctx); err != nil { + return + } + tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return nil, 0, err + } + c := dao.ImSecurityPolicy.Columns() + model := imtenant.RegistryDB().Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Fields(securityPolicyFields("")...).Where(c.TenantId, tenantID).WhereNull(c.DeletedAt) + if in.PublishStatus != "" { + model = model.Where(c.PublishStatus, in.PublishStatus) + } + err = model.Page(in.Page, in.PerPage).OrderDesc(c.PolicyVersion).ScanAndCount(&list, &total, false) + return +} + +func (s *sSysImSecurityPolicy) View(ctx context.Context, in *sysin.ImSecurityPolicyViewInp) (res *sysin.ImSecurityPolicyModel, err error) { + if err = in.Filter(ctx); err != nil { + return + } + c := dao.ImSecurityPolicy.Columns() + baseModel := imtenant.RegistryDB().Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Fields(securityPolicyFields("")...).WhereNull(c.DeletedAt) + if in.Id > 0 { + err = baseModel.Where(c.Id, in.Id).Scan(&res) + } else { + tenantID, _, resolveErr := resolveImPolicyTenant(ctx, in.TenantId) + if resolveErr != nil { + return nil, resolveErr + } + err = baseModel.Where(c.TenantId, tenantID). + Where(c.PublishStatus, consts.ImSecurityPublishPublished). + OrderDesc(c.PolicyVersion).Scan(&res) + if err == nil && res == nil { + err = baseModel.Where(c.TenantId, tenantID).OrderDesc(c.PolicyVersion).Scan(&res) + } + } + if err != nil { + return nil, gerror.Wrap(err, "获取安全策略失败") + } + if res == nil { + return nil, gerror.New("安全策略不存在") + } + if _, _, err = resolveImPolicyTenant(ctx, res.TenantId); err != nil { + return nil, err + } + res.CurfewRules, err = s.curfewRules(ctx, res.Id) + return +} + +func (s *sSysImSecurityPolicy) curfewRules(ctx context.Context, policyID int64) (list []*sysin.ImMessageCurfewRuleModel, err error) { + c := dao.ImMessageCurfewRules.Columns() + err = imtenant.RegistryDB().Model(dao.ImMessageCurfewRules.Table()).Safe().Ctx(ctx).Fields(c.Id, c.RuleCode, c.RuleName, c.DateType, "CAST("+c.CustomDates+" AS CHAR) custom_dates", "CAST("+c.Weekdays+" AS CHAR) weekdays", c.Timezone, "TIME_FORMAT("+c.StartTime+",'%H:%i') start_time", "TIME_FORMAT("+c.EndTime+",'%H:%i') end_time", c.Scope, "CAST("+c.WhitelistUserIds+" AS CHAR) whitelist_user_ids", "CAST("+c.WhitelistGroupIds+" AS CHAR) whitelist_group_ids", c.Message, c.Status, c.Sort).Where(c.PolicyId, policyID).WhereNull(c.DeletedAt).OrderAsc(c.Sort).OrderAsc(c.Id).Scan(&list) + return +} + +func (s *sSysImSecurityPolicy) Save(ctx context.Context, in *sysin.ImSecurityPolicySaveInp) (id int64, err error) { + if err = in.Filter(ctx); err != nil { + return + } + tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return 0, err + } + db := imtenant.RegistryDB() + c := dao.ImSecurityPolicy.Columns() + rc := dao.ImMessageCurfewRules.Columns() + operator := contexts.GetUserId(ctx) + now := gtime.Now() + err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { + version := uint(0) + if in.Id > 0 { + current, readErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One() + if readErr != nil { + return readErr + } + if current.IsEmpty() || current[c.TenantId].Int64() != tenantID { + return gerror.New("安全策略不存在") + } + if current[c.PublishStatus].String() != consts.ImSecurityPublishDraft { + return gerror.New("只有草稿状态的安全策略可以编辑") + } + version = current[c.PolicyVersion].Uint() + id = in.Id + } else { + maxValue, maxErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.TenantId, tenantID).Max(c.PolicyVersion) + if maxErr != nil { + return maxErr + } + version = uint(maxValue) + 1 + } + data := g.Map{c.TenantId: tenantID, c.PolicyVersion: version, c.PolicyName: in.PolicyName, c.PublishStatus: consts.ImSecurityPublishDraft, c.PasswordPolicy: policyJSON(in.PasswordPolicy, "{}"), c.LoginRateLimit: policyJSON(in.LoginRateLimit, "{}"), c.SensitiveWordPolicy: policyJSON(in.SensitiveWordPolicy, "{}"), c.FileReviewPolicy: policyJSON(in.FileReviewPolicy, "{}"), c.RealnamePolicy: policyJSON(in.RealnamePolicy, "{}"), c.RiskChallengePolicy: policyJSON(in.RiskChallengePolicy, "{}"), c.GlobalFriendEnabled: in.GlobalFriendEnabled, c.FriendDisabledPolicy: policyJSON(in.FriendDisabledPolicy, `{"hide_profile":true,"block_qrcode":true,"block_group_member_entry":true,"blocked_entries":["search","profile_card","group_member","qrcode","invite_auto_add","recommendation"],"message":"当前时段暂不允许添加好友"}`), c.MessageCurfewEnabled: in.MessageCurfewEnabled, c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: operator} + if in.Id > 0 { + if _, updateErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update(); updateErr != nil { + return updateErr + } + } else { + data[c.CreatedAt] = now + data[c.CreatedBy] = operator + result, insertErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Data(data).Insert() + if insertErr != nil { + return insertErr + } + id, insertErr = result.LastInsertId() + if insertErr != nil { + return insertErr + } + } + if _, deleteErr := tx.Model(dao.ImMessageCurfewRules.Table()).Safe().Ctx(ctx).Where(rc.PolicyId, id).Delete(); deleteErr != nil { + return deleteErr + } + for _, rule := range in.CurfewRules { + _, insertErr := tx.Model(dao.ImMessageCurfewRules.Table()).Safe().Ctx(ctx).Data(g.Map{rc.TenantId: tenantID, rc.PolicyId: id, rc.RuleCode: rule.RuleCode, rc.RuleName: rule.RuleName, rc.DateType: rule.DateType, rc.CustomDates: policyJSON(rule.CustomDates, "[]"), rc.Weekdays: policyJSON(rule.Weekdays, "[]"), rc.Timezone: rule.Timezone, rc.StartTime: rule.StartTime, rc.EndTime: rule.EndTime, rc.Scope: rule.Scope, rc.WhitelistUserIds: policyJSON(rule.WhitelistUserIds, "[]"), rc.WhitelistGroupIds: policyJSON(rule.WhitelistGroupIds, "[]"), rc.Message: rule.Message, rc.Status: rule.Status, rc.Sort: rule.Sort, rc.CreatedAt: now, rc.CreatedBy: operator, rc.UpdatedAt: now, rc.UpdatedBy: operator}).Insert() + if insertErr != nil { + return insertErr + } + } + return nil + }) + if err != nil { + return 0, gerror.Wrap(err, "保存安全策略草稿失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_security_policy_save", "im_security_policy", id, "success", g.Map{"global_friend_enabled": in.GlobalFriendEnabled, "message_curfew_enabled": in.MessageCurfewEnabled}) + return id, nil +} + +func (s *sSysImSecurityPolicy) Publish(ctx context.Context, in *sysin.ImSecurityPolicyPublishInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + db := imtenant.RegistryDB() + c := dao.ImSecurityPolicy.Columns() + var row gdb.Record + var err error + if row, err = db.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil { + return err + } + if row.IsEmpty() { + return gerror.New("安全策略不存在") + } + if row[c.PublishStatus].String() != consts.ImSecurityPublishDraft { + return gerror.New("只有草稿状态可以发布") + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64()) + if err != nil { + return err + } + operator := contexts.GetUserId(ctx) + now := gtime.Now() + err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { + if _, updateErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.TenantId, tenantID).Where(c.PublishStatus, consts.ImSecurityPublishPublished).WhereNot(c.Id, in.Id).WhereNull(c.DeletedAt).Data(g.Map{c.PublishStatus: consts.ImSecurityPublishArchived, c.UpdatedAt: now, c.UpdatedBy: operator}).Update(); updateErr != nil { + return updateErr + } + if _, updateErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(g.Map{c.PublishStatus: consts.ImSecurityPublishPublished, c.PublishedAt: now, c.PublishedBy: operator, c.UpdatedAt: now, c.UpdatedBy: operator}).Update(); updateErr != nil { + return updateErr + } + if tenantID > 0 { + tc := dao.ImTenantConfig.Columns() + if _, updateErr := tx.Model(dao.ImTenantConfig.Table()).Safe().Ctx(ctx).Where(tc.TenantId, tenantID).Data(g.Map{tc.SecurityPolicyVersion: row[c.PolicyVersion].Uint(), tc.GlobalFriendEnabled: row[c.GlobalFriendEnabled].Int(), tc.MessageCurfewEnabled: row[c.MessageCurfewEnabled].Int(), tc.UpdatedAt: now, tc.UpdatedBy: operator}).Update(); updateErr != nil { + return updateErr + } + } + return nil + }) + if err != nil { + return gerror.Wrap(err, "发布安全策略失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_security_policy_publish", "im_security_policy", in.Id, "success", g.Map{"reason": in.Reason, "version": row[c.PolicyVersion].Uint()}) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "security.policy.updated", "security_policy", row[c.PolicyVersion].Uint()) +} + +func (s *sSysImSecurityPolicy) RestoreDefault(ctx context.Context, in *sysin.ImSecurityPolicyRestoreInp) (int64, error) { + if err := in.Filter(ctx); err != nil { + return 0, err + } + tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return 0, err + } + c := dao.ImSecurityPolicy.Columns() + var source *sysin.ImSecurityPolicyModel + err = imtenant.RegistryDB().Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx). + Fields(securityPolicyFields("")...).Where(c.TenantId, 0). + Where(c.PublishStatus, consts.ImSecurityPublishPublished).WhereNull(c.DeletedAt). + OrderDesc(c.PolicyVersion).Scan(&source) + if err != nil { + return 0, gerror.Wrap(err, "读取全局默认安全策略失败") + } + if source == nil { + return 0, gerror.New("全局默认安全策略不存在") + } + source.CurfewRules, err = s.curfewRules(ctx, source.Id) + if err != nil { + return 0, err + } + rules := make([]*sysin.ImMessageCurfewRuleInp, 0, len(source.CurfewRules)) + for _, rule := range source.CurfewRules { + rules = append(rules, &sysin.ImMessageCurfewRuleInp{RuleCode: rule.RuleCode, RuleName: rule.RuleName, DateType: rule.DateType, CustomDates: gjson.New(rule.CustomDates), Weekdays: gjson.New(rule.Weekdays), Timezone: rule.Timezone, StartTime: rule.StartTime, EndTime: rule.EndTime, Scope: rule.Scope, WhitelistUserIds: gjson.New(rule.WhitelistUserIds), WhitelistGroupIds: gjson.New(rule.WhitelistGroupIds), Message: rule.Message, Status: rule.Status, Sort: rule.Sort}) + } + id, err := s.Save(ctx, &sysin.ImSecurityPolicySaveInp{TenantId: tenantID, PolicyName: "恢复默认安全策略", PasswordPolicy: gjson.New(source.PasswordPolicy), LoginRateLimit: gjson.New(source.LoginRateLimit), SensitiveWordPolicy: gjson.New(source.SensitiveWordPolicy), FileReviewPolicy: gjson.New(source.FileReviewPolicy), RealnamePolicy: gjson.New(source.RealnamePolicy), RiskChallengePolicy: gjson.New(source.RiskChallengePolicy), GlobalFriendEnabled: source.GlobalFriendEnabled, FriendDisabledPolicy: gjson.New(source.FriendDisabledPolicy), MessageCurfewEnabled: source.MessageCurfewEnabled, Remark: in.Reason, CurfewRules: rules}) + if err == nil { + _ = writeImAdminAudit(ctx, tenantID, "im_security_policy_restore_default", "im_security_policy", id, "success", g.Map{"reason": in.Reason}) + } + return id, err +} + +func (s *sSysImSecurityPolicy) IPRuleList(ctx context.Context, in *sysin.ImSecurityIPRuleListInp) (list []*sysin.ImSecurityIPRuleModel, total int, err error) { + if err = in.Filter(ctx); err != nil { + return + } + tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return nil, 0, err + } + c := dao.ImSecurityIpRules.Columns() + model := imtenant.RegistryDB().Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Fields(c.Id, c.TenantId, c.RuleType, c.IpCidr, c.Action, "CAST("+c.SceneJson+" AS CHAR) scene_json", c.RiskLevel, c.Status, c.ExpiresAt, c.Remark, c.CreatedAt, c.UpdatedAt).Where(c.TenantId, tenantID).WhereNull(c.DeletedAt) + if in.RuleType != "" { + model = model.Where(c.RuleType, in.RuleType) + } + if in.IpCidr != "" { + model = model.WhereLike(c.IpCidr, "%"+in.IpCidr+"%") + } + if in.Status != 0 { + model = model.Where(c.Status, in.Status) + } + err = model.Page(in.Page, in.PerPage).OrderDesc(c.Id).ScanAndCount(&list, &total, false) + return +} + +func (s *sSysImSecurityPolicy) IPRuleEdit(ctx context.Context, in *sysin.ImSecurityIPRuleEditInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + if net.ParseIP(in.IpCidr) == nil { + if _, _, err := net.ParseCIDR(in.IpCidr); err != nil { + return gerror.New("IP或CIDR格式不合法") + } + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return err + } + c := dao.ImSecurityIpRules.Columns() + db := imtenant.RegistryDB() + now := gtime.Now() + data := g.Map{c.TenantId: tenantID, c.RuleType: in.RuleType, c.IpCidr: in.IpCidr, c.Action: in.Action, c.SceneJson: policyJSON(in.SceneJson, "[]"), c.RiskLevel: in.RiskLevel, c.Status: in.Status, c.ExpiresAt: in.ExpiresAt, c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: contexts.GetUserId(ctx)} + targetID := in.Id + if in.Id > 0 { + var row gdb.Record + if row, err = db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil { + return err + } + if row.IsEmpty() || row[c.TenantId].Int64() != tenantID { + return gerror.New("IP规则不存在") + } + _, err = db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update() + } else { + data[c.CreatedAt] = now + data[c.CreatedBy] = contexts.GetUserId(ctx) + result, insertErr := db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Data(data).Insert() + err = insertErr + if err == nil { + targetID, err = result.LastInsertId() + } + } + if err != nil { + return gerror.Wrap(err, "保存IP规则失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_security_ip_rule_edit", "im_security_ip_rule", targetID, "success", g.Map{"ip_cidr": in.IpCidr, "rule_type": in.RuleType}) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "security.policy.updated", "security_policy", uint(targetID)) +} + +func (s *sSysImSecurityPolicy) IPRuleDelete(ctx context.Context, in *sysin.ImSecurityIPRuleDeleteInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + c := dao.ImSecurityIpRules.Columns() + db := imtenant.RegistryDB() + var row gdb.Record + var err error + if row, err = db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil { + return err + } + if row.IsEmpty() { + return gerror.New("IP规则不存在") + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64()) + if err != nil { + return err + } + _, err = db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(g.Map{c.Status: consts.StatusDisable, c.DeletedAt: gtime.Now(), c.DeletedBy: contexts.GetUserId(ctx), c.UpdatedAt: gtime.Now(), c.UpdatedBy: contexts.GetUserId(ctx)}).Update() + if err != nil { + return gerror.Wrap(err, "删除IP规则失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_security_ip_rule_delete", "im_security_ip_rule", in.Id, "success", nil) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "security.policy.updated", "security_policy", uint(in.Id)) +} diff --git a/server/internal/logic/sys/im_sensitive_word.go b/server/internal/logic/sys/im_sensitive_word.go new file mode 100644 index 0000000..12780f0 --- /dev/null +++ b/server/internal/logic/sys/im_sensitive_word.go @@ -0,0 +1,266 @@ +package sys + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "strings" + + "hotgo/internal/consts" + "hotgo/internal/dao" + "hotgo/internal/library/contexts" + "hotgo/internal/library/imtenant" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +type sSysImSensitiveWord struct{} + +func NewSysImSensitiveWord() *sSysImSensitiveWord { return &sSysImSensitiveWord{} } +func init() { service.RegisterSysImSensitiveWord(NewSysImSensitiveWord()) } + +func normalizedSensitiveWord(value string) (string, string) { + normalized := strings.ToLower(strings.TrimSpace(value)) + sum := sha256.Sum256([]byte(normalized)) + return normalized, hex.EncodeToString(sum[:]) +} + +func (s *sSysImSensitiveWord) List(ctx context.Context, in *sysin.ImSensitiveWordListInp) (list []*sysin.ImSensitiveWordListModel, total int, err error) { + if err = in.Filter(ctx); err != nil { + return + } + tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return nil, 0, err + } + c := dao.ImSensitiveWords.Columns() + gc := dao.ImSensitiveWordGroups.Columns() + model := imtenant.RegistryDB().Model(dao.ImSensitiveWords.Table()+" w").Safe().Ctx(ctx).LeftJoin(dao.ImSensitiveWordGroups.Table()+" g", "g."+gc.Id+"=w."+c.GroupId).Fields("w."+c.Id, "w."+c.TenantId, "w."+c.GroupId, "g."+gc.GroupName, "w."+c.Word, "w."+c.MatchType, "CAST(w."+c.SceneJson+" AS CHAR) scene_json", "w."+c.Action, "w."+c.Replacement, "w."+c.RiskLevel, "w."+c.Priority, "w."+c.Status, "w."+c.Remark, "w."+c.CreatedAt, "w."+c.UpdatedAt).Where("w."+c.TenantId, tenantID).WhereNull("w." + c.DeletedAt) + if in.GroupId > 0 { + model = model.Where("w."+c.GroupId, in.GroupId) + } + if in.Word != "" { + model = model.WhereLike("w."+c.Word, "%"+in.Word+"%") + } + if in.MatchType != "" { + model = model.Where("w."+c.MatchType, in.MatchType) + } + if in.Action != "" { + model = model.Where("w."+c.Action, in.Action) + } + if in.RiskLevel != "" { + model = model.Where("w."+c.RiskLevel, in.RiskLevel) + } + if in.Status != 0 { + model = model.Where("w."+c.Status, in.Status) + } + err = model.Page(in.Page, in.PerPage).OrderDesc("w."+c.Priority).OrderDesc("w."+c.Id).ScanAndCount(&list, &total, false) + if err != nil { + err = gerror.Wrap(err, "获取敏感词列表失败") + } + return +} + +func (s *sSysImSensitiveWord) Edit(ctx context.Context, in *sysin.ImSensitiveWordEditInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return err + } + if err = validateSensitiveWordGroup(ctx, tenantID, in.GroupId); err != nil { + return err + } + _, hash := normalizedSensitiveWord(in.Word) + c := dao.ImSensitiveWords.Columns() + db := imtenant.RegistryDB() + now := gtime.Now() + data := g.Map{c.TenantId: tenantID, c.GroupId: in.GroupId, c.Word: in.Word, c.WordHash: hash, c.MatchType: in.MatchType, c.SceneJson: policyJSON(in.SceneJson, "[]"), c.Action: in.Action, c.Replacement: in.Replacement, c.RiskLevel: in.RiskLevel, c.Priority: in.Priority, c.Status: in.Status, c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: contexts.GetUserId(ctx)} + targetID := in.Id + if in.Id > 0 { + var row gdb.Record + if row, err = db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil { + return err + } + if row.IsEmpty() || row[c.TenantId].Int64() != tenantID { + return gerror.New("敏感词不存在") + } + _, err = db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update() + } else { + data[c.CreatedAt] = now + data[c.CreatedBy] = contexts.GetUserId(ctx) + result, insertErr := db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Data(data).Insert() + err = insertErr + if err == nil { + targetID, err = result.LastInsertId() + } + } + if err != nil { + return gerror.Wrap(err, "保存敏感词失败,请检查是否重复") + } + _ = writeImAdminAudit(ctx, tenantID, "im_sensitive_word_edit", "im_sensitive_word", targetID, "success", g.Map{"group_id": in.GroupId, "action": in.Action}) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "sensitive_words.updated", "sensitive_words", uint(targetID)) +} + +func (s *sSysImSensitiveWord) Delete(ctx context.Context, in *sysin.ImSensitiveWordDeleteInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + return s.updateWordState(ctx, in.Id, consts.StatusDisable, true, "im_sensitive_word_delete") +} +func (s *sSysImSensitiveWord) Status(ctx context.Context, in *sysin.ImSensitiveWordStatusInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + return s.updateWordState(ctx, in.Id, in.Status, false, "im_sensitive_word_status") +} +func (s *sSysImSensitiveWord) updateWordState(ctx context.Context, id int64, status int, deleted bool, action string) error { + c := dao.ImSensitiveWords.Columns() + db := imtenant.RegistryDB() + var row gdb.Record + var err error + if row, err = db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.Id, id).WhereNull(c.DeletedAt).One(); err != nil { + return err + } + if row.IsEmpty() { + return gerror.New("敏感词不存在") + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64()) + if err != nil { + return err + } + data := g.Map{c.Status: status, c.UpdatedAt: gtime.Now(), c.UpdatedBy: contexts.GetUserId(ctx)} + if deleted { + data[c.DeletedAt] = gtime.Now() + data[c.DeletedBy] = contexts.GetUserId(ctx) + } + if _, err = db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.Id, id).Data(data).Update(); err != nil { + return gerror.Wrap(err, "更新敏感词失败") + } + _ = writeImAdminAudit(ctx, tenantID, action, "im_sensitive_word", id, "success", g.Map{"status": status}) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "sensitive_words.updated", "sensitive_words", uint(id)) +} + +func (s *sSysImSensitiveWord) BatchImport(ctx context.Context, in *sysin.ImSensitiveWordBatchImportInp) (res *sysin.ImSensitiveWordBatchImportModel, err error) { + if err = in.Filter(ctx); err != nil { + return + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return nil, err + } + if err = validateSensitiveWordGroup(ctx, tenantID, in.GroupId); err != nil { + return nil, err + } + res = &sysin.ImSensitiveWordBatchImportModel{} + db := imtenant.RegistryDB() + c := dao.ImSensitiveWords.Columns() + seen := map[string]struct{}{} + err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { + for _, raw := range in.Words { + word, hash := normalizedSensitiveWord(raw) + if word == "" { + res.Skipped++ + continue + } + if _, ok := seen[hash]; ok { + res.Skipped++ + continue + } + seen[hash] = struct{}{} + count, countErr := tx.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.TenantId, tenantID).Where(c.GroupId, in.GroupId).Where(c.WordHash, hash).WhereNull(c.DeletedAt).Count() + if countErr != nil { + return countErr + } + if count > 0 { + res.Skipped++ + continue + } + now := gtime.Now() + _, insertErr := tx.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Data(g.Map{c.TenantId: tenantID, c.GroupId: in.GroupId, c.Word: strings.TrimSpace(raw), c.WordHash: hash, c.MatchType: in.MatchType, c.SceneJson: policyJSON(in.SceneJson, "[]"), c.Action: in.Action, c.Replacement: in.Replacement, c.RiskLevel: in.RiskLevel, c.Status: consts.StatusEnabled, c.CreatedAt: now, c.CreatedBy: contexts.GetUserId(ctx), c.UpdatedAt: now, c.UpdatedBy: contexts.GetUserId(ctx)}).Insert() + if insertErr != nil { + return insertErr + } + res.Inserted++ + } + return nil + }) + if err != nil { + return nil, gerror.Wrap(err, "批量导入敏感词失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_sensitive_word_batch_import", "im_sensitive_word", 0, "success", g.Map{"inserted": res.Inserted, "skipped": res.Skipped}) + err = publishImPolicyEvent(ctx, tenantID, tenantCode, "sensitive_words.updated", "sensitive_words", uint(res.Inserted)) + return +} + +func (s *sSysImSensitiveWord) GroupList(ctx context.Context, in *sysin.ImSensitiveWordGroupListInp) (list []*sysin.ImSensitiveWordGroupModel, err error) { + if err = in.Filter(ctx); err != nil { + return + } + tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return nil, err + } + c := dao.ImSensitiveWordGroups.Columns() + err = imtenant.RegistryDB().Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Fields(c.Id, c.TenantId, c.GroupCode, c.GroupName, c.Priority, c.Status, c.Remark, c.CreatedAt).Where(c.TenantId, tenantID).WhereNull(c.DeletedAt).OrderDesc(c.Priority).OrderAsc(c.GroupName).Scan(&list) + return +} + +func (s *sSysImSensitiveWord) GroupEdit(ctx context.Context, in *sysin.ImSensitiveWordGroupEditInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return err + } + c := dao.ImSensitiveWordGroups.Columns() + db := imtenant.RegistryDB() + now := gtime.Now() + data := g.Map{c.TenantId: tenantID, c.GroupCode: in.GroupCode, c.GroupName: in.GroupName, c.Priority: in.Priority, c.Status: in.Status, c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: contexts.GetUserId(ctx)} + targetID := in.Id + if in.Id > 0 { + var row gdb.Record + if row, err = db.Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil { + return err + } + if row.IsEmpty() || row[c.TenantId].Int64() != tenantID { + return gerror.New("敏感词分组不存在") + } + if row[c.GroupCode].String() != in.GroupCode { + return gerror.New("分组编码创建后不能修改") + } + _, err = db.Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update() + } else { + data[c.CreatedAt] = now + data[c.CreatedBy] = contexts.GetUserId(ctx) + result, insertErr := db.Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Data(data).Insert() + err = insertErr + if err == nil { + targetID, err = result.LastInsertId() + } + } + if err != nil { + return gerror.Wrap(err, "保存敏感词分组失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_sensitive_word_group_edit", "im_sensitive_word_group", targetID, "success", nil) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "sensitive_words.updated", "sensitive_words", uint(targetID)) +} + +func validateSensitiveWordGroup(ctx context.Context, tenantID, groupID int64) error { + c := dao.ImSensitiveWordGroups.Columns() + count, err := imtenant.RegistryDB().Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Where(c.Id, groupID).Where(c.TenantId, tenantID).WhereNull(c.DeletedAt).Count() + if err != nil { + return gerror.Wrap(err, "检查敏感词分组失败") + } + if count == 0 { + return gerror.New("敏感词分组不存在") + } + return nil +} diff --git a/server/internal/logic/sys/im_user_policy_group.go b/server/internal/logic/sys/im_user_policy_group.go new file mode 100644 index 0000000..e1daf71 --- /dev/null +++ b/server/internal/logic/sys/im_user_policy_group.go @@ -0,0 +1,290 @@ +package sys + +import ( + "context" + + "hotgo/internal/consts" + "hotgo/internal/dao" + "hotgo/internal/library/contexts" + "hotgo/internal/library/imtenant" + "hotgo/internal/model/input/sysin" + "hotgo/internal/service" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +type sSysImUserPolicyGroup struct{} + +func NewSysImUserPolicyGroup() *sSysImUserPolicyGroup { return &sSysImUserPolicyGroup{} } +func init() { service.RegisterSysImUserPolicyGroup(NewSysImUserPolicyGroup()) } + +func (s *sSysImUserPolicyGroup) List(ctx context.Context, in *sysin.ImUserPolicyGroupListInp) (list []*sysin.ImUserPolicyGroupListModel, total int, err error) { + if err = in.Filter(ctx); err != nil { + return + } + tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return nil, 0, err + } + c := dao.ImUserPolicyGroups.Columns() + mc := dao.ImUserPolicyGroupMembers.Columns() + model := imtenant.RegistryDB().Model(dao.ImUserPolicyGroups.Table()+" p").Safe().Ctx(ctx). + Fields("p."+c.Id, "p."+c.TenantId, "p."+c.GroupCode, "p."+c.GroupName, "p."+c.Priority, "p."+c.Status, + "CAST(p."+c.PolicyJson+" AS CHAR) policy_json", "CAST(p."+c.IpWhitelist+" AS CHAR) ip_whitelist", + "CAST(p."+c.IpBlacklist+" AS CHAR) ip_blacklist", "p."+c.Version, "p."+c.Remark, "p."+c.CreatedAt, "p."+c.UpdatedAt, + "(SELECT COUNT(*) FROM "+dao.ImUserPolicyGroupMembers.Table()+" m WHERE m."+mc.GroupId+"=p."+c.Id+" AND m."+mc.Status+"=1 AND m."+mc.DeletedAt+" IS NULL) member_count"). + Where("p."+c.TenantId, tenantID).WhereNull("p." + c.DeletedAt) + if in.Keyword != "" { + keyword := "%" + in.Keyword + "%" + model = model.Where("(p."+c.GroupCode+" LIKE ? OR p."+c.GroupName+" LIKE ?)", keyword, keyword) + } + if in.Status != 0 { + model = model.Where("p."+c.Status, in.Status) + } + err = model.Page(in.Page, in.PerPage).OrderDesc("p."+c.Priority).OrderDesc("p."+c.Id).ScanAndCount(&list, &total, false) + if err != nil { + err = gerror.Wrap(err, "获取用户策略分组失败") + } + return +} + +func (s *sSysImUserPolicyGroup) View(ctx context.Context, in *sysin.ImUserPolicyGroupViewInp) (res *sysin.ImUserPolicyGroupViewModel, err error) { + if err = in.Filter(ctx); err != nil { + return + } + c := dao.ImUserPolicyGroups.Columns() + var row *sysin.ImUserPolicyGroupListModel + err = imtenant.RegistryDB().Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx). + Fields(c.Id, c.TenantId, c.GroupCode, c.GroupName, c.Priority, c.Status, "CAST("+c.PolicyJson+" AS CHAR) policy_json", "CAST("+c.IpWhitelist+" AS CHAR) ip_whitelist", "CAST("+c.IpBlacklist+" AS CHAR) ip_blacklist", c.Version, c.Remark, c.CreatedAt, c.UpdatedAt). + Where(c.Id, in.Id).WhereNull(c.DeletedAt).Scan(&row) + if err != nil { + return nil, gerror.Wrap(err, "获取用户策略分组详情失败") + } + if row == nil { + return nil, gerror.New("用户策略分组不存在") + } + if _, _, err = resolveImPolicyTenant(ctx, row.TenantId); err != nil { + return nil, err + } + return &sysin.ImUserPolicyGroupViewModel{ImUserPolicyGroupListModel: *row}, nil +} + +func (s *sSysImUserPolicyGroup) Edit(ctx context.Context, in *sysin.ImUserPolicyGroupEditInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId) + if err != nil { + return err + } + c := dao.ImUserPolicyGroups.Columns() + db := imtenant.RegistryDB() + now := gtime.Now() + operator := contexts.GetUserId(ctx) + data := g.Map{c.GroupName: in.GroupName, c.Priority: in.Priority, c.Status: in.Status, c.PolicyJson: policyJSON(in.PolicyJson, "{}"), c.IpWhitelist: policyJSON(in.IpWhitelist, "[]"), c.IpBlacklist: policyJSON(in.IpBlacklist, "[]"), c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: operator} + var targetID int64 + if in.Id > 0 { + var current gdb.Record + if current, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil { + return gerror.Wrap(err, "读取用户策略分组失败") + } + if current.IsEmpty() || current[c.TenantId].Int64() != tenantID { + return gerror.New("用户策略分组不存在") + } + if current[c.GroupCode].String() != in.GroupCode { + return gerror.New("分组编码创建后不能修改") + } + data[c.Version] = gdb.Raw("version+1") + if _, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update(); err != nil { + return gerror.Wrap(err, "更新用户策略分组失败") + } + targetID = in.Id + } else { + data[c.TenantId] = tenantID + data[c.GroupCode] = in.GroupCode + data[c.Version] = 1 + data[c.CreatedAt] = now + data[c.CreatedBy] = operator + result, insertErr := db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Data(data).Insert() + if insertErr != nil { + return gerror.Wrap(insertErr, "新增用户策略分组失败") + } + targetID, err = result.LastInsertId() + if err != nil { + return gerror.Wrap(err, "获取用户策略分组ID失败") + } + } + _ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_edit", "im_user_policy_group", targetID, "success", g.Map{"group_code": in.GroupCode}) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.updated", "user_policy_groups", uint(targetID)) +} + +func (s *sSysImUserPolicyGroup) Delete(ctx context.Context, in *sysin.ImUserPolicyGroupDeleteInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + c := dao.ImUserPolicyGroups.Columns() + mc := dao.ImUserPolicyGroupMembers.Columns() + db := imtenant.RegistryDB() + var row gdb.Record + var err error + if row, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil { + return gerror.Wrap(err, "读取用户策略分组失败") + } + if row.IsEmpty() { + return gerror.New("用户策略分组不存在") + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64()) + if err != nil { + return err + } + count, err := db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.GroupId, in.Id).Where(mc.Status, consts.StatusEnabled).WhereNull(mc.DeletedAt).Count() + if err != nil { + return err + } + if count > 0 { + return gerror.New("请先移除分组内成员") + } + now := gtime.Now() + _, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(g.Map{c.DeletedAt: now, c.DeletedBy: contexts.GetUserId(ctx), c.Status: consts.StatusDisable}).Update() + if err != nil { + return gerror.Wrap(err, "删除用户策略分组失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_delete", "im_user_policy_group", in.Id, "success", nil) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.deleted", "user_policy_groups", uint(in.Id)) +} + +func (s *sSysImUserPolicyGroup) Status(ctx context.Context, in *sysin.ImUserPolicyGroupStatusInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + c := dao.ImUserPolicyGroups.Columns() + db := imtenant.RegistryDB() + var row gdb.Record + var err error + if row, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil { + return err + } + if row.IsEmpty() { + return gerror.New("用户策略分组不存在") + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64()) + if err != nil { + return err + } + _, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(g.Map{c.Status: in.Status, c.Version: gdb.Raw("version+1"), c.UpdatedBy: contexts.GetUserId(ctx), c.UpdatedAt: gtime.Now()}).Update() + if err != nil { + return gerror.Wrap(err, "更新用户策略分组状态失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_status", "im_user_policy_group", in.Id, "success", g.Map{"status": in.Status}) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.updated", "user_policy_groups", uint(in.Id)) +} + +func (s *sSysImUserPolicyGroup) MemberList(ctx context.Context, in *sysin.ImUserPolicyGroupMemberListInp) (list []*sysin.ImUserPolicyGroupMemberModel, total int, err error) { + if err = in.Filter(ctx); err != nil { + return + } + gc := dao.ImUserPolicyGroups.Columns() + mc := dao.ImUserPolicyGroupMembers.Columns() + var group gdb.Record + if group, err = imtenant.RegistryDB().Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(gc.Id, in.GroupId).WhereNull(gc.DeletedAt).One(); err != nil { + return nil, 0, err + } + if group.IsEmpty() { + return nil, 0, gerror.New("用户策略分组不存在") + } + if _, _, err = resolveImPolicyTenant(ctx, group[gc.TenantId].Int64()); err != nil { + return nil, 0, err + } + model := imtenant.RegistryDB().Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Fields(mc.Id, mc.GroupId, mc.TenantId, mc.UserId, mc.Status, mc.ValidFrom, mc.ValidUntil, mc.Remark, mc.CreatedAt).Where(mc.GroupId, in.GroupId).WhereNull(mc.DeletedAt) + if in.UserId > 0 { + model = model.Where(mc.UserId, in.UserId) + } + err = model.Page(in.Page, in.PerPage).OrderDesc(mc.Id).ScanAndCount(&list, &total, false) + return +} + +func (s *sSysImUserPolicyGroup) MemberAdd(ctx context.Context, in *sysin.ImUserPolicyGroupMemberAddInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + gc := dao.ImUserPolicyGroups.Columns() + mc := dao.ImUserPolicyGroupMembers.Columns() + db := imtenant.RegistryDB() + var group gdb.Record + var err error + if group, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(gc.Id, in.GroupId).WhereNull(gc.DeletedAt).One(); err != nil { + return err + } + if group.IsEmpty() { + return gerror.New("用户策略分组不存在") + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, group[gc.TenantId].Int64()) + if err != nil { + return err + } + if tenantID == 0 { + return gerror.New("全局默认分组不能添加成员,请先选择具体租户") + } + tenantDB, _, err := imtenant.DB(ctx, tenantID) + if err != nil { + return err + } + userCount, err := tenantDB.Model("im_users").Safe().Ctx(ctx).Where("id", in.UserId).Count() + if err != nil { + return gerror.Wrap(err, "检查租户用户失败") + } + if userCount == 0 { + return gerror.New("用户不存在或不属于当前租户") + } + var current gdb.Record + current, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.GroupId, in.GroupId).Where(mc.UserId, in.UserId).One() + if err != nil { + return err + } + now := gtime.Now() + data := g.Map{mc.TenantId: tenantID, mc.Status: consts.StatusEnabled, mc.ValidFrom: in.ValidFrom, mc.ValidUntil: in.ValidUntil, mc.Remark: in.Remark, mc.DeletedAt: nil, mc.DeletedBy: nil, mc.UpdatedAt: now, mc.UpdatedBy: contexts.GetUserId(ctx)} + if current.IsEmpty() { + data[mc.GroupId] = in.GroupId + data[mc.UserId] = in.UserId + data[mc.CreatedAt] = now + data[mc.CreatedBy] = contexts.GetUserId(ctx) + _, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Data(data).Insert() + } else { + _, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.Id, current[mc.Id]).Data(data).Update() + } + if err != nil { + return gerror.Wrap(err, "添加策略分组成员失败") + } + _ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_member_add", "im_user_policy_group", in.GroupId, "success", g.Map{"user_id": in.UserId}) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.updated", "user_policy_groups", uint(in.GroupId)) +} + +func (s *sSysImUserPolicyGroup) MemberRemove(ctx context.Context, in *sysin.ImUserPolicyGroupMemberRemoveInp) error { + if err := in.Filter(ctx); err != nil { + return err + } + mc := dao.ImUserPolicyGroupMembers.Columns() + db := imtenant.RegistryDB() + var row gdb.Record + var err error + if row, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.Id, in.Id).WhereNull(mc.DeletedAt).One(); err != nil { + return err + } + if row.IsEmpty() { + return gerror.New("策略分组成员不存在") + } + tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[mc.TenantId].Int64()) + if err != nil { + return err + } + _, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.Id, in.Id).Data(g.Map{mc.Status: consts.StatusDisable, mc.DeletedAt: gtime.Now(), mc.DeletedBy: contexts.GetUserId(ctx), mc.UpdatedAt: gtime.Now(), mc.UpdatedBy: contexts.GetUserId(ctx)}).Update() + if err != nil { + return gerror.Wrap(err, "移除策略分组成员失败") + } + groupID := row[mc.GroupId].Int64() + _ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_member_remove", "im_user_policy_group", groupID, "success", g.Map{"user_id": row[mc.UserId].Int64()}) + return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.updated", "user_policy_groups", uint(groupID)) +} diff --git a/server/internal/model/do/im_message_curfew_rules.go b/server/internal/model/do/im_message_curfew_rules.go new file mode 100644 index 0000000..1467e68 --- /dev/null +++ b/server/internal/model/do/im_message_curfew_rules.go @@ -0,0 +1,39 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImMessageCurfewRules is the golang structure of table im_message_curfew_rules for DAO operations like Where/Data. +type ImMessageCurfewRules struct { + g.Meta `orm:"table:im_message_curfew_rules, do:true"` + Id any // + TenantId any // + PolicyId any // + RuleCode any // + RuleName any // + DateType any // daily, weekday, weekend, custom + CustomDates *gjson.Json // YYYY-MM-DD values for custom date type + Weekdays *gjson.Json // ISO weekdays 1 through 7 + Timezone any // + StartTime *gtime.Time // + EndTime *gtime.Time // Less than start_time means crossing midnight + Scope any // private_message or group_message + WhitelistUserIds *gjson.Json // + WhitelistGroupIds *gjson.Json // + Message any // + Status any // 1 enabled, 2 disabled + Sort any // + CreatedAt *gtime.Time // + CreatedBy any // + UpdatedAt *gtime.Time // + UpdatedBy any // + DeletedAt *gtime.Time // + DeletedBy any // +} diff --git a/server/internal/model/do/im_security_ip_rules.go b/server/internal/model/do/im_security_ip_rules.go new file mode 100644 index 0000000..99d8c0c --- /dev/null +++ b/server/internal/model/do/im_security_ip_rules.go @@ -0,0 +1,32 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImSecurityIpRules is the golang structure of table im_security_ip_rules for DAO operations like Where/Data. +type ImSecurityIpRules struct { + g.Meta `orm:"table:im_security_ip_rules, do:true"` + Id any // + TenantId any // + RuleType any // whitelist or blacklist + IpCidr any // IPv4, IPv6 or CIDR + Action any // allow, challenge, block, audit_only + SceneJson *gjson.Json // login, register, message, upload and other scenes + RiskLevel any // + Status any // 1 enabled, 2 disabled + ExpiresAt *gtime.Time // + Remark any // + CreatedAt *gtime.Time // + CreatedBy any // + UpdatedAt *gtime.Time // + UpdatedBy any // + DeletedAt *gtime.Time // + DeletedBy any // +} diff --git a/server/internal/model/do/im_security_policy.go b/server/internal/model/do/im_security_policy.go new file mode 100644 index 0000000..e5a9ad2 --- /dev/null +++ b/server/internal/model/do/im_security_policy.go @@ -0,0 +1,39 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImSecurityPolicy is the golang structure of table im_security_policy for DAO operations like Where/Data. +type ImSecurityPolicy struct { + g.Meta `orm:"table:im_security_policy, do:true"` + Id any // + TenantId any // 0 means global fallback policy + PolicyVersion any // + PolicyName any // + PublishStatus any // + PasswordPolicy *gjson.Json // + LoginRateLimit *gjson.Json // + SensitiveWordPolicy *gjson.Json // + FileReviewPolicy *gjson.Json // + RealnamePolicy *gjson.Json // + RiskChallengePolicy *gjson.Json // + GlobalFriendEnabled any // Backend master switch for every add-friend entry + FriendDisabledPolicy *gjson.Json // Profile masking, QR and group-member restrictions + MessageCurfewEnabled any // Backend master switch for message curfew + Remark any // + PublishedAt *gtime.Time // + PublishedBy any // + CreatedAt *gtime.Time // + CreatedBy any // + UpdatedAt *gtime.Time // + UpdatedBy any // + DeletedAt *gtime.Time // + DeletedBy any // +} diff --git a/server/internal/model/do/im_sensitive_word_groups.go b/server/internal/model/do/im_sensitive_word_groups.go new file mode 100644 index 0000000..3a4f270 --- /dev/null +++ b/server/internal/model/do/im_sensitive_word_groups.go @@ -0,0 +1,28 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImSensitiveWordGroups is the golang structure of table im_sensitive_word_groups for DAO operations like Where/Data. +type ImSensitiveWordGroups struct { + g.Meta `orm:"table:im_sensitive_word_groups, do:true"` + Id any // + TenantId any // 0 means global dictionary + GroupCode any // + GroupName any // + Priority any // + Status any // 1 enabled, 2 disabled + Remark any // + CreatedAt *gtime.Time // + CreatedBy any // + UpdatedAt *gtime.Time // + UpdatedBy any // + DeletedAt *gtime.Time // + DeletedBy any // +} diff --git a/server/internal/model/do/im_sensitive_words.go b/server/internal/model/do/im_sensitive_words.go new file mode 100644 index 0000000..1a58efd --- /dev/null +++ b/server/internal/model/do/im_sensitive_words.go @@ -0,0 +1,35 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImSensitiveWords is the golang structure of table im_sensitive_words for DAO operations like Where/Data. +type ImSensitiveWords struct { + g.Meta `orm:"table:im_sensitive_words, do:true"` + Id any // + TenantId any // 0 means global dictionary + GroupId any // + Word any // + WordHash any // SHA-256 of normalized word + MatchType any // + SceneJson *gjson.Json // Enabled scenes + Action any // + Replacement any // + RiskLevel any // + Priority any // + Status any // 1 enabled, 2 disabled + Remark any // + CreatedAt *gtime.Time // + CreatedBy any // + UpdatedAt *gtime.Time // + UpdatedBy any // + DeletedAt *gtime.Time // + DeletedBy any // +} diff --git a/server/internal/model/do/im_tenant_config.go b/server/internal/model/do/im_tenant_config.go index 35ac912..63edd98 100644 --- a/server/internal/model/do/im_tenant_config.go +++ b/server/internal/model/do/im_tenant_config.go @@ -11,14 +11,18 @@ import ( // ImTenantConfig is the golang structure of table im_tenant_config for DAO operations like Where/Data. type ImTenantConfig struct { - g.Meta `orm:"table:im_tenant_config, do:true"` - Id any // - TenantId any // - MaxUsers any // 0 means unlimited - MaxGroups any // 0 means unlimited - MaxGroupMembers any // 0 means unlimited - CreatedAt *gtime.Time // - CreatedBy any // - UpdatedAt *gtime.Time // - UpdatedBy any // + g.Meta `orm:"table:im_tenant_config, do:true"` + Id any // + TenantId any // + MaxUsers any // 0 means unlimited + MaxGroups any // 0 means unlimited + MaxGroupMembers any // 0 means unlimited + DefaultPolicyGroupId any // Default user policy group + SecurityPolicyVersion any // Published security policy version + GlobalFriendEnabled any // Published global friend switch + MessageCurfewEnabled any // Published message curfew switch + CreatedAt *gtime.Time // + CreatedBy any // + UpdatedAt *gtime.Time // + UpdatedBy any // } diff --git a/server/internal/model/do/im_user_policy_group_members.go b/server/internal/model/do/im_user_policy_group_members.go new file mode 100644 index 0000000..9e00af6 --- /dev/null +++ b/server/internal/model/do/im_user_policy_group_members.go @@ -0,0 +1,29 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImUserPolicyGroupMembers is the golang structure of table im_user_policy_group_members for DAO operations like Where/Data. +type ImUserPolicyGroupMembers struct { + g.Meta `orm:"table:im_user_policy_group_members, do:true"` + Id any // + TenantId any // + GroupId any // + UserId any // User ID in the tenant database + Status any // 1 enabled, 2 disabled + ValidFrom *gtime.Time // + ValidUntil *gtime.Time // + Remark any // + CreatedAt *gtime.Time // + CreatedBy any // + UpdatedAt *gtime.Time // + UpdatedBy any // + DeletedAt *gtime.Time // + DeletedBy any // +} diff --git a/server/internal/model/do/im_user_policy_groups.go b/server/internal/model/do/im_user_policy_groups.go new file mode 100644 index 0000000..ee4638a --- /dev/null +++ b/server/internal/model/do/im_user_policy_groups.go @@ -0,0 +1,33 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImUserPolicyGroups is the golang structure of table im_user_policy_groups for DAO operations like Where/Data. +type ImUserPolicyGroups struct { + g.Meta `orm:"table:im_user_policy_groups, do:true"` + Id any // + TenantId any // 0 means global default + GroupCode any // Stable policy group code + GroupName any // Policy group name + Priority any // Higher value has higher priority + Status any // 1 enabled, 2 disabled + PolicyJson *gjson.Json // Login, friend, message, group and file policies + IpWhitelist *gjson.Json // IPv4/IPv6 or CIDR list + IpBlacklist *gjson.Json // IPv4/IPv6 or CIDR list + Version any // Optimistic-lock/config version + Remark any // + CreatedAt *gtime.Time // + CreatedBy any // + UpdatedAt *gtime.Time // + UpdatedBy any // + DeletedAt *gtime.Time // + DeletedBy any // +} diff --git a/server/internal/model/entity/im_message_curfew_rules.go b/server/internal/model/entity/im_message_curfew_rules.go new file mode 100644 index 0000000..9dae62e --- /dev/null +++ b/server/internal/model/entity/im_message_curfew_rules.go @@ -0,0 +1,37 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImMessageCurfewRules is the golang structure for table im_message_curfew_rules. +type ImMessageCurfewRules struct { + Id int64 `json:"id" orm:"id" description:""` + TenantId int64 `json:"tenantId" orm:"tenant_id" description:""` + PolicyId int64 `json:"policyId" orm:"policy_id" description:""` + RuleCode string `json:"ruleCode" orm:"rule_code" description:""` + RuleName string `json:"ruleName" orm:"rule_name" description:""` + DateType string `json:"dateType" orm:"date_type" description:"daily, weekday, weekend, custom"` + CustomDates *gjson.Json `json:"customDates" orm:"custom_dates" description:"YYYY-MM-DD values for custom date type"` + Weekdays *gjson.Json `json:"weekdays" orm:"weekdays" description:"ISO weekdays 1 through 7"` + Timezone string `json:"timezone" orm:"timezone" description:""` + StartTime *gtime.Time `json:"startTime" orm:"start_time" description:""` + EndTime *gtime.Time `json:"endTime" orm:"end_time" description:"Less than start_time means crossing midnight"` + Scope string `json:"scope" orm:"scope" description:"private_message or group_message"` + WhitelistUserIds *gjson.Json `json:"whitelistUserIds" orm:"whitelist_user_ids" description:""` + WhitelistGroupIds *gjson.Json `json:"whitelistGroupIds" orm:"whitelist_group_ids" description:""` + Message string `json:"message" orm:"message" description:""` + Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"` + Sort int `json:"sort" orm:"sort" description:""` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` + DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""` +} diff --git a/server/internal/model/entity/im_security_ip_rules.go b/server/internal/model/entity/im_security_ip_rules.go new file mode 100644 index 0000000..bc28762 --- /dev/null +++ b/server/internal/model/entity/im_security_ip_rules.go @@ -0,0 +1,30 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImSecurityIpRules is the golang structure for table im_security_ip_rules. +type ImSecurityIpRules struct { + Id int64 `json:"id" orm:"id" description:""` + TenantId int64 `json:"tenantId" orm:"tenant_id" description:""` + RuleType string `json:"ruleType" orm:"rule_type" description:"whitelist or blacklist"` + IpCidr string `json:"ipCidr" orm:"ip_cidr" description:"IPv4, IPv6 or CIDR"` + Action string `json:"action" orm:"action" description:"allow, challenge, block, audit_only"` + SceneJson *gjson.Json `json:"sceneJson" orm:"scene_json" description:"login, register, message, upload and other scenes"` + RiskLevel string `json:"riskLevel" orm:"risk_level" description:""` + Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"` + ExpiresAt *gtime.Time `json:"expiresAt" orm:"expires_at" description:""` + Remark string `json:"remark" orm:"remark" description:""` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` + DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""` +} diff --git a/server/internal/model/entity/im_security_policy.go b/server/internal/model/entity/im_security_policy.go new file mode 100644 index 0000000..ccd0566 --- /dev/null +++ b/server/internal/model/entity/im_security_policy.go @@ -0,0 +1,37 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImSecurityPolicy is the golang structure for table im_security_policy. +type ImSecurityPolicy struct { + Id int64 `json:"id" orm:"id" description:""` + TenantId int64 `json:"tenantId" orm:"tenant_id" description:"0 means global fallback policy"` + PolicyVersion uint `json:"policyVersion" orm:"policy_version" description:""` + PolicyName string `json:"policyName" orm:"policy_name" description:""` + PublishStatus string `json:"publishStatus" orm:"publish_status" description:""` + PasswordPolicy *gjson.Json `json:"passwordPolicy" orm:"password_policy" description:""` + LoginRateLimit *gjson.Json `json:"loginRateLimit" orm:"login_rate_limit" description:""` + SensitiveWordPolicy *gjson.Json `json:"sensitiveWordPolicy" orm:"sensitive_word_policy" description:""` + FileReviewPolicy *gjson.Json `json:"fileReviewPolicy" orm:"file_review_policy" description:""` + RealnamePolicy *gjson.Json `json:"realnamePolicy" orm:"realname_policy" description:""` + RiskChallengePolicy *gjson.Json `json:"riskChallengePolicy" orm:"risk_challenge_policy" description:""` + GlobalFriendEnabled int `json:"globalFriendEnabled" orm:"global_friend_enabled" description:"Backend master switch for every add-friend entry"` + FriendDisabledPolicy *gjson.Json `json:"friendDisabledPolicy" orm:"friend_disabled_policy" description:"Profile masking, QR and group-member restrictions"` + MessageCurfewEnabled int `json:"messageCurfewEnabled" orm:"message_curfew_enabled" description:"Backend master switch for message curfew"` + Remark string `json:"remark" orm:"remark" description:""` + PublishedAt *gtime.Time `json:"publishedAt" orm:"published_at" description:""` + PublishedBy int64 `json:"publishedBy" orm:"published_by" description:""` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` + DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""` +} diff --git a/server/internal/model/entity/im_sensitive_word_groups.go b/server/internal/model/entity/im_sensitive_word_groups.go new file mode 100644 index 0000000..882ba77 --- /dev/null +++ b/server/internal/model/entity/im_sensitive_word_groups.go @@ -0,0 +1,26 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// ImSensitiveWordGroups is the golang structure for table im_sensitive_word_groups. +type ImSensitiveWordGroups struct { + Id int64 `json:"id" orm:"id" description:""` + TenantId int64 `json:"tenantId" orm:"tenant_id" description:"0 means global dictionary"` + GroupCode string `json:"groupCode" orm:"group_code" description:""` + GroupName string `json:"groupName" orm:"group_name" description:""` + Priority int `json:"priority" orm:"priority" description:""` + Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"` + Remark string `json:"remark" orm:"remark" description:""` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` + DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""` +} diff --git a/server/internal/model/entity/im_sensitive_words.go b/server/internal/model/entity/im_sensitive_words.go new file mode 100644 index 0000000..ba097ca --- /dev/null +++ b/server/internal/model/entity/im_sensitive_words.go @@ -0,0 +1,33 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImSensitiveWords is the golang structure for table im_sensitive_words. +type ImSensitiveWords struct { + Id int64 `json:"id" orm:"id" description:""` + TenantId int64 `json:"tenantId" orm:"tenant_id" description:"0 means global dictionary"` + GroupId int64 `json:"groupId" orm:"group_id" description:""` + Word string `json:"word" orm:"word" description:""` + WordHash string `json:"wordHash" orm:"word_hash" description:"SHA-256 of normalized word"` + MatchType string `json:"matchType" orm:"match_type" description:""` + SceneJson *gjson.Json `json:"sceneJson" orm:"scene_json" description:"Enabled scenes"` + Action string `json:"action" orm:"action" description:""` + Replacement string `json:"replacement" orm:"replacement" description:""` + RiskLevel string `json:"riskLevel" orm:"risk_level" description:""` + Priority int `json:"priority" orm:"priority" description:""` + Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"` + Remark string `json:"remark" orm:"remark" description:""` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` + DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""` +} diff --git a/server/internal/model/entity/im_tenant_config.go b/server/internal/model/entity/im_tenant_config.go index a28e460..e8caeb9 100644 --- a/server/internal/model/entity/im_tenant_config.go +++ b/server/internal/model/entity/im_tenant_config.go @@ -10,13 +10,17 @@ import ( // ImTenantConfig is the golang structure for table im_tenant_config. type ImTenantConfig struct { - Id int64 `json:"id" orm:"id" description:""` - TenantId int64 `json:"tenantId" orm:"tenant_id" description:""` - MaxUsers uint64 `json:"maxUsers" orm:"max_users" description:"0 means unlimited"` - MaxGroups uint64 `json:"maxGroups" orm:"max_groups" description:"0 means unlimited"` - MaxGroupMembers uint `json:"maxGroupMembers" orm:"max_group_members" description:"0 means unlimited"` - CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` - CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` - UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` - UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` + Id int64 `json:"id" orm:"id" description:""` + TenantId int64 `json:"tenantId" orm:"tenant_id" description:""` + MaxUsers uint64 `json:"maxUsers" orm:"max_users" description:"0 means unlimited"` + MaxGroups uint64 `json:"maxGroups" orm:"max_groups" description:"0 means unlimited"` + MaxGroupMembers uint `json:"maxGroupMembers" orm:"max_group_members" description:"0 means unlimited"` + DefaultPolicyGroupId int64 `json:"defaultPolicyGroupId" orm:"default_policy_group_id" description:"Default user policy group"` + SecurityPolicyVersion uint `json:"securityPolicyVersion" orm:"security_policy_version" description:"Published security policy version"` + GlobalFriendEnabled int `json:"globalFriendEnabled" orm:"global_friend_enabled" description:"Published global friend switch"` + MessageCurfewEnabled int `json:"messageCurfewEnabled" orm:"message_curfew_enabled" description:"Published message curfew switch"` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` } diff --git a/server/internal/model/entity/im_user_policy_group_members.go b/server/internal/model/entity/im_user_policy_group_members.go new file mode 100644 index 0000000..af440ba --- /dev/null +++ b/server/internal/model/entity/im_user_policy_group_members.go @@ -0,0 +1,27 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// ImUserPolicyGroupMembers is the golang structure for table im_user_policy_group_members. +type ImUserPolicyGroupMembers struct { + Id int64 `json:"id" orm:"id" description:""` + TenantId int64 `json:"tenantId" orm:"tenant_id" description:""` + GroupId int64 `json:"groupId" orm:"group_id" description:""` + UserId int64 `json:"userId" orm:"user_id" description:"User ID in the tenant database"` + Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"` + ValidFrom *gtime.Time `json:"validFrom" orm:"valid_from" description:""` + ValidUntil *gtime.Time `json:"validUntil" orm:"valid_until" description:""` + Remark string `json:"remark" orm:"remark" description:""` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` + DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""` +} diff --git a/server/internal/model/entity/im_user_policy_groups.go b/server/internal/model/entity/im_user_policy_groups.go new file mode 100644 index 0000000..1485510 --- /dev/null +++ b/server/internal/model/entity/im_user_policy_groups.go @@ -0,0 +1,31 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/os/gtime" +) + +// ImUserPolicyGroups is the golang structure for table im_user_policy_groups. +type ImUserPolicyGroups struct { + Id int64 `json:"id" orm:"id" description:""` + TenantId int64 `json:"tenantId" orm:"tenant_id" description:"0 means global default"` + GroupCode string `json:"groupCode" orm:"group_code" description:"Stable policy group code"` + GroupName string `json:"groupName" orm:"group_name" description:"Policy group name"` + Priority int `json:"priority" orm:"priority" description:"Higher value has higher priority"` + Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"` + PolicyJson *gjson.Json `json:"policyJson" orm:"policy_json" description:"Login, friend, message, group and file policies"` + IpWhitelist *gjson.Json `json:"ipWhitelist" orm:"ip_whitelist" description:"IPv4/IPv6 or CIDR list"` + IpBlacklist *gjson.Json `json:"ipBlacklist" orm:"ip_blacklist" description:"IPv4/IPv6 or CIDR list"` + Version uint `json:"version" orm:"version" description:"Optimistic-lock/config version"` + Remark string `json:"remark" orm:"remark" description:""` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:""` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""` + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` + DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""` +} diff --git a/server/internal/model/input/sysin/im_dashboard.go b/server/internal/model/input/sysin/im_dashboard.go new file mode 100644 index 0000000..9eeedee --- /dev/null +++ b/server/internal/model/input/sysin/im_dashboard.go @@ -0,0 +1,44 @@ +package sysin + +import ( + "context" + + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" +) + +type ImDashboardOverviewInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` +} + +type ImDashboardOverviewModel struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + TenantName string `json:"tenantName" dc:"租户名称"` + TotalUsers int64 `json:"totalUsers" dc:"总用户数"` + ActiveUsers int64 `json:"activeUsers" dc:"活跃用户数"` + TotalGroups int64 `json:"totalGroups" dc:"总群组数"` + TotalConversations int64 `json:"totalConversations" dc:"总会话数"` + TotalMessages int64 `json:"totalMessages" dc:"总消息数"` + TodayMessages int64 `json:"todayMessages" dc:"今日消息数"` +} + +type ImDashboardTrendsInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + Days int `json:"days" dc:"统计天数"` +} + +func (in *ImDashboardTrendsInp) Filter(ctx context.Context) error { + if in.Days == 0 { + in.Days = 7 + } + if in.Days < 1 || in.Days > 31 { + return gerror.New("统计天数必须在1到31天之间") + } + return nil +} + +type ImDashboardTrendModel struct { + Date *gtime.Time `json:"date" dc:"日期"` + UserCount int64 `json:"userCount" dc:"新增用户数"` + MessageCount int64 `json:"messageCount" dc:"新增消息数"` +} diff --git a/server/internal/model/input/sysin/im_login_audit.go b/server/internal/model/input/sysin/im_login_audit.go new file mode 100644 index 0000000..c94b0b5 --- /dev/null +++ b/server/internal/model/input/sysin/im_login_audit.go @@ -0,0 +1,161 @@ +package sysin + +import ( + "context" + "hotgo/internal/model/input/form" + "strings" + + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" +) + +type ImUserLoginHistoryListInp struct { + form.PageReq + TenantId int64 `json:"tenantId" dc:"租户ID"` + UserId string `json:"userId" dc:"用户ID"` + Account string `json:"account" dc:"脱敏账号"` + LoginType string `json:"loginType" dc:"登录方式"` + EventType string `json:"eventType" dc:"事件类型"` + Platform string `json:"platform" dc:"客户端平台"` + Ip string `json:"ip" dc:"IP地址"` + LoginAt []*gtime.Time `json:"loginAt" dc:"登录时间"` +} + +func (in *ImUserLoginHistoryListInp) Filter(ctx context.Context) error { + in.Account = strings.TrimSpace(in.Account) + in.Ip = strings.TrimSpace(in.Ip) + return filterImAuditPage(&in.PageReq) +} + +type ImUserLoginHistoryModel struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + TenantName string `json:"tenantName" dc:"租户名称"` + Id int64 `json:"id" dc:"ID"` + UserId string `json:"userId" dc:"用户ID"` + Username string `json:"username" dc:"用户名"` + AccountType string `json:"accountType" dc:"账号类型"` + AccountMask string `json:"accountMask" dc:"脱敏账号"` + LoginType string `json:"loginType" dc:"登录方式"` + EventType string `json:"eventType" dc:"事件类型"` + SessionId string `json:"sessionId" dc:"会话ID"` + DeviceId string `json:"deviceId" dc:"设备ID"` + Platform string `json:"platform" dc:"客户端平台"` + AppVersion string `json:"appVersion" dc:"客户端版本"` + Ip string `json:"ip" dc:"IP地址"` + Region string `json:"region" dc:"地区"` + UserAgent string `json:"userAgent" dc:"客户端标识"` + RiskLevel string `json:"riskLevel" dc:"风险等级"` + RequestId string `json:"requestId" dc:"请求ID"` + LoginAt *gtime.Time `json:"loginAt" dc:"登录时间"` + LogoutAt *gtime.Time `json:"logoutAt" dc:"登出时间"` + Metadata string `json:"metadata" dc:"元数据"` +} + +type ImLoginFailureLogListInp struct { + form.PageReq + TenantId int64 `json:"tenantId" dc:"租户ID"` + UserId string `json:"userId" dc:"用户ID"` + Account string `json:"account" dc:"脱敏账号"` + FailureType string `json:"failureType" dc:"失败类型"` + Platform string `json:"platform" dc:"客户端平台"` + Ip string `json:"ip" dc:"IP地址"` + AttemptAt []*gtime.Time `json:"attemptAt" dc:"尝试时间"` +} + +func (in *ImLoginFailureLogListInp) Filter(ctx context.Context) error { + in.Account = strings.TrimSpace(in.Account) + in.Ip = strings.TrimSpace(in.Ip) + return filterImAuditPage(&in.PageReq) +} + +func filterImAuditPage(page *form.PageReq) error { + if page.Page <= 0 { + page.Page = 1 + } + if page.PerPage <= 0 { + page.PerPage = 20 + } + if page.PerPage > 200 { + return gerror.New("每页数量不能超过200") + } + return nil +} + +type ImLoginFailureLogModel struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + TenantName string `json:"tenantName" dc:"租户名称"` + Id int64 `json:"id" dc:"ID"` + UserId string `json:"userId" dc:"用户ID"` + AccountType string `json:"accountType" dc:"账号类型"` + AccountMask string `json:"accountMask" dc:"脱敏账号"` + FailureType string `json:"failureType" dc:"失败类型"` + Reason string `json:"reason" dc:"原因码"` + Detail string `json:"detail" dc:"失败详情"` + Ip string `json:"ip" dc:"IP地址"` + Region string `json:"region" dc:"地区"` + DeviceId string `json:"deviceId" dc:"设备ID"` + Platform string `json:"platform" dc:"客户端平台"` + AppVersion string `json:"appVersion" dc:"客户端版本"` + UserAgent string `json:"userAgent" dc:"客户端标识"` + RiskLevel string `json:"riskLevel" dc:"风险等级"` + RiskAction string `json:"riskAction" dc:"风控动作"` + RequestId string `json:"requestId" dc:"请求ID"` + AttemptAt *gtime.Time `json:"attemptAt" dc:"尝试时间"` + Metadata string `json:"metadata" dc:"元数据"` +} + +type ImLoginFailureViewInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + Id int64 `json:"id" dc:"日志ID"` +} + +func (in *ImLoginFailureViewInp) Filter(ctx context.Context) error { + if in.Id <= 0 { + return gerror.New("日志ID不能为空") + } + return nil +} + +type ImLoginFailureAddBlacklistInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + Ip string `json:"ip" dc:"IP地址"` + Remark string `json:"remark" dc:"备注"` +} + +func (in *ImLoginFailureAddBlacklistInp) Filter(ctx context.Context) error { + in.Ip = strings.TrimSpace(in.Ip) + if in.Ip == "" { + return gerror.New("IP地址不能为空") + } + return nil +} + +type ImLoginFailureBanUserInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + UserId int64 `json:"userId" dc:"用户ID"` + Reason string `json:"reason" dc:"封禁原因"` +} + +func (in *ImLoginFailureBanUserInp) Filter(ctx context.Context) error { + in.Reason = strings.TrimSpace(in.Reason) + if in.UserId <= 0 { + return gerror.New("用户ID不能为空") + } + if in.Reason == "" { + return gerror.New("封禁原因不能为空") + } + return nil +} + +type ImLoginAuditExportModel struct { + Id int64 `json:"id" dc:"ID"` + UserId string `json:"userId" dc:"用户ID"` + AccountMask string `json:"accountMask" dc:"脱敏账号"` + EventType string `json:"eventType" dc:"事件/失败类型"` + Platform string `json:"platform" dc:"客户端平台"` + Ip string `json:"ip" dc:"IP地址"` + Region string `json:"region" dc:"地区"` + RiskLevel string `json:"riskLevel" dc:"风险等级"` + Reason string `json:"reason" dc:"原因"` + OccurredAt *gtime.Time `json:"occurredAt" dc:"发生时间"` +} diff --git a/server/internal/model/input/sysin/im_message_admin.go b/server/internal/model/input/sysin/im_message_admin.go new file mode 100644 index 0000000..e027f05 --- /dev/null +++ b/server/internal/model/input/sysin/im_message_admin.go @@ -0,0 +1,147 @@ +package sysin + +import ( + "context" + "hotgo/internal/consts" + "hotgo/internal/library/dict" + "hotgo/internal/model/input/form" + "strings" + + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" +) + +type ImPrivateMessageListInp struct { + form.PageReq + TenantId int64 `json:"tenantId" dc:"租户ID"` + Topic string `json:"topic" dc:"会话Topic"` + FromUserId string `json:"fromUserId" dc:"发送用户ID"` + ToUserId string `json:"toUserId" dc:"接收用户ID"` + ContentType string `json:"contentType" dc:"内容类型"` + Status string `json:"status" dc:"状态"` + Keyword string `json:"keyword" dc:"内容关键词"` + CreatedAt []*gtime.Time `json:"createdAt" dc:"发送时间"` +} + +func (in *ImPrivateMessageListInp) Filter(ctx context.Context) error { + return filterImMessageList(&in.PageReq, &in.Topic, &in.Keyword, in.ContentType, in.Status) +} + +type ImGroupMessageListInp struct { + form.PageReq + TenantId int64 `json:"tenantId" dc:"租户ID"` + Topic string `json:"topic" dc:"群Topic"` + SenderUserId string `json:"senderUserId" dc:"发送用户ID"` + ContentType string `json:"contentType" dc:"内容类型"` + Status string `json:"status" dc:"状态"` + Keyword string `json:"keyword" dc:"内容关键词"` + CreatedAt []*gtime.Time `json:"createdAt" dc:"发送时间"` +} + +func (in *ImGroupMessageListInp) Filter(ctx context.Context) error { + return filterImMessageList(&in.PageReq, &in.Topic, &in.Keyword, in.ContentType, in.Status) +} + +func filterImMessageList(page *form.PageReq, topic *string, keyword *string, contentType string, status string) error { + *topic = strings.TrimSpace(*topic) + *keyword = strings.TrimSpace(*keyword) + if page.Page <= 0 { + page.Page = 1 + } + if page.PerPage <= 0 { + page.PerPage = 20 + } + if page.PerPage > 200 { + return gerror.New("每页数量不能超过200") + } + if contentType != "" && !dict.HasOptionKey(consts.ImMessageContentTypeOptions, contentType) { + return gerror.New("消息类型不合法") + } + if status != "" && !dict.HasOptionKey(consts.ImMessageStatusOptions, status) { + return gerror.New("消息状态不合法") + } + return nil +} + +type ImMessageListModel struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + TenantName string `json:"tenantName" dc:"租户名称"` + Topic string `json:"topic" dc:"会话Topic"` + SeqId int64 `json:"seqId" dc:"消息序号"` + FromUserId string `json:"fromUserId" dc:"发送用户ID"` + SenderUsername string `json:"senderUsername" dc:"发送人用户名"` + SenderNickname string `json:"senderNickname" dc:"发送人昵称"` + ToUserId string `json:"toUserId" dc:"接收用户ID"` + ReceiverUsername string `json:"receiverUsername" dc:"接收人用户名"` + ReceiverNickname string `json:"receiverNickname" dc:"接收人昵称"` + GroupName string `json:"groupName" dc:"群名称"` + GroupNo string `json:"groupNo" dc:"群号"` + ContentType string `json:"contentType" dc:"消息类型"` + ContentExcerpt string `json:"contentExcerpt" dc:"内容摘要"` + Status string `json:"status" dc:"状态"` + ReplyToSeq int64 `json:"replyToSeq" dc:"回复消息序号"` + AtUsers string `json:"atUsers" dc:"@用户"` + CreatedAt *gtime.Time `json:"createdAt" dc:"发送时间"` + UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"` +} + +type ImMessageViewInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + Topic string `json:"topic" dc:"会话Topic"` + SeqId int64 `json:"seqId" dc:"消息序号"` +} + +func (in *ImMessageViewInp) Filter(ctx context.Context) error { + in.Topic = strings.TrimSpace(in.Topic) + if in.Topic == "" || in.SeqId <= 0 { + return gerror.New("消息Topic和序号不能为空") + } + return nil +} + +type ImMessageViewModel struct { + ImMessageListModel + Head string `json:"head" dc:"消息头"` + Content string `json:"content" dc:"完整消息内容"` + Metadata string `json:"metadata" dc:"扩展数据"` +} + +type ImMessageActionInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + Topic string `json:"topic" dc:"会话Topic"` + SeqId int64 `json:"seqId" dc:"消息序号"` + Reason string `json:"reason" dc:"处置原因"` +} + +func (in *ImMessageActionInp) Filter(ctx context.Context) error { + in.Topic = strings.TrimSpace(in.Topic) + in.Reason = strings.TrimSpace(in.Reason) + if in.Topic == "" || in.SeqId <= 0 { + return gerror.New("消息Topic和序号不能为空") + } + if in.Reason == "" { + return gerror.New("处置原因不能为空") + } + if len([]rune(in.Reason)) > 500 { + return gerror.New("处置原因不能超过500个字符") + } + return nil +} + +type ImMessageCommandModel struct { + CommandId string `json:"commandId" dc:"命令ID"` + EventId string `json:"eventId" dc:"事件ID"` + Status string `json:"status" dc:"命令状态"` +} + +type ImMessageExportModel struct { + Topic string `json:"topic" dc:"Topic"` + SeqId int64 `json:"seqId" dc:"消息序号"` + FromUserId string `json:"fromUserId" dc:"发送用户ID"` + ToUserId string `json:"toUserId" dc:"接收用户ID"` + GroupName string `json:"groupName" dc:"群名称"` + ContentType string `json:"contentType" dc:"消息类型"` + ContentExcerpt string `json:"contentExcerpt" dc:"内容摘要"` + Status string `json:"status" dc:"状态"` + CreatedAt *gtime.Time `json:"createdAt" dc:"发送时间"` +} diff --git a/server/internal/model/input/sysin/im_policy_test.go b/server/internal/model/input/sysin/im_policy_test.go new file mode 100644 index 0000000..c1c21b4 --- /dev/null +++ b/server/internal/model/input/sysin/im_policy_test.go @@ -0,0 +1,145 @@ +package sysin + +import ( + "context" + "testing" + + "hotgo/internal/consts" + + "github.com/gogf/gf/v2/encoding/gjson" +) + +func TestImMessageCurfewRuleFilter(t *testing.T) { + ctx := context.Background() + valid := &ImMessageCurfewRuleInp{ + RuleCode: "after_work", + RuleName: "下班时段", + DateType: consts.ImCurfewDateWeekday, + StartTime: "18:00", + EndTime: "09:00", + Scope: consts.ImCurfewScopePrivate, + } + if err := valid.Filter(ctx); err != nil { + t.Fatalf("跨午夜宵禁规则应合法: %v", err) + } + if valid.Timezone != "Asia/Shanghai" || valid.Status != consts.StatusEnabled { + t.Fatalf("默认值未补齐: timezone=%s status=%d", valid.Timezone, valid.Status) + } + + invalidTime := *valid + invalidTime.StartTime = "25:00" + if err := invalidTime.Filter(ctx); err == nil { + t.Fatal("非法宵禁时间应被拒绝") + } +} + +func TestImSecurityPolicySaveFilterRequiresCurfewRule(t *testing.T) { + in := &ImSecurityPolicySaveInp{ + PolicyName: "默认策略", + GlobalFriendEnabled: 1, + MessageCurfewEnabled: 1, + } + if err := in.Filter(context.Background()); err == nil { + t.Fatal("启用宵禁但未配置规则应被拒绝") + } + in.CurfewRules = []*ImMessageCurfewRuleInp{{ + RuleCode: "group_only", + RuleName: "仅群聊", + DateType: consts.ImCurfewDateDaily, + StartTime: "18:00", + EndTime: "09:00", + Scope: consts.ImCurfewScopeGroup, + }} + if err := in.Filter(context.Background()); err == nil { + t.Fatal("宵禁仅配置群聊规则时应被拒绝") + } +} + +func TestImSecurityPolicySaveFilterForcesEveryFriendEntryOff(t *testing.T) { + in := &ImSecurityPolicySaveInp{ + PolicyName: "下班策略", + GlobalFriendEnabled: 0, + MessageCurfewEnabled: 0, + FriendDisabledPolicy: gjson.New(map[string]interface{}{ + "hide_profile": false, + "blocked_entries": []string{"search"}, + }), + } + if err := in.Filter(context.Background()); err != nil { + t.Fatalf("关闭全局好友功能的策略应合法: %v", err) + } + policy := in.FriendDisabledPolicy.Map() + if hide, ok := policy["hide_profile"].(bool); !ok || !hide { + t.Fatal("关闭全局好友功能时必须强制隐藏个人资料") + } + entries := in.FriendDisabledPolicy.Get("blocked_entries").Array() + if len(entries) != 6 { + t.Fatalf("关闭全局好友功能时必须禁用全部6个入口: %#v", policy["blocked_entries"]) + } +} + +func TestImSecurityPolicyPublishFilter(t *testing.T) { + ctx := context.Background() + if err := (&ImSecurityPolicyPublishInp{Id: 1, Reason: " "}).Filter(ctx); err == nil { + t.Fatal("空发布原因应被拒绝") + } + if err := (&ImSecurityPolicyPublishInp{Id: 1, Reason: "管理员发布"}).Filter(ctx); err != nil { + t.Fatalf("合法发布参数不应报错: %v", err) + } +} + +func TestImSecurityIPRuleEditFilter(t *testing.T) { + ctx := context.Background() + valid := &ImSecurityIPRuleEditInp{ + RuleType: "blacklist", + IpCidr: "192.0.2.0/24", + Action: consts.ImSecurityActionBlock, + SceneJson: gjson.New([]string{"login"}), + RiskLevel: consts.ImRiskLevelHigh, + } + if err := valid.Filter(ctx); err != nil { + t.Fatalf("合法IP阻断规则不应报错: %v", err) + } + + invalidAction := *valid + invalidAction.Action = consts.ImPolicyActionDeny + if err := invalidAction.Filter(ctx); err == nil { + t.Fatal("数据库枚举不支持的deny动作应被拒绝") + } +} + +func TestImSensitiveWordEditFilter(t *testing.T) { + in := &ImSensitiveWordEditInp{ + GroupId: 1, + Word: "测试词", + MatchType: consts.ImSensitiveMatchContains, + SceneJson: gjson.New([]string{"private_message"}), + Action: consts.ImSensitiveActionReplace, + RiskLevel: consts.ImRiskLevelMedium, + } + if err := in.Filter(context.Background()); err == nil { + t.Fatal("替换动作未填写替换文本应被拒绝") + } +} + +func TestImSensitiveWordGroupEditFilter(t *testing.T) { + in := &ImSensitiveWordGroupEditInp{GroupCode: "default", GroupName: " "} + if err := in.Filter(context.Background()); err == nil { + t.Fatal("空分组名称应被拒绝") + } +} + +func TestImUserPolicyGroupInputFilter(t *testing.T) { + ctx := context.Background() + group := &ImUserPolicyGroupEditInp{ + GroupCode: "staff", + GroupName: " ", + PolicyJson: gjson.New(map[string]interface{}{}), + } + if err := group.Filter(ctx); err == nil { + t.Fatal("空用户策略分组名称应被拒绝") + } + if err := (&ImUserPolicyGroupMemberAddInp{GroupId: 1, UserId: 0}).Filter(ctx); err == nil { + t.Fatal("无效用户ID应被拒绝") + } +} diff --git a/server/internal/model/input/sysin/im_security_policy.go b/server/internal/model/input/sysin/im_security_policy.go new file mode 100644 index 0000000..020a456 --- /dev/null +++ b/server/internal/model/input/sysin/im_security_policy.go @@ -0,0 +1,324 @@ +package sysin + +import ( + "context" + "strings" + "time" + + "hotgo/internal/consts" + "hotgo/internal/library/dict" + "hotgo/internal/model/input/form" + + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" +) + +type ImSecurityPolicyListInp struct { + form.PageReq + TenantId int64 `json:"tenantId"` + PublishStatus string `json:"publishStatus"` +} + +func (in *ImSecurityPolicyListInp) Filter(ctx context.Context) error { + if in.PublishStatus != "" && !dict.HasOptionKey(consts.ImSecurityPublishStatusOptions, in.PublishStatus) { + return gerror.New("发布状态不合法") + } + return nil +} + +type ImMessageCurfewRuleModel struct { + Id int64 `json:"id"` + RuleCode string `json:"ruleCode"` + RuleName string `json:"ruleName"` + DateType string `json:"dateType"` + CustomDates string `json:"customDates"` + Weekdays string `json:"weekdays"` + Timezone string `json:"timezone"` + StartTime string `json:"startTime"` + EndTime string `json:"endTime"` + Scope string `json:"scope"` + WhitelistUserIds string `json:"whitelistUserIds"` + WhitelistGroupIds string `json:"whitelistGroupIds"` + Message string `json:"message"` + Status int `json:"status"` + Sort int `json:"sort"` +} + +type ImSecurityPolicyModel struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + PolicyVersion uint `json:"policyVersion"` + PolicyName string `json:"policyName"` + PublishStatus string `json:"publishStatus"` + PasswordPolicy string `json:"passwordPolicy"` + LoginRateLimit string `json:"loginRateLimit"` + SensitiveWordPolicy string `json:"sensitiveWordPolicy"` + FileReviewPolicy string `json:"fileReviewPolicy"` + RealnamePolicy string `json:"realnamePolicy"` + RiskChallengePolicy string `json:"riskChallengePolicy"` + GlobalFriendEnabled int `json:"globalFriendEnabled"` + FriendDisabledPolicy string `json:"friendDisabledPolicy"` + MessageCurfewEnabled int `json:"messageCurfewEnabled"` + Remark string `json:"remark"` + PublishedAt *gtime.Time `json:"publishedAt"` + PublishedBy int64 `json:"publishedBy"` + CreatedAt *gtime.Time `json:"createdAt"` + UpdatedAt *gtime.Time `json:"updatedAt"` + CurfewRules []*ImMessageCurfewRuleModel `json:"curfewRules"` +} + +type ImSecurityPolicyViewInp struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` +} + +func (in *ImSecurityPolicyViewInp) Filter(ctx context.Context) error { + if in.Id <= 0 && in.TenantId < 0 { + return gerror.New("策略ID或租户ID不合法") + } + return nil +} + +type ImMessageCurfewRuleInp struct { + RuleCode string `json:"ruleCode"` + RuleName string `json:"ruleName"` + DateType string `json:"dateType"` + CustomDates *gjson.Json `json:"customDates"` + Weekdays *gjson.Json `json:"weekdays"` + Timezone string `json:"timezone"` + StartTime string `json:"startTime"` + EndTime string `json:"endTime"` + Scope string `json:"scope"` + WhitelistUserIds *gjson.Json `json:"whitelistUserIds"` + WhitelistGroupIds *gjson.Json `json:"whitelistGroupIds"` + Message string `json:"message"` + Status int `json:"status"` + Sort int `json:"sort"` +} + +func (in *ImMessageCurfewRuleInp) Filter(ctx context.Context) error { + in.RuleCode = strings.TrimSpace(in.RuleCode) + in.RuleName = strings.TrimSpace(in.RuleName) + in.Timezone = strings.TrimSpace(in.Timezone) + in.Message = strings.TrimSpace(in.Message) + if !imPolicyGroupCodePattern.MatchString(in.RuleCode) { + return gerror.New("宵禁规则编码格式不合法") + } + if in.RuleName == "" { + return gerror.New("宵禁规则名称不能为空") + } + if !dict.HasOptionKey(consts.ImCurfewDateTypeOptions, in.DateType) { + return gerror.New("宵禁日期类型不合法") + } + if !dict.HasOptionKey(consts.ImCurfewScopeOptions, in.Scope) { + return gerror.New("宵禁范围不合法") + } + if len(in.StartTime) != 5 || len(in.EndTime) != 5 { + return gerror.New("宵禁时间必须使用HH:mm格式") + } + if _, err := time.Parse("15:04", in.StartTime); err != nil { + return gerror.New("宵禁开始时间不合法") + } + if _, err := time.Parse("15:04", in.EndTime); err != nil { + return gerror.New("宵禁结束时间不合法") + } + if in.Timezone == "" { + in.Timezone = "Asia/Shanghai" + } + if in.Message == "" { + in.Message = "当前时段暂不能发送消息" + } + if in.Status == 0 { + in.Status = consts.StatusEnabled + } + if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable { + return gerror.New("宵禁规则状态不合法") + } + return nil +} + +type ImSecurityPolicySaveInp struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + PolicyName string `json:"policyName" v:"required#策略名称不能为空"` + PasswordPolicy *gjson.Json `json:"passwordPolicy"` + LoginRateLimit *gjson.Json `json:"loginRateLimit"` + SensitiveWordPolicy *gjson.Json `json:"sensitiveWordPolicy"` + FileReviewPolicy *gjson.Json `json:"fileReviewPolicy"` + RealnamePolicy *gjson.Json `json:"realnamePolicy"` + RiskChallengePolicy *gjson.Json `json:"riskChallengePolicy"` + GlobalFriendEnabled int `json:"globalFriendEnabled"` + FriendDisabledPolicy *gjson.Json `json:"friendDisabledPolicy"` + MessageCurfewEnabled int `json:"messageCurfewEnabled"` + Remark string `json:"remark"` + CurfewRules []*ImMessageCurfewRuleInp `json:"curfewRules"` +} + +func (in *ImSecurityPolicySaveInp) Filter(ctx context.Context) error { + in.PolicyName = strings.TrimSpace(in.PolicyName) + in.Remark = strings.TrimSpace(in.Remark) + if in.PolicyName == "" || len([]rune(in.PolicyName)) > 128 { + return gerror.New("策略名称长度必须为1至128个字符") + } + if in.GlobalFriendEnabled != 0 && in.GlobalFriendEnabled != 1 { + return gerror.New("全局好友开关不合法") + } + if in.MessageCurfewEnabled != 0 && in.MessageCurfewEnabled != 1 { + return gerror.New("宵禁开关不合法") + } + if in.GlobalFriendEnabled == 0 { + policy := make(map[string]interface{}) + if in.FriendDisabledPolicy != nil { + policy = in.FriendDisabledPolicy.Map() + } + policy["hide_profile"] = true + policy["block_qrcode"] = true + policy["block_group_member_entry"] = true + policy["blocked_entries"] = []string{ + "search", "profile_card", "group_member", "qrcode", "invite_auto_add", "recommendation", + } + message, ok := policy["message"].(string) + if !ok || strings.TrimSpace(message) == "" { + policy["message"] = "当前时段暂不允许添加好友" + } + in.FriendDisabledPolicy = gjson.New(policy) + } + if in.MessageCurfewEnabled == 1 && len(in.CurfewRules) == 0 { + return gerror.New("启用宵禁时至少配置一条宵禁规则") + } + seen := make(map[string]struct{}, len(in.CurfewRules)) + hasPrivateMessageRule := false + for _, rule := range in.CurfewRules { + if rule == nil { + return gerror.New("宵禁规则不能为空") + } + if err := rule.Filter(ctx); err != nil { + return err + } + if _, ok := seen[rule.RuleCode]; ok { + return gerror.New("宵禁规则编码不能重复") + } + seen[rule.RuleCode] = struct{}{} + if rule.Scope == consts.ImCurfewScopePrivate && rule.Status == consts.StatusEnabled { + hasPrivateMessageRule = true + } + } + if in.MessageCurfewEnabled == 1 && !hasPrivateMessageRule { + return gerror.New("启用宵禁时至少配置一条启用的单聊/私聊规则") + } + return nil +} + +type ImSecurityPolicyPublishInp struct { + Id int64 `json:"id" v:"required|min:1#策略ID不能为空|策略ID不合法"` + Reason string `json:"reason" v:"required#发布原因不能为空"` +} + +func (in *ImSecurityPolicyPublishInp) Filter(ctx context.Context) error { + in.Reason = strings.TrimSpace(in.Reason) + if in.Id <= 0 { + return gerror.New("策略ID不合法") + } + if in.Reason == "" { + return gerror.New("发布原因不能为空") + } + if len([]rune(in.Reason)) > 500 { + return gerror.New("发布原因不能超过500个字符") + } + return nil +} + +type ImSecurityPolicyRestoreInp struct { + TenantId int64 `json:"tenantId"` + Reason string `json:"reason" v:"required#恢复原因不能为空"` +} + +func (in *ImSecurityPolicyRestoreInp) Filter(ctx context.Context) error { + in.Reason = strings.TrimSpace(in.Reason) + if in.TenantId < 0 { + return gerror.New("租户ID不合法") + } + if in.Reason == "" { + return gerror.New("恢复原因不能为空") + } + if len([]rune(in.Reason)) > 500 { + return gerror.New("恢复原因不能超过500个字符") + } + return nil +} + +type ImSecurityIPRuleListInp struct { + form.PageReq + TenantId int64 `json:"tenantId"` + RuleType string `json:"ruleType"` + IpCidr string `json:"ipCidr"` + Status int `json:"status"` +} + +func (in *ImSecurityIPRuleListInp) Filter(ctx context.Context) error { + in.IpCidr = strings.TrimSpace(in.IpCidr) + if in.RuleType != "" && in.RuleType != "whitelist" && in.RuleType != "blacklist" { + return gerror.New("IP规则类型不合法") + } + return nil +} + +type ImSecurityIPRuleModel struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + RuleType string `json:"ruleType"` + IpCidr string `json:"ipCidr"` + Action string `json:"action"` + SceneJson string `json:"sceneJson"` + RiskLevel string `json:"riskLevel"` + Status int `json:"status"` + ExpiresAt *gtime.Time `json:"expiresAt"` + Remark string `json:"remark"` + CreatedAt *gtime.Time `json:"createdAt"` + UpdatedAt *gtime.Time `json:"updatedAt"` +} +type ImSecurityIPRuleEditInp struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + RuleType string `json:"ruleType"` + IpCidr string `json:"ipCidr"` + Action string `json:"action"` + SceneJson *gjson.Json `json:"sceneJson"` + RiskLevel string `json:"riskLevel"` + Status int `json:"status"` + ExpiresAt *gtime.Time `json:"expiresAt"` + Remark string `json:"remark"` +} + +func (in *ImSecurityIPRuleEditInp) Filter(ctx context.Context) error { + in.IpCidr = strings.TrimSpace(in.IpCidr) + if in.RuleType != "whitelist" && in.RuleType != "blacklist" { + return gerror.New("IP规则类型不合法") + } + if in.IpCidr == "" { + return gerror.New("IP或CIDR不能为空") + } + if !dict.HasOptionKey(consts.ImSecurityActionOptions, in.Action) { + return gerror.New("规则动作不合法") + } + if !dict.HasOptionKey(consts.ImRiskLevelOptions, in.RiskLevel) { + return gerror.New("风险等级不合法") + } + if in.Status == 0 { + in.Status = consts.StatusEnabled + } + if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable { + return gerror.New("状态不合法") + } + if in.SceneJson == nil || in.SceneJson.String() == "" || in.SceneJson.String() == "null" { + return gerror.New("生效场景不能为空") + } + return nil +} + +type ImSecurityIPRuleDeleteInp struct { + Id int64 `json:"id" v:"required|min:1#IP规则ID不能为空|IP规则ID不合法"` +} + +func (in *ImSecurityIPRuleDeleteInp) Filter(ctx context.Context) error { return nil } diff --git a/server/internal/model/input/sysin/im_sensitive_word.go b/server/internal/model/input/sysin/im_sensitive_word.go new file mode 100644 index 0000000..f13908d --- /dev/null +++ b/server/internal/model/input/sysin/im_sensitive_word.go @@ -0,0 +1,190 @@ +package sysin + +import ( + "context" + "strings" + + "hotgo/internal/consts" + "hotgo/internal/library/dict" + "hotgo/internal/model/input/form" + + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" +) + +type ImSensitiveWordListInp struct { + form.PageReq + TenantId int64 `json:"tenantId"` + GroupId int64 `json:"groupId"` + Word string `json:"word"` + MatchType string `json:"matchType"` + Action string `json:"action"` + RiskLevel string `json:"riskLevel"` + Status int `json:"status"` +} + +func (in *ImSensitiveWordListInp) Filter(ctx context.Context) error { + in.Word = strings.TrimSpace(in.Word) + if in.MatchType != "" && !dict.HasOptionKey(consts.ImSensitiveMatchTypeOptions, in.MatchType) { + return gerror.New("匹配类型不合法") + } + if in.Action != "" && !dict.HasOptionKey(consts.ImSensitiveActionOptions, in.Action) { + return gerror.New("命中动作不合法") + } + if in.RiskLevel != "" && !dict.HasOptionKey(consts.ImRiskLevelOptions, in.RiskLevel) { + return gerror.New("风险等级不合法") + } + return nil +} + +type ImSensitiveWordListModel struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + GroupId int64 `json:"groupId"` + GroupName string `json:"groupName"` + Word string `json:"word"` + MatchType string `json:"matchType"` + SceneJson string `json:"sceneJson"` + Action string `json:"action"` + Replacement string `json:"replacement"` + RiskLevel string `json:"riskLevel"` + Priority int `json:"priority"` + Status int `json:"status"` + Remark string `json:"remark"` + CreatedAt *gtime.Time `json:"createdAt"` + UpdatedAt *gtime.Time `json:"updatedAt"` +} + +type ImSensitiveWordEditInp struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + GroupId int64 `json:"groupId" v:"required|min:1#敏感词分组不能为空|敏感词分组不合法"` + Word string `json:"word" v:"required#敏感词不能为空"` + MatchType string `json:"matchType"` + SceneJson *gjson.Json `json:"sceneJson" v:"required#生效场景不能为空"` + Action string `json:"action"` + Replacement string `json:"replacement"` + RiskLevel string `json:"riskLevel"` + Priority int `json:"priority"` + Status int `json:"status"` + Remark string `json:"remark"` +} + +func (in *ImSensitiveWordEditInp) Filter(ctx context.Context) error { + in.Word = strings.TrimSpace(in.Word) + in.Replacement = strings.TrimSpace(in.Replacement) + in.Remark = strings.TrimSpace(in.Remark) + if in.Word == "" || len([]rune(in.Word)) > 255 { + return gerror.New("敏感词长度必须为1至255个字符") + } + if !dict.HasOptionKey(consts.ImSensitiveMatchTypeOptions, in.MatchType) { + return gerror.New("匹配类型不合法") + } + if !dict.HasOptionKey(consts.ImSensitiveActionOptions, in.Action) { + return gerror.New("命中动作不合法") + } + if !dict.HasOptionKey(consts.ImRiskLevelOptions, in.RiskLevel) { + return gerror.New("风险等级不合法") + } + if in.Status == 0 { + in.Status = consts.StatusEnabled + } + if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable { + return gerror.New("状态不合法") + } + if in.SceneJson == nil || in.SceneJson.String() == "" || in.SceneJson.String() == "null" { + return gerror.New("生效场景不能为空") + } + if in.Action == consts.ImSensitiveActionReplace && in.Replacement == "" { + return gerror.New("替换动作必须填写替换文本") + } + return nil +} + +type ImSensitiveWordDeleteInp struct { + Id int64 `json:"id" v:"required|min:1#敏感词ID不能为空|敏感词ID不合法"` +} + +func (in *ImSensitiveWordDeleteInp) Filter(ctx context.Context) error { return nil } + +type ImSensitiveWordStatusInp struct { + Id int64 `json:"id" v:"required|min:1#敏感词ID不能为空|敏感词ID不合法"` + Status int `json:"status" v:"required#状态不能为空"` +} + +func (in *ImSensitiveWordStatusInp) Filter(ctx context.Context) error { + if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable { + return gerror.New("状态不合法") + } + return nil +} + +type ImSensitiveWordBatchImportInp struct { + TenantId int64 `json:"tenantId"` + GroupId int64 `json:"groupId" v:"required|min:1#敏感词分组不能为空|敏感词分组不合法"` + Words []string `json:"words" v:"required#敏感词列表不能为空"` + MatchType string `json:"matchType"` + SceneJson *gjson.Json `json:"sceneJson"` + Action string `json:"action"` + Replacement string `json:"replacement"` + RiskLevel string `json:"riskLevel"` +} + +func (in *ImSensitiveWordBatchImportInp) Filter(ctx context.Context) error { + if len(in.Words) == 0 || len(in.Words) > 5000 { + return gerror.New("每次导入1至5000个敏感词") + } + base := ImSensitiveWordEditInp{GroupId: in.GroupId, Word: "validate", MatchType: in.MatchType, SceneJson: in.SceneJson, Action: in.Action, Replacement: in.Replacement, RiskLevel: in.RiskLevel, Status: consts.StatusEnabled} + return base.Filter(ctx) +} + +type ImSensitiveWordBatchImportModel struct { + Inserted int `json:"inserted"` + Skipped int `json:"skipped"` +} + +type ImSensitiveWordGroupListInp struct { + TenantId int64 `json:"tenantId"` +} + +func (in *ImSensitiveWordGroupListInp) Filter(ctx context.Context) error { return nil } + +type ImSensitiveWordGroupModel struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + GroupCode string `json:"groupCode"` + GroupName string `json:"groupName"` + Priority int `json:"priority"` + Status int `json:"status"` + Remark string `json:"remark"` + CreatedAt *gtime.Time `json:"createdAt"` +} +type ImSensitiveWordGroupEditInp struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + GroupCode string `json:"groupCode" v:"required#分组编码不能为空"` + GroupName string `json:"groupName" v:"required#分组名称不能为空"` + Priority int `json:"priority"` + Status int `json:"status"` + Remark string `json:"remark"` +} + +func (in *ImSensitiveWordGroupEditInp) Filter(ctx context.Context) error { + in.GroupCode = strings.TrimSpace(in.GroupCode) + in.GroupName = strings.TrimSpace(in.GroupName) + in.Remark = strings.TrimSpace(in.Remark) + if !imPolicyGroupCodePattern.MatchString(in.GroupCode) { + return gerror.New("分组编码格式不合法") + } + if in.GroupName == "" || len([]rune(in.GroupName)) > 128 { + return gerror.New("分组名称长度必须为1至128个字符") + } + if in.Status == 0 { + in.Status = consts.StatusEnabled + } + if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable { + return gerror.New("状态不合法") + } + return nil +} diff --git a/server/internal/model/input/sysin/im_user_policy_group.go b/server/internal/model/input/sysin/im_user_policy_group.go new file mode 100644 index 0000000..6fb35cd --- /dev/null +++ b/server/internal/model/input/sysin/im_user_policy_group.go @@ -0,0 +1,157 @@ +package sysin + +import ( + "context" + "regexp" + "strings" + + "hotgo/internal/consts" + "hotgo/internal/model/input/form" + + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" +) + +var imPolicyGroupCodePattern = regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_-]{1,63}$`) + +type ImUserPolicyGroupListInp struct { + form.PageReq + TenantId int64 `json:"tenantId" dc:"租户ID,0为全局默认"` + Keyword string `json:"keyword" dc:"编码或名称"` + Status int `json:"status" dc:"状态"` +} + +func (in *ImUserPolicyGroupListInp) Filter(ctx context.Context) error { + in.Keyword = strings.TrimSpace(in.Keyword) + if in.Status != 0 && in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable { + return gerror.New("状态不合法") + } + return nil +} + +type ImUserPolicyGroupListModel struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId"` + GroupCode string `json:"groupCode"` + GroupName string `json:"groupName"` + Priority int `json:"priority"` + Status int `json:"status"` + PolicyJson string `json:"policyJson"` + IpWhitelist string `json:"ipWhitelist"` + IpBlacklist string `json:"ipBlacklist"` + Version uint `json:"version"` + Remark string `json:"remark"` + MemberCount int `json:"memberCount"` + CreatedAt *gtime.Time `json:"createdAt"` + UpdatedAt *gtime.Time `json:"updatedAt"` +} + +type ImUserPolicyGroupViewInp struct { + Id int64 `json:"id" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"` +} + +func (in *ImUserPolicyGroupViewInp) Filter(ctx context.Context) error { return nil } + +type ImUserPolicyGroupViewModel struct{ ImUserPolicyGroupListModel } + +type ImUserPolicyGroupEditInp struct { + Id int64 `json:"id"` + TenantId int64 `json:"tenantId" dc:"租户ID,0为全局默认"` + GroupCode string `json:"groupCode" v:"required#分组编码不能为空"` + GroupName string `json:"groupName" v:"required#分组名称不能为空"` + Priority int `json:"priority"` + Status int `json:"status"` + PolicyJson *gjson.Json `json:"policyJson" v:"required#策略配置不能为空"` + IpWhitelist *gjson.Json `json:"ipWhitelist"` + IpBlacklist *gjson.Json `json:"ipBlacklist"` + Remark string `json:"remark"` +} + +func (in *ImUserPolicyGroupEditInp) Filter(ctx context.Context) error { + in.GroupCode = strings.TrimSpace(in.GroupCode) + in.GroupName = strings.TrimSpace(in.GroupName) + in.Remark = strings.TrimSpace(in.Remark) + if !imPolicyGroupCodePattern.MatchString(in.GroupCode) { + return gerror.New("分组编码必须以字母开头,只能包含字母、数字、下划线和中划线") + } + if in.GroupName == "" || len([]rune(in.GroupName)) > 128 { + return gerror.New("分组名称长度必须为1至128个字符") + } + if in.Status == 0 { + in.Status = consts.StatusEnabled + } + if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable { + return gerror.New("状态不合法") + } + if in.PolicyJson == nil || in.PolicyJson.String() == "null" { + return gerror.New("策略配置不能为空") + } + return nil +} + +type ImUserPolicyGroupDeleteInp struct { + Id int64 `json:"id" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"` +} + +func (in *ImUserPolicyGroupDeleteInp) Filter(ctx context.Context) error { return nil } + +type ImUserPolicyGroupStatusInp struct { + Id int64 `json:"id" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"` + Status int `json:"status" v:"required#状态不能为空"` +} + +func (in *ImUserPolicyGroupStatusInp) Filter(ctx context.Context) error { + if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable { + return gerror.New("状态不合法") + } + return nil +} + +type ImUserPolicyGroupMemberListInp struct { + form.PageReq + GroupId int64 `json:"groupId" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"` + UserId int64 `json:"userId"` +} + +func (in *ImUserPolicyGroupMemberListInp) Filter(ctx context.Context) error { return nil } + +type ImUserPolicyGroupMemberModel struct { + Id int64 `json:"id"` + GroupId int64 `json:"groupId"` + TenantId int64 `json:"tenantId"` + UserId int64 `json:"userId"` + Status int `json:"status"` + ValidFrom *gtime.Time `json:"validFrom"` + ValidUntil *gtime.Time `json:"validUntil"` + Remark string `json:"remark"` + CreatedAt *gtime.Time `json:"createdAt"` +} + +type ImUserPolicyGroupMemberAddInp struct { + GroupId int64 `json:"groupId" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"` + UserId int64 `json:"userId" v:"required|min:1#用户ID不能为空|用户ID不合法"` + ValidFrom *gtime.Time `json:"validFrom"` + ValidUntil *gtime.Time `json:"validUntil"` + Remark string `json:"remark"` +} + +func (in *ImUserPolicyGroupMemberAddInp) Filter(ctx context.Context) error { + in.Remark = strings.TrimSpace(in.Remark) + if in.GroupId <= 0 { + return gerror.New("策略分组ID不合法") + } + if in.UserId <= 0 { + return gerror.New("用户ID不合法") + } + if in.ValidFrom != nil && in.ValidUntil != nil && in.ValidUntil.Before(in.ValidFrom) { + return gerror.New("有效结束时间不能早于开始时间") + } + return nil +} + +type ImUserPolicyGroupMemberRemoveInp struct { + Id int64 `json:"id" v:"required|min:1#成员关系ID不能为空|成员关系ID不合法"` +} + +func (in *ImUserPolicyGroupMemberRemoveInp) Filter(ctx context.Context) error { return nil } diff --git a/server/internal/router/genrouter/im_dashboard.go b/server/internal/router/genrouter/im_dashboard.go new file mode 100644 index 0000000..d5aa19a --- /dev/null +++ b/server/internal/router/genrouter/im_dashboard.go @@ -0,0 +1,5 @@ +package genrouter + +import "hotgo/internal/controller/admin/sys" + +func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImDashboard) } diff --git a/server/internal/router/genrouter/im_group_message.go b/server/internal/router/genrouter/im_group_message.go new file mode 100644 index 0000000..956c32a --- /dev/null +++ b/server/internal/router/genrouter/im_group_message.go @@ -0,0 +1,5 @@ +package genrouter + +import "hotgo/internal/controller/admin/sys" + +func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImGroupMessage) } diff --git a/server/internal/router/genrouter/im_login_failure_log.go b/server/internal/router/genrouter/im_login_failure_log.go new file mode 100644 index 0000000..69c8d31 --- /dev/null +++ b/server/internal/router/genrouter/im_login_failure_log.go @@ -0,0 +1,5 @@ +package genrouter + +import "hotgo/internal/controller/admin/sys" + +func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImLoginFailureLog) } diff --git a/server/internal/router/genrouter/im_private_message.go b/server/internal/router/genrouter/im_private_message.go new file mode 100644 index 0000000..c3827ff --- /dev/null +++ b/server/internal/router/genrouter/im_private_message.go @@ -0,0 +1,5 @@ +package genrouter + +import "hotgo/internal/controller/admin/sys" + +func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImPrivateMessage) } diff --git a/server/internal/router/genrouter/im_security_policy.go b/server/internal/router/genrouter/im_security_policy.go new file mode 100644 index 0000000..8dcb15d --- /dev/null +++ b/server/internal/router/genrouter/im_security_policy.go @@ -0,0 +1,5 @@ +package genrouter + +import "hotgo/internal/controller/admin/sys" + +func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImSecurityPolicy) } diff --git a/server/internal/router/genrouter/im_sensitive_word.go b/server/internal/router/genrouter/im_sensitive_word.go new file mode 100644 index 0000000..d40be89 --- /dev/null +++ b/server/internal/router/genrouter/im_sensitive_word.go @@ -0,0 +1,5 @@ +package genrouter + +import "hotgo/internal/controller/admin/sys" + +func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImSensitiveWord) } diff --git a/server/internal/router/genrouter/im_user_login_history.go b/server/internal/router/genrouter/im_user_login_history.go new file mode 100644 index 0000000..6940376 --- /dev/null +++ b/server/internal/router/genrouter/im_user_login_history.go @@ -0,0 +1,5 @@ +package genrouter + +import "hotgo/internal/controller/admin/sys" + +func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImUserLoginHistory) } diff --git a/server/internal/router/genrouter/im_user_policy_group.go b/server/internal/router/genrouter/im_user_policy_group.go new file mode 100644 index 0000000..1ba01b7 --- /dev/null +++ b/server/internal/router/genrouter/im_user_policy_group.go @@ -0,0 +1,5 @@ +package genrouter + +import "hotgo/internal/controller/admin/sys" + +func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImUserPolicyGroup) } diff --git a/server/internal/service/sys.go b/server/internal/service/sys.go index b79497d..6f55bbc 100644 --- a/server/internal/service/sys.go +++ b/server/internal/service/sys.go @@ -359,6 +359,64 @@ type ( // Update 更新IM文件策略 Update(ctx context.Context, in *sysin.ImFilePolicyUpdateInp) (err error) } + ISysImUserPolicyGroup interface { + List(ctx context.Context, in *sysin.ImUserPolicyGroupListInp) (list []*sysin.ImUserPolicyGroupListModel, totalCount int, err error) + View(ctx context.Context, in *sysin.ImUserPolicyGroupViewInp) (res *sysin.ImUserPolicyGroupViewModel, err error) + Edit(ctx context.Context, in *sysin.ImUserPolicyGroupEditInp) (err error) + Delete(ctx context.Context, in *sysin.ImUserPolicyGroupDeleteInp) (err error) + Status(ctx context.Context, in *sysin.ImUserPolicyGroupStatusInp) (err error) + MemberList(ctx context.Context, in *sysin.ImUserPolicyGroupMemberListInp) (list []*sysin.ImUserPolicyGroupMemberModel, totalCount int, err error) + MemberAdd(ctx context.Context, in *sysin.ImUserPolicyGroupMemberAddInp) (err error) + MemberRemove(ctx context.Context, in *sysin.ImUserPolicyGroupMemberRemoveInp) (err error) + } + ISysImSensitiveWord interface { + List(ctx context.Context, in *sysin.ImSensitiveWordListInp) (list []*sysin.ImSensitiveWordListModel, totalCount int, err error) + Edit(ctx context.Context, in *sysin.ImSensitiveWordEditInp) (err error) + Delete(ctx context.Context, in *sysin.ImSensitiveWordDeleteInp) (err error) + Status(ctx context.Context, in *sysin.ImSensitiveWordStatusInp) (err error) + BatchImport(ctx context.Context, in *sysin.ImSensitiveWordBatchImportInp) (res *sysin.ImSensitiveWordBatchImportModel, err error) + GroupList(ctx context.Context, in *sysin.ImSensitiveWordGroupListInp) (list []*sysin.ImSensitiveWordGroupModel, err error) + GroupEdit(ctx context.Context, in *sysin.ImSensitiveWordGroupEditInp) (err error) + } + ISysImSecurityPolicy interface { + List(ctx context.Context, in *sysin.ImSecurityPolicyListInp) (list []*sysin.ImSecurityPolicyModel, totalCount int, err error) + View(ctx context.Context, in *sysin.ImSecurityPolicyViewInp) (res *sysin.ImSecurityPolicyModel, err error) + Save(ctx context.Context, in *sysin.ImSecurityPolicySaveInp) (id int64, err error) + Publish(ctx context.Context, in *sysin.ImSecurityPolicyPublishInp) (err error) + RestoreDefault(ctx context.Context, in *sysin.ImSecurityPolicyRestoreInp) (id int64, err error) + IPRuleList(ctx context.Context, in *sysin.ImSecurityIPRuleListInp) (list []*sysin.ImSecurityIPRuleModel, totalCount int, err error) + IPRuleEdit(ctx context.Context, in *sysin.ImSecurityIPRuleEditInp) (err error) + IPRuleDelete(ctx context.Context, in *sysin.ImSecurityIPRuleDeleteInp) (err error) + } + ISysImDashboard interface { + Overview(ctx context.Context, in *sysin.ImDashboardOverviewInp) (res *sysin.ImDashboardOverviewModel, err error) + Trends(ctx context.Context, in *sysin.ImDashboardTrendsInp) (list []*sysin.ImDashboardTrendModel, err error) + } + ISysImPrivateMessage interface { + List(ctx context.Context, in *sysin.ImPrivateMessageListInp) (list []*sysin.ImMessageListModel, totalCount int, err error) + View(ctx context.Context, in *sysin.ImMessageViewInp) (res *sysin.ImMessageViewModel, err error) + Hide(ctx context.Context, in *sysin.ImMessageActionInp) (res *sysin.ImMessageCommandModel, err error) + Delete(ctx context.Context, in *sysin.ImMessageActionInp) (res *sysin.ImMessageCommandModel, err error) + Export(ctx context.Context, in *sysin.ImPrivateMessageListInp) (err error) + } + ISysImGroupMessage interface { + List(ctx context.Context, in *sysin.ImGroupMessageListInp) (list []*sysin.ImMessageListModel, totalCount int, err error) + View(ctx context.Context, in *sysin.ImMessageViewInp) (res *sysin.ImMessageViewModel, err error) + Hide(ctx context.Context, in *sysin.ImMessageActionInp) (res *sysin.ImMessageCommandModel, err error) + Delete(ctx context.Context, in *sysin.ImMessageActionInp) (res *sysin.ImMessageCommandModel, err error) + Export(ctx context.Context, in *sysin.ImGroupMessageListInp) (err error) + } + ISysImUserLoginHistory interface { + List(ctx context.Context, in *sysin.ImUserLoginHistoryListInp) (list []*sysin.ImUserLoginHistoryModel, totalCount int, err error) + Export(ctx context.Context, in *sysin.ImUserLoginHistoryListInp) (err error) + } + ISysImLoginFailureLog interface { + List(ctx context.Context, in *sysin.ImLoginFailureLogListInp) (list []*sysin.ImLoginFailureLogModel, totalCount int, err error) + View(ctx context.Context, in *sysin.ImLoginFailureViewInp) (res *sysin.ImLoginFailureLogModel, err error) + Export(ctx context.Context, in *sysin.ImLoginFailureLogListInp) (err error) + AddBlacklist(ctx context.Context, in *sysin.ImLoginFailureAddBlacklistInp) (err error) + BanUser(ctx context.Context, in *sysin.ImLoginFailureBanUserInp) (res *sysin.ImUserCommandModel, err error) + } ISysImExternalConfig interface { // List 获取IM外部服务配置列表 List(ctx context.Context, in *sysin.ImExternalConfigListInp) (list []*sysin.ImExternalConfigListModel, totalCount int, err error) @@ -686,50 +744,58 @@ type ( ) var ( - localSysAddons ISysAddons - localSysAddonsConfig ISysAddonsConfig - localSysAttachment ISysAttachment - localSysBlacklist ISysBlacklist - localSysConfig ISysConfig - localSysCron ISysCron - localSysCronGroup ISysCronGroup - localSysCurdDemo ISysCurdDemo - localSysImTenant ISysImTenant - localSysImRegistration ISysImRegistration - localSysImInvite ISysImInvite - localSysImUser ISysImUser - localSysImGroup ISysImGroup - localSysImRealname ISysImRealname - localSysImWorkOrder ISysImWorkOrder - localSysImOutbox ISysImOutbox - localSysImOrg ISysImOrg - localSysImFile ISysImFile - localSysImFilePolicy ISysImFilePolicy - localSysImExternalConfig ISysImExternalConfig - localSysImNotification ISysImNotification - localSysImAppRelease ISysImAppRelease - localSysImAbuseReason ISysImAbuseReason - localSysImMailboxConfig ISysImMailboxConfig - localSysImFeedbackConfig ISysImFeedbackConfig - localSysImWorkbench ISysImWorkbench - localSysImTaskDashboard ISysImTaskDashboard - localSysImAuditLog ISysImAuditLog - localSysImKafkaAudit ISysImKafkaAudit - localSysImKafkaCommand ISysImKafkaCommand - localSysImDeadLetter ISysImDeadLetter - localSysDictData ISysDictData - localSysDictType ISysDictType - localSysEmsLog ISysEmsLog - localSysGenCodes ISysGenCodes - localSysLog ISysLog - localSysLoginLog ISysLoginLog - localSysNormalTreeDemo ISysNormalTreeDemo - localSysOptionTreeDemo ISysOptionTreeDemo - localSysProvinces ISysProvinces - localSysServeLicense ISysServeLicense - localSysServeLog ISysServeLog - localSysSmsLog ISysSmsLog - localSysTestCategory ISysTestCategory + localSysAddons ISysAddons + localSysAddonsConfig ISysAddonsConfig + localSysAttachment ISysAttachment + localSysBlacklist ISysBlacklist + localSysConfig ISysConfig + localSysCron ISysCron + localSysCronGroup ISysCronGroup + localSysCurdDemo ISysCurdDemo + localSysImTenant ISysImTenant + localSysImRegistration ISysImRegistration + localSysImInvite ISysImInvite + localSysImUser ISysImUser + localSysImGroup ISysImGroup + localSysImRealname ISysImRealname + localSysImWorkOrder ISysImWorkOrder + localSysImOutbox ISysImOutbox + localSysImOrg ISysImOrg + localSysImFile ISysImFile + localSysImFilePolicy ISysImFilePolicy + localSysImUserPolicyGroup ISysImUserPolicyGroup + localSysImSensitiveWord ISysImSensitiveWord + localSysImSecurityPolicy ISysImSecurityPolicy + localSysImDashboard ISysImDashboard + localSysImPrivateMessage ISysImPrivateMessage + localSysImGroupMessage ISysImGroupMessage + localSysImUserLoginHistory ISysImUserLoginHistory + localSysImLoginFailureLog ISysImLoginFailureLog + localSysImExternalConfig ISysImExternalConfig + localSysImNotification ISysImNotification + localSysImAppRelease ISysImAppRelease + localSysImAbuseReason ISysImAbuseReason + localSysImMailboxConfig ISysImMailboxConfig + localSysImFeedbackConfig ISysImFeedbackConfig + localSysImWorkbench ISysImWorkbench + localSysImTaskDashboard ISysImTaskDashboard + localSysImAuditLog ISysImAuditLog + localSysImKafkaAudit ISysImKafkaAudit + localSysImKafkaCommand ISysImKafkaCommand + localSysImDeadLetter ISysImDeadLetter + localSysDictData ISysDictData + localSysDictType ISysDictType + localSysEmsLog ISysEmsLog + localSysGenCodes ISysGenCodes + localSysLog ISysLog + localSysLoginLog ISysLoginLog + localSysNormalTreeDemo ISysNormalTreeDemo + localSysOptionTreeDemo ISysOptionTreeDemo + localSysProvinces ISysProvinces + localSysServeLicense ISysServeLicense + localSysServeLog ISysServeLog + localSysSmsLog ISysSmsLog + localSysTestCategory ISysTestCategory ) func SysAddons() ISysAddons { @@ -941,6 +1007,78 @@ func RegisterSysImFilePolicy(i ISysImFilePolicy) { localSysImFilePolicy = i } +func SysImUserPolicyGroup() ISysImUserPolicyGroup { + if localSysImUserPolicyGroup == nil { + panic("implement not found for interface ISysImUserPolicyGroup, forgot register?") + } + return localSysImUserPolicyGroup +} + +func RegisterSysImUserPolicyGroup(i ISysImUserPolicyGroup) { localSysImUserPolicyGroup = i } + +func SysImSensitiveWord() ISysImSensitiveWord { + if localSysImSensitiveWord == nil { + panic("implement not found for interface ISysImSensitiveWord, forgot register?") + } + return localSysImSensitiveWord +} + +func RegisterSysImSensitiveWord(i ISysImSensitiveWord) { localSysImSensitiveWord = i } + +func SysImSecurityPolicy() ISysImSecurityPolicy { + if localSysImSecurityPolicy == nil { + panic("implement not found for interface ISysImSecurityPolicy, forgot register?") + } + return localSysImSecurityPolicy +} + +func RegisterSysImSecurityPolicy(i ISysImSecurityPolicy) { localSysImSecurityPolicy = i } + +func SysImDashboard() ISysImDashboard { + if localSysImDashboard == nil { + panic("implement not found for interface ISysImDashboard, forgot register?") + } + return localSysImDashboard +} + +func RegisterSysImDashboard(i ISysImDashboard) { localSysImDashboard = i } + +func SysImPrivateMessage() ISysImPrivateMessage { + if localSysImPrivateMessage == nil { + panic("implement not found for interface ISysImPrivateMessage, forgot register?") + } + return localSysImPrivateMessage +} + +func RegisterSysImPrivateMessage(i ISysImPrivateMessage) { localSysImPrivateMessage = i } + +func SysImGroupMessage() ISysImGroupMessage { + if localSysImGroupMessage == nil { + panic("implement not found for interface ISysImGroupMessage, forgot register?") + } + return localSysImGroupMessage +} + +func RegisterSysImGroupMessage(i ISysImGroupMessage) { localSysImGroupMessage = i } + +func SysImUserLoginHistory() ISysImUserLoginHistory { + if localSysImUserLoginHistory == nil { + panic("implement not found for interface ISysImUserLoginHistory, forgot register?") + } + return localSysImUserLoginHistory +} + +func RegisterSysImUserLoginHistory(i ISysImUserLoginHistory) { localSysImUserLoginHistory = i } + +func SysImLoginFailureLog() ISysImLoginFailureLog { + if localSysImLoginFailureLog == nil { + panic("implement not found for interface ISysImLoginFailureLog, forgot register?") + } + return localSysImLoginFailureLog +} + +func RegisterSysImLoginFailureLog(i ISysImLoginFailureLog) { localSysImLoginFailureLog = i } + func SysImExternalConfig() ISysImExternalConfig { if localSysImExternalConfig == nil { panic("implement not found for interface ISysImExternalConfig, forgot register?") diff --git a/server/storage/data/generate/im_adfahi_batch2_menu.sql b/server/storage/data/generate/im_adfahi_batch2_menu.sql new file mode 100644 index 0000000..eba9167 --- /dev/null +++ b/server/storage/data/generate/im_adfahi_batch2_menu.sql @@ -0,0 +1,38 @@ +SET @now := NOW(); +SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1); + +INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`) +SELECT NULL,@imRootId,p.title,p.name,p.path,'','2','',p.permissions,'',p.component,'1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),p.sort,'','1',@now,@now +FROM ( + SELECT '数据概览' title,'imDashboardIndex' name,'dashboard/index' path,'/imDashboard/overview' permissions,'/imDashboard/index' component,5 sort UNION ALL + SELECT '单聊消息','imPrivateMessageIndex','private-message/index','/imPrivateMessage/list','/imPrivateMessage/index',40 UNION ALL + SELECT '群聊消息','imGroupMessageIndex','group-message/index','/imGroupMessage/list','/imGroupMessage/index',45 UNION ALL + SELECT '用户登录历史','imUserLoginHistoryIndex','user-login-history/index','/imUserLoginHistory/list','/imUserLoginHistory/index',50 UNION ALL + SELECT '登录失败日志','imLoginFailureLogIndex','login-failure-log/index','/imLoginFailureLog/list','/imLoginFailureLog/index',55 +) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name); + +SET @dashboardId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imDashboardIndex' LIMIT 1); +SET @privateMessageId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imPrivateMessageIndex' LIMIT 1); +SET @groupMessageId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imGroupMessageIndex' LIMIT 1); +SET @userLoginId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imUserLoginHistoryIndex' LIMIT 1); +SET @loginFailureId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imLoginFailureLogIndex' LIMIT 1); + +INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`) +SELECT NULL,x.pid,x.title,x.name,'','','3','',x.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',x.pid,' '),x.sort,'','1',@now,@now +FROM ( + SELECT @dashboardId pid,'查看概览' title,'imDashboardOverview' name,'/imDashboard/overview' permissions,10 sort UNION ALL + SELECT @dashboardId,'查看趋势','imDashboardTrends','/imDashboard/trends',20 UNION ALL + SELECT @privateMessageId,'消息详情','imPrivateMessageView','/imPrivateMessage/view',10 UNION ALL + SELECT @privateMessageId,'隐藏消息','imPrivateMessageHide','/imPrivateMessage/hide',20 UNION ALL + SELECT @privateMessageId,'删除消息','imPrivateMessageDelete','/imPrivateMessage/delete',30 UNION ALL + SELECT @privateMessageId,'导出消息','imPrivateMessageExport','/imPrivateMessage/export',40 UNION ALL + SELECT @groupMessageId,'消息详情','imGroupMessageView','/imGroupMessage/view',10 UNION ALL + SELECT @groupMessageId,'隐藏消息','imGroupMessageHide','/imGroupMessage/hide',20 UNION ALL + SELECT @groupMessageId,'删除消息','imGroupMessageDelete','/imGroupMessage/delete',30 UNION ALL + SELECT @groupMessageId,'导出消息','imGroupMessageExport','/imGroupMessage/export',40 UNION ALL + SELECT @userLoginId,'导出登录历史','imUserLoginHistoryExport','/imUserLoginHistory/export',10 UNION ALL + SELECT @loginFailureId,'失败详情','imLoginFailureLogView','/imLoginFailureLog/view',10 UNION ALL + SELECT @loginFailureId,'导出失败日志','imLoginFailureLogExport','/imLoginFailureLog/export',20 UNION ALL + SELECT @loginFailureId,'加入IP黑名单','imLoginFailureLogAddBlacklist','/imLoginFailureLog/addBlacklist',30 UNION ALL + SELECT @loginFailureId,'封禁关联用户','imLoginFailureLogBanUser','/imLoginFailureLog/banUser',40 +) x WHERE x.pid IS NOT NULL AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=x.name); diff --git a/server/storage/data/generate/im_adfahi_policy_menu.sql b/server/storage/data/generate/im_adfahi_policy_menu.sql new file mode 100644 index 0000000..5c6dbde --- /dev/null +++ b/server/storage/data/generate/im_adfahi_policy_menu.sql @@ -0,0 +1,52 @@ +SET @now := NOW(); +SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1); + +INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`) +SELECT NULL,@imRootId,'用户分组','imUserPolicyGroupIndex','user-policy-group/index','','2','','/imUserPolicyGroup/list','','/imUserPolicyGroup/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'25','','1',@now,@now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imUserPolicyGroupIndex'); +SET @policyGroupId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imUserPolicyGroupIndex' LIMIT 1); + +INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`) +SELECT NULL,@policyGroupId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@policyGroupId,' '),p.sort,'','1',@now,@now +FROM ( + SELECT '分组详情' title,'imUserPolicyGroupView' name,'/imUserPolicyGroup/view' permissions,10 sort UNION ALL + SELECT '分组编辑','imUserPolicyGroupEdit','/imUserPolicyGroup/edit',20 UNION ALL + SELECT '分组删除','imUserPolicyGroupDelete','/imUserPolicyGroup/delete',30 UNION ALL + SELECT '状态更新','imUserPolicyGroupStatus','/imUserPolicyGroup/status',40 UNION ALL + SELECT '成员列表','imUserPolicyGroupMemberList','/imUserPolicyGroup/memberList',50 UNION ALL + SELECT '添加成员','imUserPolicyGroupMemberAdd','/imUserPolicyGroup/memberAdd',60 UNION ALL + SELECT '移除成员','imUserPolicyGroupMemberRemove','/imUserPolicyGroup/memberRemove',70 +) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name); + +INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`) +SELECT NULL,@imRootId,'敏感词库','imSensitiveWordIndex','sensitive-word/index','','2','','/imSensitiveWord/list','','/imSensitiveWord/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'90','','1',@now,@now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imSensitiveWordIndex'); +SET @sensitiveWordId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imSensitiveWordIndex' LIMIT 1); + +INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`) +SELECT NULL,@sensitiveWordId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@sensitiveWordId,' '),p.sort,'','1',@now,@now +FROM ( + SELECT '敏感词编辑' title,'imSensitiveWordEdit' name,'/imSensitiveWord/edit' permissions,10 sort UNION ALL + SELECT '敏感词删除','imSensitiveWordDelete','/imSensitiveWord/delete',20 UNION ALL + SELECT '状态更新','imSensitiveWordStatus','/imSensitiveWord/status',30 UNION ALL + SELECT '批量导入','imSensitiveWordBatchImport','/imSensitiveWord/batchImport',40 UNION ALL + SELECT '分组列表','imSensitiveWordGroupList','/imSensitiveWord/groupList',50 UNION ALL + SELECT '分组编辑','imSensitiveWordGroupEdit','/imSensitiveWord/groupEdit',60 +) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name); + +INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`) +SELECT NULL,@imRootId,'安全策略','imSecurityPolicyIndex','security-policy/index','','2','','/imSecurityPolicy/list','','/imSecurityPolicy/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'95','','1',@now,@now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imSecurityPolicyIndex'); +SET @securityPolicyId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imSecurityPolicyIndex' LIMIT 1); + +INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`) +SELECT NULL,@securityPolicyId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@securityPolicyId,' '),p.sort,'','1',@now,@now +FROM ( + SELECT '策略详情' title,'imSecurityPolicyView' name,'/imSecurityPolicy/view' permissions,10 sort UNION ALL + SELECT '保存草稿','imSecurityPolicySave','/imSecurityPolicy/save',20 UNION ALL + SELECT '发布策略','imSecurityPolicyPublish','/imSecurityPolicy/publish',30 UNION ALL + SELECT '恢复默认','imSecurityPolicyRestoreDefault','/imSecurityPolicy/restoreDefault',40 UNION ALL + SELECT 'IP规则列表','imSecurityPolicyIpRuleList','/imSecurityPolicy/ipRuleList',50 UNION ALL + SELECT 'IP规则编辑','imSecurityPolicyIpRuleEdit','/imSecurityPolicy/ipRuleEdit',60 UNION ALL + SELECT 'IP规则删除','imSecurityPolicyIpRuleDelete','/imSecurityPolicy/ipRuleDelete',70 +) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name); diff --git a/web/src/api/imDashboard/index.ts b/web/src/api/imDashboard/index.ts new file mode 100644 index 0000000..bcec7ee --- /dev/null +++ b/web/src/api/imDashboard/index.ts @@ -0,0 +1,9 @@ +import { http } from '@/utils/http/axios'; + +export function Overview(params) { + return http.request({ url: '/imDashboard/overview', method: 'GET', params }); +} + +export function Trends(params) { + return http.request({ url: '/imDashboard/trends', method: 'GET', params }); +} diff --git a/web/src/api/imGroupMessage/index.ts b/web/src/api/imGroupMessage/index.ts new file mode 100644 index 0000000..4f762f9 --- /dev/null +++ b/web/src/api/imGroupMessage/index.ts @@ -0,0 +1,17 @@ +import { http, jumpExport } from '@/utils/http/axios'; + +export function List(params) { + return http.request({ url: '/imGroupMessage/list', method: 'GET', params }); +} +export function View(params) { + return http.request({ url: '/imGroupMessage/view', method: 'GET', params }); +} +export function Hide(params) { + return http.request({ url: '/imGroupMessage/hide', method: 'POST', params }); +} +export function Delete(params) { + return http.request({ url: '/imGroupMessage/delete', method: 'POST', params }); +} +export function Export(params) { + jumpExport('/imGroupMessage/export', params); +} diff --git a/web/src/api/imLoginFailureLog/index.ts b/web/src/api/imLoginFailureLog/index.ts new file mode 100644 index 0000000..6cea803 --- /dev/null +++ b/web/src/api/imLoginFailureLog/index.ts @@ -0,0 +1,17 @@ +import { http, jumpExport } from '@/utils/http/axios'; + +export function List(params) { + return http.request({ url: '/imLoginFailureLog/list', method: 'GET', params }); +} +export function View(params) { + return http.request({ url: '/imLoginFailureLog/view', method: 'GET', params }); +} +export function Export(params) { + jumpExport('/imLoginFailureLog/export', params); +} +export function AddBlacklist(params) { + return http.request({ url: '/imLoginFailureLog/addBlacklist', method: 'POST', params }); +} +export function BanUser(params) { + return http.request({ url: '/imLoginFailureLog/banUser', method: 'POST', params }); +} diff --git a/web/src/api/imPrivateMessage/index.ts b/web/src/api/imPrivateMessage/index.ts new file mode 100644 index 0000000..6cd29c4 --- /dev/null +++ b/web/src/api/imPrivateMessage/index.ts @@ -0,0 +1,17 @@ +import { http, jumpExport } from '@/utils/http/axios'; + +export function List(params) { + return http.request({ url: '/imPrivateMessage/list', method: 'GET', params }); +} +export function View(params) { + return http.request({ url: '/imPrivateMessage/view', method: 'GET', params }); +} +export function Hide(params) { + return http.request({ url: '/imPrivateMessage/hide', method: 'POST', params }); +} +export function Delete(params) { + return http.request({ url: '/imPrivateMessage/delete', method: 'POST', params }); +} +export function Export(params) { + jumpExport('/imPrivateMessage/export', params); +} diff --git a/web/src/api/imSecurityPolicy/index.ts b/web/src/api/imSecurityPolicy/index.ts new file mode 100644 index 0000000..afb3c3d --- /dev/null +++ b/web/src/api/imSecurityPolicy/index.ts @@ -0,0 +1,18 @@ +import { http } from '@/utils/http/axios'; + +export const List = (params) => + http.request({ url: '/imSecurityPolicy/list', method: 'GET', params }); +export const View = (params) => + http.request({ url: '/imSecurityPolicy/view', method: 'GET', params }); +export const Save = (params) => + http.request({ url: '/imSecurityPolicy/save', method: 'POST', params }); +export const Publish = (params) => + http.request({ url: '/imSecurityPolicy/publish', method: 'POST', params }); +export const RestoreDefault = (params) => + http.request({ url: '/imSecurityPolicy/restoreDefault', method: 'POST', params }); +export const IPRuleList = (params) => + http.request({ url: '/imSecurityPolicy/ipRuleList', method: 'GET', params }); +export const IPRuleEdit = (params) => + http.request({ url: '/imSecurityPolicy/ipRuleEdit', method: 'POST', params }); +export const IPRuleDelete = (params) => + http.request({ url: '/imSecurityPolicy/ipRuleDelete', method: 'POST', params }); diff --git a/web/src/api/imSensitiveWord/index.ts b/web/src/api/imSensitiveWord/index.ts new file mode 100644 index 0000000..b776d1c --- /dev/null +++ b/web/src/api/imSensitiveWord/index.ts @@ -0,0 +1,16 @@ +import { http } from '@/utils/http/axios'; + +export const List = (params) => + http.request({ url: '/imSensitiveWord/list', method: 'GET', params }); +export const Edit = (params) => + http.request({ url: '/imSensitiveWord/edit', method: 'POST', params }); +export const Delete = (params) => + http.request({ url: '/imSensitiveWord/delete', method: 'POST', params }); +export const Status = (params) => + http.request({ url: '/imSensitiveWord/status', method: 'POST', params }); +export const BatchImport = (params) => + http.request({ url: '/imSensitiveWord/batchImport', method: 'POST', params }); +export const GroupList = (params) => + http.request({ url: '/imSensitiveWord/groupList', method: 'GET', params }); +export const GroupEdit = (params) => + http.request({ url: '/imSensitiveWord/groupEdit', method: 'POST', params }); diff --git a/web/src/api/imUserLoginHistory/index.ts b/web/src/api/imUserLoginHistory/index.ts new file mode 100644 index 0000000..1129361 --- /dev/null +++ b/web/src/api/imUserLoginHistory/index.ts @@ -0,0 +1,8 @@ +import { http, jumpExport } from '@/utils/http/axios'; + +export function List(params) { + return http.request({ url: '/imUserLoginHistory/list', method: 'GET', params }); +} +export function Export(params) { + jumpExport('/imUserLoginHistory/export', params); +} diff --git a/web/src/api/imUserPolicyGroup/index.ts b/web/src/api/imUserPolicyGroup/index.ts new file mode 100644 index 0000000..82807d6 --- /dev/null +++ b/web/src/api/imUserPolicyGroup/index.ts @@ -0,0 +1,18 @@ +import { http } from '@/utils/http/axios'; + +export const List = (params) => + http.request({ url: '/imUserPolicyGroup/list', method: 'GET', params }); +export const View = (params) => + http.request({ url: '/imUserPolicyGroup/view', method: 'GET', params }); +export const Edit = (params) => + http.request({ url: '/imUserPolicyGroup/edit', method: 'POST', params }); +export const Delete = (params) => + http.request({ url: '/imUserPolicyGroup/delete', method: 'POST', params }); +export const Status = (params) => + http.request({ url: '/imUserPolicyGroup/status', method: 'POST', params }); +export const MemberList = (params) => + http.request({ url: '/imUserPolicyGroup/memberList', method: 'GET', params }); +export const MemberAdd = (params) => + http.request({ url: '/imUserPolicyGroup/memberAdd', method: 'POST', params }); +export const MemberRemove = (params) => + http.request({ url: '/imUserPolicyGroup/memberRemove', method: 'POST', params }); diff --git a/web/src/views/imAdminQueryShared.ts b/web/src/views/imAdminQueryShared.ts new file mode 100644 index 0000000..36781f4 --- /dev/null +++ b/web/src/views/imAdminQueryShared.ts @@ -0,0 +1,13 @@ +import { ref } from 'vue'; +import { List as TenantList } from '@/api/imTenant'; + +export const imQueryTenantOptions = ref([]); + +export async function loadImQueryTenantOptions() { + const res = await TenantList({ page: 1, perPage: 100 }); + imQueryTenantOptions.value = (res?.list || []).map((item) => ({ + label: `${item.name}(${item.code})`, + value: item.id, + })); + return imQueryTenantOptions.value; +} diff --git a/web/src/views/imDashboard/index.vue b/web/src/views/imDashboard/index.vue new file mode 100644 index 0000000..c1200c8 --- /dev/null +++ b/web/src/views/imDashboard/index.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/web/src/views/imGroupMessage/index.vue b/web/src/views/imGroupMessage/index.vue new file mode 100644 index 0000000..e4ecace --- /dev/null +++ b/web/src/views/imGroupMessage/index.vue @@ -0,0 +1,4 @@ + + diff --git a/web/src/views/imLoginFailureLog/index.vue b/web/src/views/imLoginFailureLog/index.vue new file mode 100644 index 0000000..b914f24 --- /dev/null +++ b/web/src/views/imLoginFailureLog/index.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/web/src/views/imLoginFailureLog/model.ts b/web/src/views/imLoginFailureLog/model.ts new file mode 100644 index 0000000..a575a7e --- /dev/null +++ b/web/src/views/imLoginFailureLog/model.ts @@ -0,0 +1,92 @@ +import { computed, ref } from 'vue'; +import { FormSchema } from '@/components/Form'; +import { defRangeShortcuts } from '@/utils/dateUtil'; +import { useDictStore } from '@/store/modules/dict'; +import { imQueryTenantOptions } from '@/views/imAdminQueryShared'; + +const dict = useDictStore(); + +export const schemas = ref([ + { + field: 'tenantId', + component: 'NSelect', + label: '租户', + componentProps: { + clearable: false, + options: computed(() => imQueryTenantOptions.value), + placeholder: '请选择租户', + }, + }, + { + field: 'userId', + component: 'NInput', + label: '用户ID', + componentProps: { placeholder: '请输入用户ID' }, + }, + { + field: 'account', + component: 'NInput', + label: '账号', + componentProps: { placeholder: '请输入脱敏账号' }, + }, + { + field: 'failureType', + component: 'NSelect', + label: '失败类型', + componentProps: { + clearable: true, + options: dict.getOption('ImLoginFailureTypeOptions'), + placeholder: '全部类型', + }, + }, + { + field: 'platform', + component: 'NSelect', + label: '客户端', + componentProps: { + clearable: true, + options: dict.getOption('ImClientPlatformOptions'), + placeholder: '全部客户端', + }, + }, + { + field: 'ip', + component: 'NInput', + label: 'IP', + componentProps: { placeholder: '请输入IP地址' }, + }, + { + field: 'attemptAt', + component: 'NDatePicker', + label: '尝试时间', + componentProps: { type: 'datetimerange', clearable: true, shortcuts: defRangeShortcuts() }, + }, +]); + +export const columns = [ + { title: 'ID', key: 'id', width: 90 }, + { title: '用户ID', key: 'userId', width: 130 }, + { title: '账号', key: 'accountMask', width: 170 }, + { + title: '失败类型', + key: 'failureType', + width: 140, + render: (row) => dict.getLabel('ImLoginFailureTypeOptions', row.failureType) || row.failureType, + }, + { title: '原因码', key: 'reason', width: 180 }, + { title: 'IP', key: 'ip', width: 140 }, + { title: '地区', key: 'region', width: 150 }, + { + title: '客户端', + key: 'platform', + width: 110, + render: (row) => dict.getLabel('ImClientPlatformOptions', row.platform) || row.platform, + }, + { title: '风险', key: 'riskLevel', width: 90 }, + { title: '风控动作', key: 'riskAction', width: 120 }, + { title: '尝试时间', key: 'attemptAt', width: 180 }, +]; + +export function loadOptions() { + dict.loadOptions(['ImLoginFailureTypeOptions', 'ImClientPlatformOptions']); +} diff --git a/web/src/views/imMessageShared/MessageTable.vue b/web/src/views/imMessageShared/MessageTable.vue new file mode 100644 index 0000000..3c82d3f --- /dev/null +++ b/web/src/views/imMessageShared/MessageTable.vue @@ -0,0 +1,232 @@ + + + + + diff --git a/web/src/views/imMessageShared/model.ts b/web/src/views/imMessageShared/model.ts new file mode 100644 index 0000000..47d32e9 --- /dev/null +++ b/web/src/views/imMessageShared/model.ts @@ -0,0 +1,131 @@ +import { computed, ref } from 'vue'; +import { FormSchema } from '@/components/Form'; +import { defRangeShortcuts } from '@/utils/dateUtil'; +import { useDictStore } from '@/store/modules/dict'; +import { imQueryTenantOptions } from '@/views/imAdminQueryShared'; + +const dict = useDictStore(); + +export function createMessageSchemas(group: boolean) { + const items: FormSchema[] = [ + { + field: 'tenantId', + component: 'NSelect', + label: '租户', + componentProps: { + clearable: false, + options: computed(() => imQueryTenantOptions.value), + placeholder: '请选择租户', + }, + }, + { + field: 'topic', + component: 'NInput', + label: group ? '群Topic' : '会话Topic', + componentProps: { placeholder: '请输入Topic' }, + }, + { + field: group ? 'senderUserId' : 'fromUserId', + component: 'NInput', + label: '发送用户', + componentProps: { placeholder: '请输入用户ID' }, + }, + ]; + if (!group) + items.push({ + field: 'toUserId', + component: 'NInput', + label: '接收用户', + componentProps: { placeholder: '请输入用户ID' }, + }); + items.push( + { + field: 'contentType', + component: 'NSelect', + label: '消息类型', + componentProps: { + clearable: true, + options: dict.getOption('ImMessageContentTypeOptions'), + placeholder: '全部类型', + }, + }, + { + field: 'status', + component: 'NSelect', + label: '消息状态', + componentProps: { + clearable: true, + options: dict.getOption('ImMessageStatusOptions'), + placeholder: '全部状态', + }, + }, + { + field: 'keyword', + component: 'NInput', + label: '关键词', + componentProps: { placeholder: '请输入内容关键词' }, + }, + { + field: 'createdAt', + component: 'NDatePicker', + label: '发送时间', + componentProps: { type: 'datetimerange', clearable: true, shortcuts: defRangeShortcuts() }, + } + ); + return ref(items); +} + +export function createMessageColumns(group: boolean) { + const columns: any[] = [ + { title: '消息序号', key: 'seqId', width: 110 }, + { + title: '发送人', + key: 'fromUserId', + width: 190, + render: (row) => + row.senderNickname + ? `${row.senderNickname} / ${row.senderUsername || row.fromUserId}` + : row.senderUsername || row.fromUserId, + }, + ]; + if (group) + columns.push({ + title: '群名称', + key: 'groupName', + width: 190, + render: (row) => + row.groupName ? `${row.groupName} / ${row.groupNo || row.topic}` : row.topic, + }); + else + columns.push({ + title: '接收人', + key: 'toUserId', + width: 190, + render: (row) => + row.receiverNickname + ? `${row.receiverNickname} / ${row.receiverUsername || row.toUserId}` + : row.receiverUsername || row.toUserId, + }); + columns.push( + { + title: '类型', + key: 'contentType', + width: 100, + render: (row) => + dict.getLabel('ImMessageContentTypeOptions', row.contentType) || row.contentType, + }, + { title: '内容', key: 'contentExcerpt', width: 300, ellipsis: { tooltip: true } }, + { + title: '状态', + key: 'status', + width: 110, + render: (row) => dict.getLabel('ImMessageStatusOptions', row.status) || row.status, + }, + { title: '发送时间', key: 'createdAt', width: 180 } + ); + return columns; +} + +export function loadMessageOptions() { + dict.loadOptions(['ImMessageContentTypeOptions', 'ImMessageStatusOptions']); +} diff --git a/web/src/views/imPolicyShared.ts b/web/src/views/imPolicyShared.ts new file mode 100644 index 0000000..9c004dd --- /dev/null +++ b/web/src/views/imPolicyShared.ts @@ -0,0 +1,32 @@ +import { ref } from 'vue'; +import { List as TenantList } from '@/api/imTenant'; + +export const policyTenantOptions = ref([{ label: '全局默认', value: 0 }]); + +export async function loadPolicyTenantOptions(includeGlobal = true) { + const res = await TenantList({ page: 1, perPage: 100 }); + const tenants = (res?.list || []).map((item) => ({ + label: `${item.name}(${item.code})`, + value: item.id, + })); + policyTenantOptions.value = includeGlobal + ? [{ label: '全局默认', value: 0 }, ...tenants] + : tenants; + return policyTenantOptions.value; +} + +export function parseJSON(value: string, fallback: any) { + try { + return value ? JSON.parse(value) : fallback; + } catch { + return fallback; + } +} + +export function stringifyJSON(value: any, fallback = '{}') { + try { + return JSON.stringify(value ?? JSON.parse(fallback)); + } catch { + return fallback; + } +} diff --git a/web/src/views/imPrivateMessage/index.vue b/web/src/views/imPrivateMessage/index.vue new file mode 100644 index 0000000..91db3d0 --- /dev/null +++ b/web/src/views/imPrivateMessage/index.vue @@ -0,0 +1,4 @@ + + diff --git a/web/src/views/imSecurityPolicy/index.vue b/web/src/views/imSecurityPolicy/index.vue new file mode 100644 index 0000000..f4feb69 --- /dev/null +++ b/web/src/views/imSecurityPolicy/index.vue @@ -0,0 +1,568 @@ + + + diff --git a/web/src/views/imSecurityPolicy/model.ts b/web/src/views/imSecurityPolicy/model.ts new file mode 100644 index 0000000..0a67393 --- /dev/null +++ b/web/src/views/imSecurityPolicy/model.ts @@ -0,0 +1,88 @@ +import { computed, ref } from 'vue'; +import { FormSchema } from '@/components/Form'; +import { useDictStore } from '@/store/modules/dict'; +import { policyTenantOptions } from '@/views/imPolicyShared'; + +const dict = useDictStore(); +export const schemas = ref([ + { + field: 'tenantId', + component: 'NSelect', + label: '租户', + componentProps: { options: computed(() => policyTenantOptions.value), clearable: false }, + }, + { + field: 'publishStatus', + component: 'NSelect', + label: '发布状态', + componentProps: { + options: computed(() => dict.getOptions('ImSecurityPublishStatusOptions')), + clearable: true, + }, + }, +]); +export const columns = [ + { title: '版本', key: 'policyVersion', width: 90 }, + { title: '策略名称', key: 'policyName', width: 180 }, + { + title: '发布状态', + key: 'publishStatus', + width: 110, + render: (r) => dict.getLabel('ImSecurityPublishStatusOptions', r.publishStatus), + }, + { + title: '允许加好友', + key: 'globalFriendEnabled', + width: 110, + render: (r) => (r.globalFriendEnabled ? '允许' : '禁止'), + }, + { + title: '消息宵禁', + key: 'messageCurfewEnabled', + width: 100, + render: (r) => (r.messageCurfewEnabled ? '启用' : '关闭'), + }, + { title: '发布时间', key: 'publishedAt', width: 180 }, + { title: '更新时间', key: 'updatedAt', width: 180 }, + { title: '备注', key: 'remark', width: 220 }, +]; +export const ipColumns = [ + { + title: '类型', + key: 'ruleType', + width: 100, + render: (r) => (r.ruleType === 'whitelist' ? '白名单' : '黑名单'), + }, + { title: 'IP/CIDR', key: 'ipCidr', width: 180 }, + { + title: '动作', + key: 'action', + width: 110, + render: (r) => dict.getLabel('ImSecurityActionOptions', r.action), + }, + { + title: '风险等级', + key: 'riskLevel', + width: 100, + render: (r) => dict.getLabel('ImRiskLevelOptions', r.riskLevel), + }, + { + title: '状态', + key: 'status', + width: 90, + render: (r) => dict.getLabel('sys_normal_disable', r.status), + }, + { title: '过期时间', key: 'expiresAt', width: 180 }, + { title: '备注', key: 'remark', width: 200 }, +]; +export function loadOptions() { + dict.loadOptions([ + 'ImSecurityPublishStatusOptions', + 'ImCurfewDateTypeOptions', + 'ImCurfewScopeOptions', + 'ImSecurityActionOptions', + 'ImFriendEntryOptions', + 'ImRiskLevelOptions', + 'sys_normal_disable', + ]); +} diff --git a/web/src/views/imSensitiveWord/index.vue b/web/src/views/imSensitiveWord/index.vue new file mode 100644 index 0000000..7bbff1d --- /dev/null +++ b/web/src/views/imSensitiveWord/index.vue @@ -0,0 +1,330 @@ + + + diff --git a/web/src/views/imSensitiveWord/model.ts b/web/src/views/imSensitiveWord/model.ts new file mode 100644 index 0000000..f0ec9ce --- /dev/null +++ b/web/src/views/imSensitiveWord/model.ts @@ -0,0 +1,110 @@ +import { computed, ref } from 'vue'; +import { FormSchema } from '@/components/Form'; +import { useDictStore } from '@/store/modules/dict'; +import { policyTenantOptions } from '@/views/imPolicyShared'; + +const dict = useDictStore(); +export const groupOptions = ref([]); +export const schemas = ref([ + { + field: 'tenantId', + component: 'NSelect', + label: '租户', + componentProps: { options: computed(() => policyTenantOptions.value), clearable: false }, + }, + { field: 'word', component: 'NInput', label: '敏感词', componentProps: { clearable: true } }, + { + field: 'groupId', + component: 'NSelect', + label: '分组', + componentProps: { options: computed(() => groupOptions.value), clearable: true }, + }, + { + field: 'matchType', + component: 'NSelect', + label: '匹配类型', + componentProps: { + options: computed(() => dict.getOptions('ImSensitiveMatchTypeOptions')), + clearable: true, + }, + }, + { + field: 'action', + component: 'NSelect', + label: '命中动作', + componentProps: { + options: computed(() => dict.getOptions('ImSensitiveActionOptions')), + clearable: true, + }, + }, + { + field: 'riskLevel', + component: 'NSelect', + label: '风险等级', + componentProps: { + options: computed(() => dict.getOptions('ImRiskLevelOptions')), + clearable: true, + }, + }, + { + field: 'status', + component: 'NSelect', + label: '状态', + componentProps: { + options: computed(() => dict.getOptions('sys_normal_disable')), + clearable: true, + }, + }, +]); +export const columns = [ + { title: '敏感词', key: 'word', width: 180 }, + { title: '分组', key: 'groupName', width: 140 }, + { + title: '匹配类型', + key: 'matchType', + width: 110, + render: (r) => dict.getLabel('ImSensitiveMatchTypeOptions', r.matchType), + }, + { + title: '生效场景', + key: 'sceneJson', + width: 220, + render: (r) => { + try { + return JSON.parse(r.sceneJson || '[]') + .map((v) => dict.getLabel('ImSensitiveSceneOptions', v) || v) + .join('、'); + } catch { + return ''; + } + }, + }, + { + title: '命中动作', + key: 'action', + width: 110, + render: (r) => dict.getLabel('ImSensitiveActionOptions', r.action), + }, + { + title: '风险等级', + key: 'riskLevel', + width: 100, + render: (r) => dict.getLabel('ImRiskLevelOptions', r.riskLevel), + }, + { + title: '状态', + key: 'status', + width: 90, + render: (r) => dict.getLabel('sys_normal_disable', r.status), + }, + { title: '更新时间', key: 'updatedAt', width: 180 }, +]; +export function loadOptions() { + dict.loadOptions([ + 'ImSensitiveMatchTypeOptions', + 'ImSensitiveActionOptions', + 'ImSensitiveSceneOptions', + 'ImRiskLevelOptions', + 'sys_normal_disable', + ]); +} diff --git a/web/src/views/imUserLoginHistory/index.vue b/web/src/views/imUserLoginHistory/index.vue new file mode 100644 index 0000000..da01c74 --- /dev/null +++ b/web/src/views/imUserLoginHistory/index.vue @@ -0,0 +1,95 @@ + + + diff --git a/web/src/views/imUserLoginHistory/model.ts b/web/src/views/imUserLoginHistory/model.ts new file mode 100644 index 0000000..b96fc8d --- /dev/null +++ b/web/src/views/imUserLoginHistory/model.ts @@ -0,0 +1,109 @@ +import { computed, ref } from 'vue'; +import { FormSchema } from '@/components/Form'; +import { defRangeShortcuts } from '@/utils/dateUtil'; +import { useDictStore } from '@/store/modules/dict'; +import { imQueryTenantOptions } from '@/views/imAdminQueryShared'; + +const dict = useDictStore(); + +export const schemas = ref([ + { + field: 'tenantId', + component: 'NSelect', + label: '租户', + componentProps: { + clearable: false, + options: computed(() => imQueryTenantOptions.value), + placeholder: '请选择租户', + }, + }, + { + field: 'userId', + component: 'NInput', + label: '用户ID', + componentProps: { placeholder: '请输入用户ID' }, + }, + { + field: 'account', + component: 'NInput', + label: '账号', + componentProps: { placeholder: '请输入手机号/脱敏账号' }, + }, + { + field: 'loginType', + component: 'NSelect', + label: '登录方式', + componentProps: { + clearable: true, + options: dict.getOption('ImLoginTypeOptions'), + placeholder: '全部方式', + }, + }, + { + field: 'eventType', + component: 'NSelect', + label: '事件类型', + componentProps: { + clearable: true, + options: dict.getOption('ImLoginEventTypeOptions'), + placeholder: '全部事件', + }, + }, + { + field: 'platform', + component: 'NSelect', + label: '客户端', + componentProps: { + clearable: true, + options: dict.getOption('ImClientPlatformOptions'), + placeholder: '全部客户端', + }, + }, + { + field: 'ip', + component: 'NInput', + label: 'IP', + componentProps: { placeholder: '请输入IP地址' }, + }, + { + field: 'loginAt', + component: 'NDatePicker', + label: '登录时间', + componentProps: { type: 'datetimerange', clearable: true, shortcuts: defRangeShortcuts() }, + }, +]); + +export const columns = [ + { title: 'ID', key: 'id', width: 90 }, + { title: '用户ID', key: 'userId', width: 130 }, + { title: '用户名', key: 'username', width: 150 }, + { title: '账号', key: 'accountMask', width: 170 }, + { + title: '登录方式', + key: 'loginType', + width: 120, + render: (row) => dict.getLabel('ImLoginTypeOptions', row.loginType) || row.loginType, + }, + { + title: '事件', + key: 'eventType', + width: 120, + render: (row) => dict.getLabel('ImLoginEventTypeOptions', row.eventType) || row.eventType, + }, + { + title: '客户端', + key: 'platform', + width: 110, + render: (row) => dict.getLabel('ImClientPlatformOptions', row.platform) || row.platform, + }, + { title: '版本', key: 'appVersion', width: 100 }, + { title: 'IP', key: 'ip', width: 140 }, + { title: '地区', key: 'region', width: 150 }, + { title: '风险', key: 'riskLevel', width: 90 }, + { title: '登录时间', key: 'loginAt', width: 180 }, + { title: '登出时间', key: 'logoutAt', width: 180 }, +]; + +export function loadOptions() { + dict.loadOptions(['ImLoginTypeOptions', 'ImLoginEventTypeOptions', 'ImClientPlatformOptions']); +} diff --git a/web/src/views/imUserPolicyGroup/index.vue b/web/src/views/imUserPolicyGroup/index.vue new file mode 100644 index 0000000..e6f7c99 --- /dev/null +++ b/web/src/views/imUserPolicyGroup/index.vue @@ -0,0 +1,364 @@ + + + + + diff --git a/web/src/views/imUserPolicyGroup/model.ts b/web/src/views/imUserPolicyGroup/model.ts new file mode 100644 index 0000000..b512ab3 --- /dev/null +++ b/web/src/views/imUserPolicyGroup/model.ts @@ -0,0 +1,64 @@ +import { computed, ref } from 'vue'; +import { FormSchema } from '@/components/Form'; +import { useDictStore } from '@/store/modules/dict'; +import { policyTenantOptions } from '@/views/imPolicyShared'; + +const dict = useDictStore(); + +export const defaultPolicy = { + allow_add_friend: true, + direct_add_friend: false, + max_friend_count: 5000, + allow_qrcode_add_friend: true, + allow_group_member_profile: true, + hide_profile_when_friend_disabled: true, + allow_private_message: true, + allow_group_message: true, + allow_create_group: true, + allow_join_group: true, + allow_upload_file: true, +}; + +export const schemas = ref([ + { + field: 'tenantId', + component: 'NSelect', + label: '租户', + componentProps: { options: computed(() => policyTenantOptions.value), clearable: false }, + }, + { + field: 'keyword', + component: 'NInput', + label: '关键词', + componentProps: { placeholder: '分组编码或名称', clearable: true }, + }, + { + field: 'status', + component: 'NSelect', + label: '状态', + componentProps: { + options: computed(() => dict.getOptions('sys_normal_disable')), + clearable: true, + }, + }, +]); + +export const columns = [ + { title: '分组编码', key: 'groupCode', width: 150 }, + { title: '分组名称', key: 'groupName', width: 160 }, + { title: '优先级', key: 'priority', width: 90 }, + { title: '成员数', key: 'memberCount', width: 90 }, + { + title: '状态', + key: 'status', + width: 90, + render: (row) => dict.getLabel('sys_normal_disable', row.status), + }, + { title: '版本', key: 'version', width: 80 }, + { title: '备注', key: 'remark', width: 220 }, + { title: '更新时间', key: 'updatedAt', width: 180 }, +]; + +export function loadOptions() { + dict.loadOptions(['sys_normal_disable', 'ImPolicyActionOptions', 'ImFriendEntryOptions']); +}