Quellcode durchsuchen

初次微服务功能模板上传

1037015548@qq.com vor 1 Jahr
Ursprung
Commit
4f287c274e
100 geänderte Dateien mit 6130 neuen und 0 gelöschten Zeilen
  1. 15 0
      .dockerignore
  2. 15 0
      .gitignore
  3. 2 0
      .mvn/jvm.config
  4. 2 0
      .mvn/maven.config
  5. 30 0
      Dockerfile
  6. 201 0
      LICENSE
  7. 67 0
      Makefile
  8. 55 0
      dc3-center/dc3-center-auth/Dockerfile
  9. 68 0
      dc3-center/dc3-center-auth/pom.xml
  10. 38 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/AuthApplication.java
  11. 66 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/BlackIpApi.java
  12. 89 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/TenantApi.java
  13. 74 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/TokenApi.java
  14. 92 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/UserApi.java
  15. 90 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/UserLoginApi.java
  16. 177 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/BlackIpController.java
  17. 105 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/DictionaryController.java
  18. 43 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/IndexController.java
  19. 163 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/TenantController.java
  20. 103 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/TokenController.java
  21. 197 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/UserLoginController.java
  22. 34 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/bean/AuthHeader.java
  23. 35 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/bean/TokenValid.java
  24. 44 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/bean/UserLimit.java
  25. 61 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/bo/UserLoginBO.java
  26. 98 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/builder/UserLoginBuilder.java
  27. 39 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/BlackIpPageQuery.java
  28. 21 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/ResourcePageQuery.java
  29. 21 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/RoleResourceBindPageQuery.java
  30. 21 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/RoleUserBindPageQuery.java
  31. 39 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/TenantBindPageQuery.java
  32. 37 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/TenantPageQuery.java
  33. 37 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/UserDto.java
  34. 37 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/UserLoginPageQuery.java
  35. 37 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/UserPasswordPageQuery.java
  36. 61 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/vo/UserLoginVO.java
  37. 31 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/BlackIpMapper.java
  38. 15 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/ResourceMapper.java
  39. 15 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/RoleMapper.java
  40. 15 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/RoleResourceBindMapper.java
  41. 13 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/RoleUserBindMapper.java
  42. 31 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/TenantBindMapper.java
  43. 31 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/TenantMapper.java
  44. 31 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/UserLoginMapper.java
  45. 31 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/UserMapper.java
  46. 31 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/UserPasswordMapper.java
  47. 35 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/AuthService.java
  48. 46 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/BlackIpService.java
  49. 54 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/DictionaryService.java
  50. 14 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/ResourceService.java
  51. 25 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/RoleResourceBindService.java
  52. 26 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/RoleUserBindService.java
  53. 39 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/TenantBindService.java
  54. 38 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/TenantService.java
  55. 67 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/TokenService.java
  56. 47 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/UserLoginService.java
  57. 37 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/UserPasswordService.java
  58. 57 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/UserService.java
  59. 134 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/AuthServiceImpl.java
  60. 124 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/BlackIpServiceImpl.java
  61. 93 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/DictionaryServiceImpl.java
  62. 86 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/ResourceServiceImpl.java
  63. 105 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/RoleResourceBindServiceImpl.java
  64. 107 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/RoleUserBindServiceImpl.java
  65. 114 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/TenantBindServiceImpl.java
  66. 112 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/TenantServiceImpl.java
  67. 190 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/TokenServiceImpl.java
  68. 142 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/UserLoginServiceImpl.java
  69. 115 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/UserPasswordServiceImpl.java
  70. 201 0
      dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/UserServiceImpl.java
  71. 22 0
      dc3-center/dc3-center-auth/src/main/resources/META-INF/aop.xml
  72. 39 0
      dc3-center/dc3-center-auth/src/main/resources/application-dev.yml
  73. 21 0
      dc3-center/dc3-center-auth/src/main/resources/application-pre.yml
  74. 21 0
      dc3-center/dc3-center-auth/src/main/resources/application-pro.yml
  75. 21 0
      dc3-center/dc3-center-auth/src/main/resources/application-test.yml
  76. 37 0
      dc3-center/dc3-center-auth/src/main/resources/application.yml
  77. 49 0
      dc3-center/dc3-center-data/Dockerfile
  78. 113 0
      dc3-center/dc3-center-data/pom.xml
  79. 38 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/DataApplication.java
  80. 56 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/api/PointValueApi.java
  81. 104 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/config/DataTopicConfig.java
  82. 88 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/config/ElasticsearchConfig.java
  83. 48 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/config/OpentsdbConfig.java
  84. 70 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/DeviceEventController.java
  85. 100 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/DeviceStatusController.java
  86. 70 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/DriverEventController.java
  87. 63 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/DriverStatusController.java
  88. 43 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/IndexController.java
  89. 79 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/PointValueCommandController.java
  90. 92 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/PointValueController.java
  91. 43 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/PointValueReadVO.java
  92. 46 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/PointValueWriteVO.java
  93. 49 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/DeviceEventPageQuery.java
  94. 41 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/DevicePageQuery.java
  95. 44 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/DriverEventPageQuery.java
  96. 39 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/DriverPageQuery.java
  97. 60 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/PointValuePageQuery.java
  98. 40 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/init/DataInitRunner.java
  99. 28 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/mapper/TaosPointValueMapper.java
  100. 0 0
      dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/service/DeviceStatusService.java

+ 15 - 0
.dockerignore

@@ -0,0 +1,15 @@
+**/.idea
+**/*.iml
+
+**/*logs
+**/*target
+
+**/.vs
+**/.vscode
+
+**/.settings
+**/.project
+
+**/*.iws
+**/*.ipr
+**/*.md

+ 15 - 0
.gitignore

@@ -0,0 +1,15 @@
+*target
+*logs
+.idea
+*.iws
+*.iml
+*.ipr
+.vs
+.vscode
+.settings
+.project
+.DS_Store
+
+dc3-api
+dc3-common
+dc3-driver-sdk

+ 2 - 0
.mvn/jvm.config

@@ -0,0 +1,2 @@
+-Xms256m
+-Xmx512m

+ 2 - 0
.mvn/maven.config

@@ -0,0 +1,2 @@
+--define
+    skiptests=true

+ 30 - 0
Dockerfile

@@ -0,0 +1,30 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# builder
+FROM registry.cn-beijing.aliyuncs.com/dc3/alpine-java:dragonwell-jdk-8.13.14 AS builder
+MAINTAINER pnoker <pnokers.icloud.com>
+
+ARG PROFILE=dev
+
+RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+
+WORKDIR /build
+COPY . /build
+
+COPY ./ ./
+
+RUN mvn -U -e -B clean package -DskipTests -P $PROFILE

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 67 - 0
Makefile

@@ -0,0 +1,67 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# tip:
+# make -f ./Makefile dev
+# make -f ./Makefile deploy
+# make -f ./Makefile package
+# make -f ./Makefile clean
+
+.PHONY: build clean
+
+help:
+	echo 'You can use make to execute the following commands:' \
+	&& echo 'Usage: make [clean | package | deploy | dev | tag]' \
+	&& echo ' - make demo: build & push demo images' \
+	&& echo ' - make dev: run local development environment' \
+	&& echo ' - make clean: mvn clean' \
+	&& echo ' - make package: mvn package' \
+	&& echo ' - make build: build images' \
+	&& echo ' - make deploy.N: mvn deploy N' \
+	&& echo ' - make tag: git tag' \
+
+demo:
+	mvn clean package \
+	&& cd dc3 \
+	&& docker-compose -f docker-compose-demo.yml build \
+	&& docker-compose -f docker-compose-demo.yml push \
+
+dev:
+	cd dc3 \
+	&& docker-compose -f docker-compose-dev.yml up -d \
+
+clean:
+	mvn clean \
+
+package:
+	mvn package \
+
+build:
+	mvn clean package \
+    && cd dc3 \
+	&& docker-compose build \
+
+deploy.api:
+	cd dc3-api \
+	&& mvn clean deploy \
+
+deploy.common:
+	cd dc3-common \
+	&& mvn clean deploy \
+
+deploy.sdk:
+	cd dc3-driver-sdk \
+	&& mvn clean deploy \

+ 55 - 0
dc3-center/dc3-center-auth/Dockerfile

@@ -0,0 +1,55 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# runtime
+FROM registry.cn-beijing.aliyuncs.com/dc3/alpine-java:dragonwell-8.13.14 AS runtime
+MAINTAINER pnoker <pnokers.icloud.com>
+
+# default env
+ENV NODE_ENV dev
+ENV EUREKA_TLS_ENABLE false
+ENV SERVER_PORT 8300
+
+# default jvm & gc env
+ENV JAVA_OPS -server \
+             -Xms128m \
+             -Xmx1024m \
+             -Djava.security.egd=file:/dev/./urandom \
+             -XX:CompressedClassSpaceSize=128m \
+             -XX:MetaspaceSize=200m \
+             -XX:MaxMetaspaceSize=200m
+ENV GC_LOG   -XX:+PrintGCDetails \
+             -XX:+PrintGCDateStamps \
+             -XX:+PrintTenuringDistribution \
+             -XX:+PrintHeapAtGC \
+             -XX:+PrintReferenceGC \
+             -XX:+PrintGCApplicationStoppedTime \
+             -XX:+UseGCLogFileRotation \
+             -XX:NumberOfGCLogFiles=10 \
+             -XX:GCLogFileSize=10M \
+             -Xloggc:dc3/logs/center/auth/gc/dc3-center-auth.log
+
+RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+
+WORKDIR /dc3-center/dc3-center-auth
+
+ADD ./target/dc3-center-auth.jar ./
+
+EXPOSE ${SERVER_PORT}
+VOLUME /dc3-center/dc3-center-auth/dc3/logs
+
+CMD mkdir -p /dc3-center/dc3-center-auth/dc3/logs/center/auth/gc \
+    && java ${JAVA_OPS} ${GC_LOG} -jar dc3-center-auth.jar

+ 68 - 0
dc3-center/dc3-center-auth/pom.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>io.github.pnoker</groupId>
+        <artifactId>dc3-center</artifactId>
+        <version>2023.4.5</version>
+    </parent>
+
+    <artifactId>dc3-center-auth</artifactId>
+    <packaging>jar</packaging>
+
+    <description>IOT DC3 平台 授权服务。</description>
+
+    <dependencies>
+
+        <!-- DC3 Api -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-api-auth</artifactId>
+        </dependency>
+
+        <!-- DC3 Common MySQL -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-mysql</artifactId>
+        </dependency>
+
+        <!-- DC3 Common Redis -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-redis</artifactId>
+        </dependency>
+
+        <!-- DC3 Common Auth -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-auth</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 38 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/AuthApplication.java

@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * 授权中心服务启动入口
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableTransactionManagement
+public class AuthApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(AuthApplication.class, args);
+    }
+}
+

+ 66 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/BlackIpApi.java

@@ -0,0 +1,66 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.api;
+
+
+import io.github.pnoker.api.center.auth.BlackIpApiGrpc;
+import io.github.pnoker.api.center.auth.IpQuery;
+import io.github.pnoker.api.center.auth.RBlackIpDTO;
+import io.github.pnoker.api.common.RDTO;
+import io.github.pnoker.center.auth.service.BlackIpService;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.grpc.stub.StreamObserver;
+import lombok.extern.slf4j.Slf4j;
+import net.devh.boot.grpc.server.service.GrpcService;
+
+import javax.annotation.Resource;
+
+/**
+ * BlackIp Api
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@GrpcService
+public class BlackIpApi extends BlackIpApiGrpc.BlackIpApiImplBase {
+
+    @Resource
+    private BlackIpService blackIpService;
+
+    @Override
+    public void checkBlackIpValid(IpQuery request, StreamObserver<RBlackIpDTO> responseObserver) {
+        RBlackIpDTO.Builder builder = RBlackIpDTO.newBuilder();
+        RDTO.Builder rBuilder = RDTO.newBuilder();
+        Boolean ipValid = blackIpService.checkBlackIpValid(request.getIp());
+        if (!Boolean.TRUE.equals(ipValid)) {
+            rBuilder.setOk(false);
+            rBuilder.setCode(ResponseEnum.IP_INVALID.getCode());
+            rBuilder.setMessage(ResponseEnum.IP_INVALID.getMessage());
+        } else {
+            rBuilder.setOk(true);
+            rBuilder.setCode(ResponseEnum.OK.getCode());
+            rBuilder.setMessage(ResponseEnum.OK.getMessage());
+            builder.setData(true);
+        }
+
+        builder.setResult(rBuilder);
+        responseObserver.onNext(builder.build());
+        responseObserver.onCompleted();
+    }
+
+}

+ 89 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/TenantApi.java

@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.api;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import io.github.pnoker.api.center.auth.CodeQuery;
+import io.github.pnoker.api.center.auth.RTenantDTO;
+import io.github.pnoker.api.center.auth.TenantApiGrpc;
+import io.github.pnoker.api.center.auth.TenantDTO;
+import io.github.pnoker.api.common.BaseDTO;
+import io.github.pnoker.api.common.EnableFlagDTOEnum;
+import io.github.pnoker.api.common.RDTO;
+import io.github.pnoker.center.auth.service.TenantService;
+import io.github.pnoker.common.utils.BuilderUtil;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.github.pnoker.common.model.Tenant;
+import io.grpc.stub.StreamObserver;
+import lombok.extern.slf4j.Slf4j;
+import net.devh.boot.grpc.server.service.GrpcService;
+
+import javax.annotation.Resource;
+
+/**
+ * Tenant Api
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@GrpcService
+public class TenantApi extends TenantApiGrpc.TenantApiImplBase {
+
+    @Resource
+    private TenantService tenantService;
+
+    @Override
+    public void selectByCode(CodeQuery request, StreamObserver<RTenantDTO> responseObserver) {
+        RTenantDTO.Builder builder = RTenantDTO.newBuilder();
+        RDTO.Builder rBuilder = RDTO.newBuilder();
+        Tenant select = tenantService.selectByCode(request.getCode());
+        if (ObjectUtil.isNull(select)) {
+            rBuilder.setOk(false);
+            rBuilder.setCode(ResponseEnum.NO_RESOURCE.getCode());
+            rBuilder.setMessage(ResponseEnum.NO_RESOURCE.getMessage());
+        } else {
+            rBuilder.setOk(true);
+            rBuilder.setCode(ResponseEnum.OK.getCode());
+            rBuilder.setMessage(ResponseEnum.OK.getMessage());
+            TenantDTO tenant = buildDTOByDO(select);
+            builder.setData(tenant);
+        }
+
+        builder.setResult(rBuilder);
+        responseObserver.onNext(builder.build());
+        responseObserver.onCompleted();
+    }
+
+
+    /**
+     * DO to DTO
+     *
+     * @param entityDO Tenant
+     * @return TenantDTO
+     */
+    private TenantDTO buildDTOByDO(Tenant entityDO) {
+        TenantDTO.Builder builder = TenantDTO.newBuilder();
+        BaseDTO baseDTO = BuilderUtil.buildBaseDTOByDO(entityDO);
+        builder.setBase(baseDTO);
+        builder.setTenantName(entityDO.getTenantName());
+        builder.setTenantCode(entityDO.getTenantCode());
+        builder.setEnableFlag(EnableFlagDTOEnum.valueOf(entityDO.getEnableFlag().name()));
+        return builder.build();
+    }
+}

+ 74 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/TokenApi.java

@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.api;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import io.github.pnoker.api.center.auth.LoginQuery;
+import io.github.pnoker.api.center.auth.RTokenDTO;
+import io.github.pnoker.api.center.auth.TokenApiGrpc;
+import io.github.pnoker.api.common.RDTO;
+import io.github.pnoker.center.auth.entity.bean.TokenValid;
+import io.github.pnoker.center.auth.service.TokenService;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.github.pnoker.common.utils.TimeUtil;
+import io.grpc.stub.StreamObserver;
+import lombok.extern.slf4j.Slf4j;
+import net.devh.boot.grpc.server.service.GrpcService;
+
+import javax.annotation.Resource;
+
+/**
+ * Token Api
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@GrpcService
+public class TokenApi extends TokenApiGrpc.TokenApiImplBase {
+
+    @Resource
+    private TokenService tokenService;
+
+    @Override
+    public void checkTokenValid(LoginQuery request, StreamObserver<RTokenDTO> responseObserver) {
+        RTokenDTO.Builder builder = RTokenDTO.newBuilder();
+        RDTO.Builder rBuilder = RDTO.newBuilder();
+        TokenValid select = tokenService.checkTokenValid(request.getName(), request.getSalt(), request.getToken(), request.getTenant());
+        if (ObjectUtil.isNull(select)) {
+            rBuilder.setOk(false);
+            rBuilder.setCode(ResponseEnum.NO_RESOURCE.getCode());
+            rBuilder.setMessage(ResponseEnum.NO_RESOURCE.getMessage());
+        } else if (!select.isValid()) {
+            rBuilder.setOk(false);
+            rBuilder.setCode(ResponseEnum.TOKEN_INVALID.getCode());
+            rBuilder.setMessage(ResponseEnum.TOKEN_INVALID.getMessage());
+        } else {
+            String expireTime = TimeUtil.completeFormat(select.getExpireTime());
+            rBuilder.setOk(true);
+            rBuilder.setCode(ResponseEnum.OK.getCode());
+            rBuilder.setMessage(ResponseEnum.OK.getMessage());
+            builder.setData(expireTime);
+        }
+
+        builder.setResult(rBuilder);
+        responseObserver.onNext(builder.build());
+        responseObserver.onCompleted();
+    }
+
+}

+ 92 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/UserApi.java

@@ -0,0 +1,92 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.api;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import io.github.pnoker.api.center.auth.IdQuery;
+import io.github.pnoker.api.center.auth.RUserDTO;
+import io.github.pnoker.api.center.auth.UserApiGrpc;
+import io.github.pnoker.api.center.auth.UserDTO;
+import io.github.pnoker.api.common.BaseDTO;
+import io.github.pnoker.api.common.EnableFlagDTOEnum;
+import io.github.pnoker.api.common.RDTO;
+import io.github.pnoker.center.auth.service.UserService;
+import io.github.pnoker.common.utils.BuilderUtil;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.github.pnoker.common.model.User;
+import io.grpc.stub.StreamObserver;
+import lombok.extern.slf4j.Slf4j;
+import net.devh.boot.grpc.server.service.GrpcService;
+
+import javax.annotation.Resource;
+
+/**
+ * User Api
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@GrpcService
+public class UserApi extends UserApiGrpc.UserApiImplBase {
+
+    @Resource
+    private UserService userService;
+
+    @Override
+    public void selectById(IdQuery request, StreamObserver<RUserDTO> responseObserver) {
+        RUserDTO.Builder builder = RUserDTO.newBuilder();
+        RDTO.Builder rBuilder = RDTO.newBuilder();
+        User select = userService.selectById(request.getId());
+        if (ObjectUtil.isNull(select)) {
+            rBuilder.setOk(false);
+            rBuilder.setCode(ResponseEnum.NO_RESOURCE.getCode());
+            rBuilder.setMessage(ResponseEnum.NO_RESOURCE.getMessage());
+        } else {
+            rBuilder.setOk(true);
+            rBuilder.setCode(ResponseEnum.OK.getCode());
+            rBuilder.setMessage(ResponseEnum.OK.getMessage());
+            UserDTO user = buildDTOByDO(select);
+            builder.setData(user);
+        }
+
+        builder.setResult(rBuilder);
+        responseObserver.onNext(builder.build());
+        responseObserver.onCompleted();
+    }
+
+
+    /**
+     * DO to DTO
+     *
+     * @param entityDO User
+     * @return UserDTO
+     */
+    private UserDTO buildDTOByDO(User entityDO) {
+        UserDTO.Builder builder = UserDTO.newBuilder();
+        BaseDTO baseDTO = BuilderUtil.buildBaseDTOByDO(entityDO);
+        builder.setBase(baseDTO);
+        builder.setNickName(entityDO.getNickName());
+        builder.setUserName(entityDO.getUserName());
+        builder.setPhone(entityDO.getPhone());
+        builder.setEmail(entityDO.getEmail());
+        builder.setSocialExt(entityDO.getSocialExt());
+        builder.setIdentityExt(entityDO.getIdentityExt());
+        return builder.build();
+    }
+}

+ 90 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/api/UserLoginApi.java

@@ -0,0 +1,90 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.api;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import io.github.pnoker.api.center.auth.NameQuery;
+import io.github.pnoker.api.center.auth.RUserLoginDTO;
+import io.github.pnoker.api.center.auth.UserLoginApiGrpc;
+import io.github.pnoker.api.center.auth.UserLoginDTO;
+import io.github.pnoker.api.common.BaseDTO;
+import io.github.pnoker.api.common.EnableFlagDTOEnum;
+import io.github.pnoker.api.common.RDTO;
+import io.github.pnoker.center.auth.service.UserLoginService;
+import io.github.pnoker.common.utils.BuilderUtil;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.github.pnoker.common.model.UserLogin;
+import io.grpc.stub.StreamObserver;
+import lombok.extern.slf4j.Slf4j;
+import net.devh.boot.grpc.server.service.GrpcService;
+
+import javax.annotation.Resource;
+
+/**
+ * UserLogin Api
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@GrpcService
+public class UserLoginApi extends UserLoginApiGrpc.UserLoginApiImplBase {
+
+    @Resource
+    private UserLoginService userLoginService;
+
+    @Override
+    public void selectByName(NameQuery request, StreamObserver<RUserLoginDTO> responseObserver) {
+        RUserLoginDTO.Builder builder = RUserLoginDTO.newBuilder();
+        RDTO.Builder rBuilder = RDTO.newBuilder();
+        UserLogin select = userLoginService.selectByLoginName(request.getName(), false);
+        if (ObjectUtil.isNull(select)) {
+            rBuilder.setOk(false);
+            rBuilder.setCode(ResponseEnum.NO_RESOURCE.getCode());
+            rBuilder.setMessage(ResponseEnum.NO_RESOURCE.getMessage());
+        } else {
+            rBuilder.setOk(true);
+            rBuilder.setCode(ResponseEnum.OK.getCode());
+            rBuilder.setMessage(ResponseEnum.OK.getMessage());
+            UserLoginDTO user = buildDTOByDO(select);
+            builder.setData(user);
+        }
+
+        builder.setResult(rBuilder);
+        responseObserver.onNext(builder.build());
+        responseObserver.onCompleted();
+    }
+
+
+    /**
+     * DO to DTO
+     *
+     * @param entityDO UserLogin
+     * @return UserLoginDTO
+     */
+    private UserLoginDTO buildDTOByDO(UserLogin entityDO) {
+        UserLoginDTO.Builder builder = UserLoginDTO.newBuilder();
+        BaseDTO baseDTO = BuilderUtil.buildBaseDTOByDO(entityDO);
+        builder.setBase(baseDTO);
+        builder.setLoginName(entityDO.getLoginName());
+        builder.setUserId(entityDO.getUserId());
+        builder.setUserPasswordId(entityDO.getUserPasswordId());
+        builder.setEnableFlag(EnableFlagDTOEnum.valueOf(entityDO.getEnableFlag().name()));
+        return builder.build();
+    }
+}

+ 177 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/BlackIpController.java

@@ -0,0 +1,177 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.BlackIpPageQuery;
+import io.github.pnoker.center.auth.service.BlackIpService;
+import io.github.pnoker.common.constant.service.AuthServiceConstant;
+import io.github.pnoker.common.entity.R;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.github.pnoker.common.model.BlackIp;
+import io.github.pnoker.common.valid.Insert;
+import io.github.pnoker.common.valid.Update;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+
+/**
+ * Ip 黑名单 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(value = AuthServiceConstant.BLACK_IP_URL_PREFIX)
+public class BlackIpController {
+
+    @Resource
+    private BlackIpService blackIpService;
+
+    /**
+     * 新增 BlackIp
+     *
+     * @param blackIp BlackIp
+     * @return {@link BlackIp}
+     */
+    @PostMapping("/add")
+    public R<String> add(@Validated(Insert.class) @RequestBody BlackIp blackIp) {
+        try {
+            blackIpService.add(blackIp);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 ID 删除 BlackIp
+     *
+     * @param id ID
+     * @return 是否删除
+     */
+    @PostMapping("/delete/{id}")
+    public R<String> delete(@NotNull @PathVariable(value = "id") String id) {
+        try {
+            blackIpService.delete(id);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 修改 BlackIp
+     * <ol>
+     * <li>支持修改: Enable</li>
+     * <li>不支持修改: Ip</li>
+     * </ol>
+     *
+     * @param blackIp BlackIp
+     * @return {@link BlackIp}
+     */
+    @PostMapping("/update")
+    public R<String> update(@Validated(Update.class) @RequestBody BlackIp blackIp) {
+        try {
+            blackIpService.update(blackIp);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 ID 查询 BlackIp
+     *
+     * @param id ID
+     * @return {@link BlackIp}
+     */
+    @GetMapping("/id/{id}")
+    public R<BlackIp> selectById(@NotNull @PathVariable(value = "id") String id) {
+        try {
+            BlackIp select = blackIpService.selectById(id);
+            if (ObjectUtil.isNotNull(select)) {
+                return R.ok(select);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+    /**
+     * 根据 Ip 查询 BlackIp
+     *
+     * @param ip Black Ip
+     * @return {@link BlackIp}
+     */
+    @GetMapping("/ip/{ip}")
+    public R<BlackIp> selectByIp(@NotNull @PathVariable(value = "ip") String ip) {
+        try {
+            BlackIp select = blackIpService.selectByIp(ip, false);
+            if (ObjectUtil.isNotNull(select)) {
+                return R.ok(select);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+    /**
+     * 模糊分页查询 BlackIp
+     *
+     * @param blackIpPageQuery BlackIp和分页参数
+     * @return 带分页的 {@link BlackIp}
+     */
+    @PostMapping("/list")
+    public R<Page<BlackIp>> list(@RequestBody(required = false) BlackIpPageQuery blackIpPageQuery) {
+        try {
+            if (ObjectUtil.isEmpty(blackIpPageQuery)) {
+                blackIpPageQuery = new BlackIpPageQuery();
+            }
+            Page<BlackIp> page = blackIpService.list(blackIpPageQuery);
+            if (ObjectUtil.isNotNull(page)) {
+                return R.ok(page);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+    /**
+     * 检测 Ip 是否在 Ip 黑名单列表
+     *
+     * @param ip Black Ip
+     * @return 当前IP是否在黑名单中
+     */
+    @GetMapping("/check/{ip}")
+    public R<Boolean> checkBlackIpValid(@NotNull @PathVariable(value = "ip") String ip) {
+        try {
+            return Boolean.TRUE.equals(blackIpService.checkBlackIpValid(ip)) ? R.ok() : R.fail();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+}

+ 105 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/DictionaryController.java

@@ -0,0 +1,105 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import io.github.pnoker.center.auth.service.DictionaryService;
+import io.github.pnoker.common.constant.common.DefaultConstant;
+import io.github.pnoker.common.constant.common.RequestConstant;
+import io.github.pnoker.common.constant.service.AuthServiceConstant;
+import io.github.pnoker.common.entity.R;
+import io.github.pnoker.common.entity.common.Dictionary;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 字典 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(AuthServiceConstant.DICTIONARY_URL_PREFIX)
+public class DictionaryController {
+
+    @Resource
+    private DictionaryService dictionaryService;
+
+    /**
+     * 查询租户字典列表
+     *
+     * @return 字典列表
+     */
+    @GetMapping("/tenant")
+    public R<List<Dictionary>> tenantDictionary() {
+        try {
+            List<Dictionary> dictionaryList = dictionaryService.tenantDictionary();
+            if (ObjectUtil.isNotNull(dictionaryList)) {
+                return R.ok(dictionaryList);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail();
+    }
+
+    /**
+     * 查询用户字典列表
+     *
+     * @param tenantId 租户ID
+     * @return 字典列表
+     */
+    @GetMapping("/user")
+    public R<List<Dictionary>> userDictionary(@RequestHeader(value = RequestConstant.Header.X_AUTH_TENANT_ID, defaultValue = DefaultConstant.DEFAULT_ID) String tenantId) {
+        try {
+            List<Dictionary> dictionaryList = dictionaryService.userDictionary(tenantId);
+            if (ObjectUtil.isNotNull(dictionaryList)) {
+                return R.ok(dictionaryList);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail();
+    }
+
+    /**
+     * 查询 Ip 黑名单字典列表
+     *
+     * @param tenantId 租户ID
+     * @return 字典列表
+     */
+    @GetMapping("/black_ip")
+    public R<List<Dictionary>> blackIpDictionary(@RequestHeader(value = RequestConstant.Header.X_AUTH_TENANT_ID, defaultValue = DefaultConstant.DEFAULT_ID) String tenantId) {
+        try {
+            List<Dictionary> dictionaryList = dictionaryService.blackIpDictionary(tenantId);
+            if (ObjectUtil.isNotNull(dictionaryList)) {
+                return R.ok(dictionaryList);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail();
+    }
+
+}

+ 43 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/IndexController.java

@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Index Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+//@RequestMapping(value = AuthServiceConstant.INDEX_URL_PREFIX)
+public class IndexController {
+
+    /**
+     * ping
+     *
+     * @return DataTime
+     */
+    /*@GetMapping("/ping")
+    public R<String> ping() {
+        return R.ok(TimeUtil.defaultFormat(new Date()));
+    }*/
+
+}

+ 163 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/TenantController.java

@@ -0,0 +1,163 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.TenantPageQuery;
+import io.github.pnoker.center.auth.service.TenantService;
+import io.github.pnoker.common.constant.service.AuthServiceConstant;
+import io.github.pnoker.common.entity.R;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.github.pnoker.common.model.Tenant;
+import io.github.pnoker.common.valid.Insert;
+import io.github.pnoker.common.valid.Update;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 用户 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(AuthServiceConstant.TENANT_URL_PREFIX)
+public class TenantController {
+
+    @Resource
+    private TenantService tenantService;
+
+    /**
+     * 新增租户
+     *
+     * @param tenant 租户
+     * @return {@link Tenant}
+     */
+    @PostMapping("/add")
+    public R<String> add(@Validated(Insert.class) @RequestBody Tenant tenant) {
+        try {
+            tenantService.add(tenant);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 ID 删除租户
+     *
+     * @param id 租户ID
+     * @return 是否删除
+     */
+    @PostMapping("/delete/{id}")
+    public R<String> delete(@NotNull @PathVariable(value = "id") String id) {
+        try {
+            tenantService.delete(id);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 ID 修改租户
+     * <ol>
+     * <li>支持修改: Enable</li>
+     * <li>不支持修改: Name</li>
+     * </ol>
+     *
+     * @param tenant Tenant
+     * @return {@link Tenant}
+     */
+    @PostMapping("/update")
+    public R<String> update(@Validated(Update.class) @RequestBody Tenant tenant) {
+        try {
+            tenant.setTenantName(null);
+            tenantService.update(tenant);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 ID 查询租户
+     *
+     * @param id 租户ID
+     * @return {@link Tenant}
+     */
+    @GetMapping("/id/{id}")
+    public R<Tenant> selectById(@NotNull @PathVariable(value = "id") String id) {
+        try {
+            Tenant select = tenantService.selectById(id);
+            if (ObjectUtil.isNotNull(select)) {
+                return R.ok(select);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+    /**
+     * 根据 Code 查询租户
+     *
+     * @param code 租户Code
+     * @return {@link Tenant}
+     */
+    @GetMapping("/code/{code}")
+    public R<Tenant> selectByCode(@NotNull @PathVariable(value = "code") String code) {
+        try {
+            Tenant select = tenantService.selectByCode(code);
+            if (ObjectUtil.isNotNull(select)) {
+                return R.ok(select);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+    /**
+     * 模糊分页查询租户
+     *
+     * @param tenantPageQuery 租户和分页参数
+     * @return 带分页的 {@link Tenant}
+     */
+    @PostMapping("/list")
+    public R<Page<Tenant>> list(@RequestBody(required = false) TenantPageQuery tenantPageQuery) {
+        try {
+            if (ObjectUtil.isEmpty(tenantPageQuery)) {
+                tenantPageQuery = new TenantPageQuery();
+            }
+            Page<Tenant> page = tenantService.list(tenantPageQuery);
+            if (ObjectUtil.isNotNull(page)) {
+                return R.ok(page);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+}

+ 103 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/TokenController.java

@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import io.github.pnoker.center.auth.entity.bean.TokenValid;
+import io.github.pnoker.center.auth.service.TokenService;
+import io.github.pnoker.common.constant.service.AuthServiceConstant;
+import io.github.pnoker.common.entity.R;
+import io.github.pnoker.common.entity.auth.Login;
+import io.github.pnoker.common.exception.UnAuthorizedException;
+import io.github.pnoker.common.utils.TimeUtil;
+import io.github.pnoker.common.valid.Auth;
+import io.github.pnoker.common.valid.Check;
+import io.github.pnoker.common.valid.Update;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 令牌 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(AuthServiceConstant.TOKEN_URL_PREFIX)
+public class TokenController {
+
+    @Resource
+    private TokenService tokenService;
+
+    /**
+     * 生成用户随机盐值
+     *
+     * @param login 登录信息
+     * @return 盐值
+     */
+    @PostMapping("/salt")
+    public R<String> generateSalt(@Validated(Update.class) @RequestBody Login login) {
+        String salt = tokenService.generateSalt(login.getName(), login.getTenant());
+        return ObjectUtil.isNotNull(salt) ? R.ok(salt, "The salt will expire in 5 minutes") : R.fail();
+    }
+
+    /**
+     * 生成用户 Token 令牌
+     *
+     * @param login 登录信息
+     * @return Token 令牌
+     */
+    @PostMapping("/generate")
+    public R<String> generateToken(@Validated(Auth.class) @RequestBody Login login) {
+        String token = tokenService.generateToken(login.getName(), login.getSalt(), login.getPassword(), login.getTenant());
+        return ObjectUtil.isNotNull(token) ? R.ok(token, "The token will expire in 12 hours.") : R.fail();
+    }
+
+    /**
+     * 检测用户 Token 令牌是否有效
+     *
+     * @param login 登录信息
+     * @return 如果有效,返回过期时间
+     */
+    @PostMapping("/check")
+    public R<String> checkTokenValid(@Validated(Check.class) @RequestBody Login login) {
+        TokenValid tokenValid = tokenService.checkTokenValid(login.getName(), login.getSalt(), login.getToken(), login.getTenant());
+        if (tokenValid.isValid()) {
+            String expireTime = TimeUtil.completeFormat(tokenValid.getExpireTime());
+            return R.ok(expireTime, "The token will expire in " + expireTime);
+        }
+        throw new UnAuthorizedException("Token invalid");
+    }
+
+    /**
+     * 注销用户的Token令牌
+     *
+     * @param login 登录信息
+     * @return 是否注销
+     */
+    @PostMapping("/cancel")
+    public R<Boolean> cancelToken(@Validated(Update.class) @RequestBody Login login) {
+        return Boolean.TRUE.equals(tokenService.cancelToken(login.getName(), login.getTenant())) ? R.ok() : R.fail();
+    }
+}

+ 197 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/controller/UserLoginController.java

@@ -0,0 +1,197 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.UserLoginPageQuery;
+import io.github.pnoker.center.auth.service.UserLoginService;
+import io.github.pnoker.center.auth.service.UserPasswordService;
+import io.github.pnoker.common.constant.service.AuthServiceConstant;
+import io.github.pnoker.common.entity.R;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.github.pnoker.common.model.UserLogin;
+import io.github.pnoker.common.valid.Insert;
+import io.github.pnoker.common.valid.Update;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 用户 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(AuthServiceConstant.USER_URL_PREFIX)
+public class UserLoginController {
+
+    @Resource
+    private UserLoginService userLoginService;
+    @Resource
+    private UserPasswordService userPasswordService;
+
+    /**
+     * 新增用户
+     *
+     * @param userLogin 用户
+     * @return {@link UserLogin}
+     */
+    @PostMapping("/add")
+    public R<String> add(@Validated(Insert.class) @RequestBody UserLogin userLogin) {
+        try {
+            userLoginService.add(userLogin);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 ID 删除用户
+     *
+     * @param id 用户ID
+     * @return 是否删除
+     */
+    @PostMapping("/delete/{id}")
+    public R<String> delete(@NotNull @PathVariable(value = "id") String id) {
+        try {
+            userLoginService.delete(id);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 修改用户
+     * <ol>
+     * <li>支持修改: Enable,Password</li>
+     * <li>不支持修改: Name</li>
+     * </ol>
+     *
+     * @param userLogin 用户
+     * @return {@link UserLogin}
+     */
+    @PostMapping("/update")
+    public R<String> update(@Validated(Update.class) @RequestBody UserLogin userLogin) {
+        try {
+            userLogin.setLoginName(null);
+            userLoginService.update(userLogin);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 ID 重置用户密码
+     *
+     * @param id 用户ID
+     * @return 是否重置
+     */
+    @PostMapping("/reset/{id}")
+    public R<Boolean> restPassword(@NotNull @PathVariable(value = "id") String id) {
+        try {
+            userPasswordService.restPassword(id);
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 ID 查询用户
+     *
+     * @param id 用户ID
+     * @return {@link UserLogin}
+     */
+    @GetMapping("/id/{id}")
+    public R<UserLogin> selectById(@NotNull @PathVariable(value = "id") String id) {
+        try {
+            UserLogin select = userLoginService.selectById(id);
+            if (ObjectUtil.isNotNull(select)) {
+                return R.ok(select);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+    /**
+     * 根据 Name 查询 User
+     *
+     * @param name 用户名称
+     * @return {@link UserLogin}
+     */
+    @GetMapping("/name/{name}")
+    public R<UserLogin> selectByName(@NotNull @PathVariable(value = "name") String name) {
+        try {
+            UserLogin select = userLoginService.selectByLoginName(name, false);
+            if (ObjectUtil.isNotNull(select)) {
+                return R.ok(select);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+    /**
+     * 模糊分页查询 User
+     *
+     * @param userPageQuery 用户和分页参数
+     * @return 带分页的 {@link UserLogin}
+     */
+    @PostMapping("/list")
+    public R<Page<UserLogin>> list(@RequestBody(required = false) UserLoginPageQuery userPageQuery) {
+        try {
+            if (ObjectUtil.isEmpty(userPageQuery)) {
+                userPageQuery = new UserLoginPageQuery();
+            }
+            Page<UserLogin> page = userLoginService.list(userPageQuery);
+            if (ObjectUtil.isNotNull(page)) {
+                return R.ok(page);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail(ResponseEnum.NO_RESOURCE.getMessage());
+    }
+
+    /**
+     * 检测登录名称是否有效
+     *
+     * @param name 用户名称
+     * @return 是否有效
+     */
+    @GetMapping("/check/{name}")
+    public R<Boolean> checkLoginNameValid(@NotNull @PathVariable(value = "name") String name) {
+        try {
+            return Boolean.TRUE.equals(userLoginService.checkLoginNameValid(name)) ? R.ok() : R.fail();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+}

+ 34 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/bean/AuthHeader.java

@@ -0,0 +1,34 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AuthHeader {
+    private String user;
+    private String salt;
+    private String token;
+}

+ 35 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/bean/TokenValid.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TokenValid {
+    private boolean valid;
+    private Date expireTime;
+}

+ 44 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/bean/UserLimit.java

@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 用户登录限制
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UserLimit {
+    /**
+     * 登录验证错误次数
+     */
+    private Integer times;
+
+    /**
+     * 限制失效时间
+     */
+    private Date expireTime;
+}

+ 61 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/bo/UserLoginBO.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.bo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.base.BaseBO;
+import io.github.pnoker.common.enums.EnableFlagEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * User
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@SuperBuilder
+@RequiredArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_DEFAULT)
+public class UserLoginBO extends BaseBO {
+
+    /**
+     * 登录名称
+     */
+    private String loginName;
+
+    /**
+     * 用户ID
+     */
+    private String userId;
+
+    /**
+     * 用户密码ID
+     */
+    private String userPasswordId;
+
+    /**
+     * 使能标识
+     */
+    private EnableFlagEnum enableFlag;
+}

+ 98 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/builder/UserLoginBuilder.java

@@ -0,0 +1,98 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.builder;
+
+import io.github.pnoker.center.auth.entity.bo.UserLoginBO;
+import io.github.pnoker.center.auth.entity.vo.UserLoginVO;
+import io.github.pnoker.common.model.UserLogin;
+import org.mapstruct.Mapper;
+
+import java.util.List;
+
+/**
+ * User Builder
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Mapper(componentModel = "spring")
+public interface UserLoginBuilder {
+
+    /**
+     * VO to BO
+     *
+     * @param entityVO EntityVO
+     * @return EntityBO
+     */
+    UserLoginBO buildBOByVO(UserLoginVO entityVO);
+
+    /**
+     * VOList to BOList
+     *
+     * @param entityVOList EntityVO Array
+     * @return EntityBO Array
+     */
+    List<UserLoginBO> buildBOListByVOList(List<UserLoginVO> entityVOList);
+
+    /**
+     * BO to DO
+     *
+     * @param entityBO EntityBO
+     * @return EntityDO
+     */
+    UserLogin buildDOByBO(UserLoginBO entityBO);
+
+    /**
+     * BOList to DOList
+     *
+     * @param entityBOList EntityBO Array
+     * @return EntityDO Array
+     */
+    List<UserLogin> buildDOListByBOList(List<UserLoginBO> entityBOList);
+
+    /**
+     * DO to BO
+     *
+     * @param entityDO EntityDO
+     * @return EntityBO
+     */
+    UserLoginBO buildBOByDO(UserLogin entityDO);
+
+    /**
+     * DOList to BOList
+     *
+     * @param entityDOList EntityDO Array
+     * @return EntityBO Array
+     */
+    List<UserLoginBO> buildBOByDO(List<UserLogin> entityDOList);
+
+    /**
+     * BO to VO
+     *
+     * @param entityBO EntityBO
+     * @return EntityVO
+     */
+    UserLoginVO buildVOByBO(UserLoginBO entityBO);
+
+    /**
+     * BOList to VOList
+     *
+     * @param entityBOList EntityBO Array
+     * @return EntityVO Array
+     */
+    List<UserLoginVO> buildVOListByBOList(List<UserLoginBO> entityBOList);
+}

+ 39 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/BlackIpPageQuery.java

@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.BlackIp;
+import lombok.*;
+
+/**
+ * BlackIp DTO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class BlackIpPageQuery extends BlackIp {
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 21 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/ResourcePageQuery.java

@@ -0,0 +1,21 @@
+package io.github.pnoker.center.auth.entity.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.Resource;
+import lombok.*;
+
+/**
+ * @author linys
+ * @since 2023.04.02
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class ResourcePageQuery extends Resource {
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 21 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/RoleResourceBindPageQuery.java

@@ -0,0 +1,21 @@
+package io.github.pnoker.center.auth.entity.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.RoleResourceBind;
+import lombok.*;
+
+/**
+ * @author linys
+ * @since 2023.04.02
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class RoleResourceBindPageQuery extends RoleResourceBind {
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 21 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/RoleUserBindPageQuery.java

@@ -0,0 +1,21 @@
+package io.github.pnoker.center.auth.entity.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.RoleUserBind;
+import lombok.*;
+
+/**
+ * @author linys
+ * @since 2023.04.02
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class RoleUserBindPageQuery extends RoleUserBind {
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 39 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/TenantBindPageQuery.java

@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.TenantBind;
+import lombok.*;
+
+/**
+ * TenantBind DTO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class TenantBindPageQuery extends TenantBind {
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 37 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/TenantPageQuery.java

@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.query;
+
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.Tenant;
+import lombok.*;
+
+/**
+ * User DTO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class TenantPageQuery extends Tenant {
+
+    private Pages page;
+}

+ 37 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/UserDto.java

@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.query;
+
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.User;
+import lombok.*;
+
+/**
+ * User DTO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class UserDto extends User {
+
+    private Pages page;
+}

+ 37 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/UserLoginPageQuery.java

@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.query;
+
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.UserLogin;
+import lombok.*;
+
+/**
+ * User DTO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class UserLoginPageQuery extends UserLogin {
+
+    private Pages page;
+}

+ 37 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/query/UserPasswordPageQuery.java

@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.query;
+
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.UserPassword;
+import lombok.*;
+
+/**
+ * UserPassword DTO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class UserPasswordPageQuery extends UserPassword {
+
+    private Pages page;
+}

+ 61 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/entity/vo/UserLoginVO.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.base.BaseVO;
+import io.github.pnoker.common.enums.EnableFlagEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * User
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@SuperBuilder
+@RequiredArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_DEFAULT)
+public class UserLoginVO extends BaseVO {
+
+    /**
+     * 登录名称
+     */
+    private String loginName;
+
+    /**
+     * 用户ID
+     */
+    private String userId;
+
+    /**
+     * 用户密码ID
+     */
+    private String userPasswordId;
+
+    /**
+     * 使能标识
+     */
+    private EnableFlagEnum enableFlag;
+}

+ 31 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/BlackIpMapper.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.BlackIp;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * Mapper
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Mapper
+public interface BlackIpMapper extends BaseMapper<BlackIp> {
+}

+ 15 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/ResourceMapper.java

@@ -0,0 +1,15 @@
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.Resource;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * resource mapper
+ *
+ * @author linys
+ * @since 2023.04.02
+ */
+@Mapper
+public interface ResourceMapper extends BaseMapper<Resource> {
+}

+ 15 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/RoleMapper.java

@@ -0,0 +1,15 @@
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.Role;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * Role Mapper
+ *
+ * @author linys
+ * @since 2023.04.02
+ */
+@Mapper
+public interface RoleMapper extends BaseMapper<Role> {
+}

+ 15 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/RoleResourceBindMapper.java

@@ -0,0 +1,15 @@
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.RoleResourceBind;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * role resource mapper
+ *
+ * @author linys
+ * @since 2023.04.02
+ */
+@Mapper
+public interface RoleResourceBindMapper extends BaseMapper<RoleResourceBind> {
+}

+ 13 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/RoleUserBindMapper.java

@@ -0,0 +1,13 @@
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.RoleUserBind;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author linys
+ * @since 2023.04.02
+ */
+@Mapper
+public interface RoleUserBindMapper extends BaseMapper<RoleUserBind> {
+}

+ 31 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/TenantBindMapper.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.TenantBind;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * Mapper
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Mapper
+public interface TenantBindMapper extends BaseMapper<TenantBind> {
+}

+ 31 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/TenantMapper.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.Tenant;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * Mapper
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Mapper
+public interface TenantMapper extends BaseMapper<Tenant> {
+}

+ 31 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/UserLoginMapper.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.UserLogin;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * Mapper
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Mapper
+public interface UserLoginMapper extends BaseMapper<UserLogin> {
+}

+ 31 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/UserMapper.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.User;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * Mapper
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Mapper
+public interface UserMapper extends BaseMapper<User> {
+}

+ 31 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/mapper/UserPasswordMapper.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.model.UserPassword;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * Mapper
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Mapper
+public interface UserPasswordMapper extends BaseMapper<UserPassword> {
+}

+ 35 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/AuthService.java

@@ -0,0 +1,35 @@
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.common.entity.auth.Login;
+import io.github.pnoker.common.model.AuthUser;
+import io.github.pnoker.common.model.UserLogin;
+
+/**
+ * User Manage Service
+ *
+ * @author: linys
+ * @since: 2023.04.02
+ */
+public interface AuthService {
+
+    /**
+     * 鉴定用户, 并返回token
+     *
+     * @param login login info
+     * @return UserLogin userLogin
+     */
+    UserLogin authenticateUser(Login login);
+
+    /**
+     * 用户登录
+     *
+     * @param login 登录参数
+     * @return AuthUser
+     */
+    AuthUser login(Login login);
+
+    /**
+     * 当前用户退出登录
+     */
+    void logout();
+}

+ 46 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/BlackIpService.java

@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.BlackIpPageQuery;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.BlackIp;
+
+/**
+ * User Interface
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+public interface BlackIpService extends Service<BlackIp, BlackIpPageQuery> {
+    /**
+     * 根据 Ip 查询 BlackIp
+     *
+     * @param ip             IP
+     * @param throwException Throw Exception
+     * @return BlackIp
+     */
+    BlackIp selectByIp(String ip, boolean throwException);
+
+    /**
+     * 根据 Ip 是否在Ip黑名单列表
+     *
+     * @param ip IP
+     * @return boolean
+     */
+    Boolean checkBlackIpValid(String ip);
+}

+ 54 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/DictionaryService.java

@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.common.entity.common.Dictionary;
+
+import java.util.List;
+
+/**
+ * Dictionary Interface
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+public interface DictionaryService {
+
+    /**
+     * 获取租户字典
+     *
+     * @return Dictionary Array
+     */
+    List<Dictionary> tenantDictionary();
+
+    /**
+     * 获取用户字典
+     *
+     * @param tenantId 租户ID
+     * @return Dictionary Array
+     */
+    List<Dictionary> userDictionary(String tenantId);
+
+    /**
+     * 获取 Ip 黑名单字典
+     *
+     * @param tenantId 租户ID
+     * @return Dictionary Array
+     */
+    List<Dictionary> blackIpDictionary(String tenantId);
+
+}

+ 14 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/ResourceService.java

@@ -0,0 +1,14 @@
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.ResourcePageQuery;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.Resource;
+
+/**
+ * resource service
+ *
+ * @author linys
+ * @since 2023.04.02
+ */
+public interface ResourceService extends Service<Resource, ResourcePageQuery> {
+}

+ 25 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/RoleResourceBindService.java

@@ -0,0 +1,25 @@
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.RoleResourceBindPageQuery;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.Resource;
+import io.github.pnoker.common.model.RoleResourceBind;
+
+import java.util.List;
+
+/**
+ * role resource bind service
+ *
+ * @author linys
+ * @since 2023.04.02
+ */
+public interface RoleResourceBindService extends Service<RoleResourceBind, RoleResourceBindPageQuery> {
+
+    /**
+     * 根据TenantId与UserId查询资源
+     *
+     * @param roleId 角色id
+     * @return 资源列表
+     */
+    List<Resource> listResourceByRoleId(String roleId);
+}

+ 26 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/RoleUserBindService.java

@@ -0,0 +1,26 @@
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.RoleUserBindPageQuery;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.Role;
+import io.github.pnoker.common.model.RoleUserBind;
+
+import java.util.List;
+
+/**
+ * role user mapper service
+ *
+ * @author linys
+ * @since 2023.04.02
+ */
+public interface RoleUserBindService extends Service<RoleUserBind, RoleUserBindPageQuery> {
+
+    /**
+     * 根据 租户id 和 用户id 查询
+     *
+     * @param tenantId 租户id
+     * @param userId   用户id
+     * @return Role list
+     */
+    List<Role> listRoleByTenantIdAndUserId(String tenantId, String userId);
+}

+ 39 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/TenantBindService.java

@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.TenantBindPageQuery;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.TenantBind;
+
+/**
+ * TenantBind Interface
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+public interface TenantBindService extends Service<TenantBind, TenantBindPageQuery> {
+
+    /**
+     * 根据 租户ID 和 关联的用户ID 查询
+     *
+     * @param tenantId 租户ID
+     * @param userId   User ID
+     * @return TenantBind
+     */
+    TenantBind selectByTenantIdAndUserId(String tenantId, String userId);
+}

+ 38 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/TenantService.java

@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.TenantPageQuery;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.Tenant;
+
+/**
+ * Tenant Interface
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+public interface TenantService extends Service<Tenant, TenantPageQuery> {
+
+    /**
+     * 根据租户Code查询租户
+     *
+     * @param code 租户Code
+     * @return {@link Tenant}
+     */
+    Tenant selectByCode(String code);
+}

+ 67 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/TokenService.java

@@ -0,0 +1,67 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.bean.TokenValid;
+
+/**
+ * Token Interface
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+public interface TokenService {
+    /**
+     * 生成用户的随机 salt
+     *
+     * @param username   用户名称
+     * @param tenantName 租户名称
+     * @return String
+     */
+    String generateSalt(String username, String tenantName);
+
+    /**
+     * 生成用户的Token令牌
+     *
+     * @param username   用户名称
+     * @param salt       User Salt
+     * @param password   User Password
+     * @param tenantName 租户名称
+     * @return String
+     */
+    String generateToken(String username, String salt, String password, String tenantName);
+
+    /**
+     * 校验用户的Token令牌是否有效
+     *
+     * @param username   用户名称
+     * @param salt       盐值
+     * @param token      Token
+     * @param tenantName 租户名称
+     * @return TokenValid
+     */
+    TokenValid checkTokenValid(String username, String salt, String token, String tenantName);
+
+    /**
+     * 注销用户的Token令牌
+     *
+     * @param username   用户名称
+     * @param tenantName 租户名称
+     * @return 是否注销
+     */
+    Boolean cancelToken(String username, String tenantName);
+}

+ 47 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/UserLoginService.java

@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.UserLoginPageQuery;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.UserLogin;
+
+/**
+ * User Interface
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+public interface UserLoginService extends Service<UserLogin, UserLoginPageQuery> {
+
+    /**
+     * 根据登录名称查询用户
+     *
+     * @param loginName      登录名称
+     * @param throwException Throw Exception
+     * @return User
+     */
+    UserLogin selectByLoginName(String loginName, boolean throwException);
+
+    /**
+     * 判断登录名称是否有效
+     *
+     * @param loginName 登录名称
+     * @return Boolean
+     */
+    boolean checkLoginNameValid(String loginName);
+}

+ 37 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/UserPasswordService.java

@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.UserPasswordPageQuery;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.UserPassword;
+
+/**
+ * UserPassword Interface
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+public interface UserPasswordService extends Service<UserPassword, UserPasswordPageQuery> {
+
+    /**
+     * 重置密码
+     *
+     * @param id ID
+     */
+    void restPassword(String id);
+}

+ 57 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/UserService.java

@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service;
+
+import io.github.pnoker.center.auth.entity.query.UserDto;
+import io.github.pnoker.common.base.Service;
+import io.github.pnoker.common.model.User;
+
+/**
+ * User Interface
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+public interface UserService extends Service<User, UserDto> {
+
+    /**
+     * 根据用户名称查询用户
+     *
+     * @param userName       用户名称
+     * @param throwException Throw Exception
+     * @return User
+     */
+    User selectByUserName(String userName, boolean throwException);
+
+    /**
+     * 根据手机号查询用户
+     *
+     * @param phone          Phone
+     * @param throwException Throw Exception
+     * @return User
+     */
+    User selectByPhone(String phone, boolean throwException);
+
+    /**
+     * 根据邮箱查询用户
+     *
+     * @param email          Email
+     * @param throwException Throw Exception
+     * @return User
+     */
+    User selectByEmail(String email, boolean throwException);
+}

+ 134 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/AuthServiceImpl.java

@@ -0,0 +1,134 @@
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import io.github.pnoker.center.auth.service.*;
+import io.github.pnoker.common.entity.auth.Login;
+import io.github.pnoker.common.exception.NotFoundException;
+import io.github.pnoker.common.exception.ServiceException;
+import io.github.pnoker.common.model.*;
+import io.github.pnoker.common.utils.AuthUtil;
+import io.github.pnoker.common.utils.DecodeUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 用户管理实现类
+ *
+ * @author linys
+ * @since 2023.04.02
+ */
+@Slf4j
+@Service
+public class AuthServiceImpl implements AuthService {
+
+    @Resource
+    private TenantService tenantService;
+
+    @Resource
+    private TenantBindService tenantBindService;
+
+    @Resource
+    private UserLoginService userLoginService;
+
+    @Resource
+    private UserPasswordService userPasswordService;
+
+    @Resource
+    private RoleUserBindService roleUserBindService;
+
+    @Resource
+    private RoleResourceBindService roleResourceBindService;
+
+    @Override
+    public UserLogin authenticateUser(Login login) {
+        Tenant tenant = tenantService.selectByCode(login.getTenant());
+        if (ObjectUtil.isNull(tenant)) {
+            throw new NotFoundException("租户{}不存在", login.getTenant());
+        }
+
+        //todo checkUserLimit
+
+        UserLogin userLogin = userLoginService.selectByLoginName(login.getName(), false);
+        if (ObjectUtil.isNull(userLogin)) {
+            throw new NotFoundException("用户{}不存在", login.getName());
+        }
+
+        TenantBind tenantBind = tenantBindService.selectByTenantIdAndUserId(tenant.getId(), userLogin.getUserId());
+        if (ObjectUtil.isNull(tenantBind)) {
+            throw new NotFoundException("租户、用户信息不匹配");
+        }
+
+        UserPassword userPassword = userPasswordService.selectById(userLogin.getUserPasswordId());
+        if (ObjectUtil.isNull(userPassword)) {
+            throw new NotFoundException("密码不存在,请先设置密码");
+        }
+
+        String saltValue = AuthUtil.getPasswordSalt(tenant.getId(), login.getName());
+        if (CharSequenceUtil.isEmpty(saltValue)) {
+            throw new NotFoundException("密码盐不存在,请重新登录");
+        }
+
+        String decodedPassword = DecodeUtil.md5(userPassword.getLoginPassword() + saltValue);
+        if (saltValue.equals(login.getSalt()) && decodedPassword.equals(login.getPassword())) {
+            //create and save token
+            String token = AuthUtil.createToken(tenant.getId(), login.getName(), saltValue);
+            login.setToken(token);
+            return userLogin;
+        }
+
+        //todo updateUserLimit
+        return null;
+    }
+
+    @Override
+    public AuthUser login(Login login) {
+        //1. authenticate user
+        UserLogin userLogin = authenticateUser(login);
+        if (ObjectUtil.isNull(userLogin)) {
+            throw new ServiceException("认证失败!请重试");
+        }
+
+        //2. save AuthUser
+        AuthUser authUser = new AuthUser();
+        authUser.setUserId(userLogin.getUserId());
+        authUser.setUserName(userLogin.getLoginName());
+        Tenant tenant = tenantService.selectByCode(login.getTenant());
+        authUser.setTenantId(tenant.getId());
+
+        //2.1 roles
+        List<Role> roles = roleUserBindService.listRoleByTenantIdAndUserId(tenant.getId(), userLogin.getUserId());
+        if (CollUtil.isEmpty(roles)) {
+            throw new ServiceException("请先为用户{}分配角色", login.getName());
+        }
+        Set<String> roleCodeSet = roles.stream().map(Role::getRoleCode).collect(Collectors.toSet());
+        authUser.setRoleCodeSet(roleCodeSet);
+
+        //2.2 resources
+        Set<io.github.pnoker.common.model.Resource> resourceSet = new HashSet<>();
+        for (Role role : roles) {
+            List<io.github.pnoker.common.model.Resource> resources = roleResourceBindService.listResourceByRoleId(role.getId());
+            resourceSet.addAll(resources);
+        }
+        if (CollUtil.isEmpty(resourceSet)) {
+            throw new ServiceException("请先为用户{}分配权限", login.getName());
+        }
+        Set<String> resourceCodeSet = resourceSet.stream().map(io.github.pnoker.common.model.Resource::getResourceCode).collect(Collectors.toSet());
+        authUser.setResourceCodeSet(resourceCodeSet);
+
+        AuthUtil.saveTokenToAuthUserMap(login.getToken(), authUser);
+        return authUser;
+    }
+
+    @Override
+    public void logout() {
+        AuthUtil.logout();
+    }
+}

+ 124 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/BlackIpServiceImpl.java

@@ -0,0 +1,124 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.BlackIpPageQuery;
+import io.github.pnoker.center.auth.mapper.BlackIpMapper;
+import io.github.pnoker.center.auth.service.BlackIpService;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.enums.EnableFlagEnum;
+import io.github.pnoker.common.exception.*;
+import io.github.pnoker.common.model.BlackIp;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * 用户服务接口实现类
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Service
+public class BlackIpServiceImpl implements BlackIpService {
+
+    @Resource
+    private BlackIpMapper blackIpMapper;
+
+    @Override
+    public void add(BlackIp entityDO) {
+        BlackIp select = selectByIp(entityDO.getIp(), false);
+        if (ObjectUtil.isNotNull(select)) {
+            throw new DuplicateException("The ip already exists in the blacklist");
+        }
+
+        if (blackIpMapper.insert(entityDO) < 1) {
+            throw new AddException("The ip {} add to the blacklist failed", entityDO.getIp());
+        }
+    }
+
+    @Override
+    public void delete(String id) {
+        BlackIp blackIp = selectById(id);
+        if (ObjectUtil.isNull(blackIp)) {
+            throw new NotFoundException("The ip does not exist in the blacklist");
+        }
+
+        if (blackIpMapper.deleteById(id) < 1) {
+            throw new DeleteException("The ip delete failed");
+        }
+    }
+
+    @Override
+    public void update(BlackIp entityDO) {
+        entityDO.setIp(null);
+        entityDO.setOperateTime(null);
+        if (blackIpMapper.updateById(entityDO) < 1) {
+            throw new UpdateException("The ip update failed in the blacklist");
+        }
+    }
+
+    @Override
+    public BlackIp selectById(String id) {
+        return blackIpMapper.selectById(id);
+    }
+
+    @Override
+    public BlackIp selectByIp(String ip, boolean throwException) {
+        LambdaQueryWrapper<BlackIp> queryWrapper = Wrappers.<BlackIp>query().lambda();
+        queryWrapper.eq(BlackIp::getIp, ip);
+        queryWrapper.last("limit 1");
+        BlackIp blackIp = blackIpMapper.selectOne(queryWrapper);
+        if (throwException && ObjectUtil.isNull(blackIp)) {
+            throw new NotFoundException();
+        }
+        return blackIp;
+    }
+
+    @Override
+    public Page<BlackIp> list(BlackIpPageQuery queryDTO) {
+        if (ObjectUtil.isNull(queryDTO.getPage())) {
+            queryDTO.setPage(new Pages());
+        }
+        return blackIpMapper.selectPage(queryDTO.getPage().convert(), fuzzyQuery(queryDTO));
+    }
+
+    @Override
+    public Boolean checkBlackIpValid(String ip) {
+        BlackIp blackIp = selectByIp(ip, false);
+        if (ObjectUtil.isNotNull(blackIp)) {
+            return EnableFlagEnum.ENABLE.equals(blackIp.getEnableFlag());
+        }
+        return false;
+    }
+
+    private LambdaQueryWrapper<BlackIp> fuzzyQuery(BlackIpPageQuery query) {
+        LambdaQueryWrapper<BlackIp> queryWrapper = Wrappers.<BlackIp>query().lambda();
+        if (ObjectUtil.isNotNull(query)) {
+            queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getIp()), BlackIp::getIp, query.getIp());
+        }
+        return queryWrapper;
+    }
+
+}

+ 93 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/DictionaryServiceImpl.java

@@ -0,0 +1,93 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import io.github.pnoker.center.auth.mapper.BlackIpMapper;
+import io.github.pnoker.center.auth.mapper.TenantMapper;
+import io.github.pnoker.center.auth.mapper.UserLoginMapper;
+import io.github.pnoker.center.auth.service.DictionaryService;
+import io.github.pnoker.common.entity.common.Dictionary;
+import io.github.pnoker.common.model.BlackIp;
+import io.github.pnoker.common.model.Tenant;
+import io.github.pnoker.common.model.UserLogin;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Service
+public class DictionaryServiceImpl implements DictionaryService {
+
+    @Resource
+    private TenantMapper tenantMapper;
+    @Resource
+    private UserLoginMapper userLoginMapper;
+    @Resource
+    private BlackIpMapper blackIpMapper;
+
+    @Override
+    public List<Dictionary> tenantDictionary() {
+        List<Dictionary> dictionaryList = new ArrayList<>(16);
+        LambdaQueryWrapper<Tenant> queryWrapper = Wrappers.<Tenant>query().lambda();
+        List<Tenant> tenantList = tenantMapper.selectList(queryWrapper);
+        for (Tenant tenant : tenantList) {
+            Dictionary driverDictionary = new Dictionary();
+            driverDictionary.setLabel(tenant.getTenantName());
+            driverDictionary.setValue(tenant.getId());
+            dictionaryList.add(driverDictionary);
+        }
+        return dictionaryList;
+    }
+
+    @Override
+    public List<Dictionary> userDictionary(String tenantId) {
+        List<Dictionary> dictionaryList = new ArrayList<>(16);
+        LambdaQueryWrapper<UserLogin> queryWrapper = Wrappers.<UserLogin>query().lambda();
+        List<UserLogin> userLoginList = userLoginMapper.selectList(queryWrapper);
+        for (UserLogin userLogin : userLoginList) {
+            Dictionary driverDictionary = new Dictionary();
+            driverDictionary.setLabel(userLogin.getLoginName());
+            driverDictionary.setValue(userLogin.getId());
+            dictionaryList.add(driverDictionary);
+        }
+        return dictionaryList;
+    }
+
+    @Override
+    public List<Dictionary> blackIpDictionary(String tenantId) {
+        List<Dictionary> dictionaryList = new ArrayList<>(16);
+        LambdaQueryWrapper<BlackIp> queryWrapper = Wrappers.<BlackIp>query().lambda();
+        List<BlackIp> blackIpList = blackIpMapper.selectList(queryWrapper);
+        for (BlackIp blackIp : blackIpList) {
+            Dictionary driverDictionary = new Dictionary();
+            driverDictionary.setLabel(blackIp.getIp());
+            driverDictionary.setValue(blackIp.getId());
+            dictionaryList.add(driverDictionary);
+        }
+        return dictionaryList;
+    }
+
+}

+ 86 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/ResourceServiceImpl.java

@@ -0,0 +1,86 @@
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.ResourcePageQuery;
+import io.github.pnoker.center.auth.mapper.ResourceMapper;
+import io.github.pnoker.center.auth.service.ResourceService;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.exception.AddException;
+import io.github.pnoker.common.exception.DeleteException;
+import io.github.pnoker.common.exception.NotFoundException;
+import io.github.pnoker.common.exception.UpdateException;
+import io.github.pnoker.common.model.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author linys
+ * @since 2023.04.02
+ */
+@Slf4j
+@Service
+public class ResourceServiceImpl implements ResourceService {
+
+    @javax.annotation.Resource
+    private ResourceMapper resourceMapper;
+
+
+    @Override
+    public void add(Resource entityDo) {
+        //todo check if exists
+        if (resourceMapper.insert(entityDo) < 1) {
+            throw new AddException("The resource add failed");
+        }
+    }
+
+    @Override
+    public void delete(String id) {
+        selectById(id);
+        if (resourceMapper.deleteById(id) < 1) {
+            throw new DeleteException("The resource delete failed");
+        }
+    }
+
+    @Override
+    public void update(Resource entityDo) {
+        selectById(entityDo.getId());
+        if (resourceMapper.updateById(entityDo) < 1) {
+            throw new UpdateException("The resource update failed");
+        }
+    }
+
+    @Override
+    public Resource selectById(String id) {
+        Resource resource = resourceMapper.selectById(id);
+        if (ObjectUtil.isNull(resource)) {
+            throw new NotFoundException();
+        }
+        return resource;
+    }
+
+    @Override
+    public Page<Resource> list(ResourcePageQuery pageQuery) {
+        if (ObjectUtil.isNull(pageQuery.getPage())) {
+            pageQuery.setPage(new Pages());
+        }
+        return resourceMapper.selectPage(pageQuery.getPage().convert(), buildQueryWrapper(pageQuery));
+    }
+
+    private LambdaQueryWrapper<Resource> buildQueryWrapper(ResourcePageQuery pageQuery) {
+        LambdaQueryWrapper<Resource> queryWrapper = Wrappers.<Resource>query().lambda();
+        if (ObjectUtil.isNotNull(pageQuery)) {
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(pageQuery.getTenantId()), Resource::getTenantId, pageQuery.getTenantId());
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(pageQuery.getParentResourceId()), Resource::getParentResourceId, pageQuery.getParentResourceId());
+            queryWrapper.like(CharSequenceUtil.isNotEmpty(pageQuery.getResourceName()), Resource::getResourceName, pageQuery.getResourceName());
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(pageQuery.getResourceCode()), Resource::getResourceCode, pageQuery.getResourceCode());
+            queryWrapper.eq(ObjectUtil.isNotEmpty(pageQuery.getResourceTypeFlag()), Resource::getResourceTypeFlag, pageQuery.getResourceTypeFlag());
+            queryWrapper.eq(ObjectUtil.isNotEmpty(pageQuery.getEnableFlag()), Resource::getEnableFlag, pageQuery.getEnableFlag());
+
+        }
+        return queryWrapper;
+    }
+}

+ 105 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/RoleResourceBindServiceImpl.java

@@ -0,0 +1,105 @@
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.RoleResourceBindPageQuery;
+import io.github.pnoker.center.auth.mapper.ResourceMapper;
+import io.github.pnoker.center.auth.mapper.RoleResourceBindMapper;
+import io.github.pnoker.center.auth.service.RoleResourceBindService;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.enums.EnableFlagEnum;
+import io.github.pnoker.common.exception.AddException;
+import io.github.pnoker.common.exception.DeleteException;
+import io.github.pnoker.common.exception.NotFoundException;
+import io.github.pnoker.common.exception.UpdateException;
+import io.github.pnoker.common.model.RoleResourceBind;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author linys
+ * @since 2023.04.02
+ */
+@Slf4j
+@Service
+public class RoleResourceBindServiceImpl implements RoleResourceBindService {
+
+    @Resource
+    private RoleResourceBindMapper bindMapper;
+
+    @Resource
+    private ResourceMapper resourceMapper;
+
+    @Override
+    public void add(RoleResourceBind entityDo) {
+        //todo check if exists
+        if (bindMapper.insert(entityDo) < 1) {
+            throw new AddException("The tenant bind add failed");
+        }
+    }
+
+    @Override
+    public void delete(String id) {
+        selectById(id);
+        if (bindMapper.deleteById(id) < 1) {
+            throw new DeleteException("The role resource bind delete failed");
+        }
+    }
+
+    @Override
+    public void update(RoleResourceBind entityDo) {
+        selectById(entityDo.getId());
+        if (bindMapper.updateById(entityDo) < 1) {
+            throw new UpdateException("The role resource bind update failed");
+        }
+    }
+
+    @Override
+    public RoleResourceBind selectById(String id) {
+        RoleResourceBind bind = bindMapper.selectById(id);
+        if (ObjectUtil.isNull(bind)) {
+            throw new NotFoundException();
+        }
+        return bind;
+    }
+
+    @Override
+    public Page<RoleResourceBind> list(RoleResourceBindPageQuery pageQuery) {
+        if (ObjectUtil.isNull(pageQuery.getPage())) {
+            pageQuery.setPage(new Pages());
+        }
+        return bindMapper.selectPage(pageQuery.getPage().convert(), buildQueryWrapper(pageQuery));
+    }
+
+    @Override
+    public List<io.github.pnoker.common.model.Resource> listResourceByRoleId(String RoleId) {
+        LambdaQueryWrapper<RoleResourceBind> queryWrapper = Wrappers.<RoleResourceBind>query().lambda();
+        queryWrapper.eq(RoleResourceBind::getRoleId, RoleId);
+        List<RoleResourceBind> roleResourceBinds = bindMapper.selectList(queryWrapper);
+        if (CollUtil.isNotEmpty(roleResourceBinds)) {
+            List<io.github.pnoker.common.model.Resource> resources = resourceMapper.selectBatchIds(roleResourceBinds.stream()
+                    .map(RoleResourceBind::getResourceId).collect(Collectors.toList()));
+            return resources.stream().filter(e -> EnableFlagEnum.ENABLE.equals(e.getEnableFlag()))
+                    .collect(Collectors.toList());
+        }
+
+        return null;
+    }
+
+    private LambdaQueryWrapper<RoleResourceBind> buildQueryWrapper(RoleResourceBindPageQuery pageQuery) {
+        LambdaQueryWrapper<RoleResourceBind> queryWrapper = Wrappers.<RoleResourceBind>query().lambda();
+        if (ObjectUtil.isNotNull(pageQuery)) {
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(pageQuery.getRoleId()), RoleResourceBind::getResourceId, pageQuery.getRoleId());
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(pageQuery.getResourceId()), RoleResourceBind::getResourceId, pageQuery.getResourceId());
+        }
+        return queryWrapper;
+    }
+}

+ 107 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/RoleUserBindServiceImpl.java

@@ -0,0 +1,107 @@
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.RoleUserBindPageQuery;
+import io.github.pnoker.center.auth.mapper.RoleMapper;
+import io.github.pnoker.center.auth.mapper.RoleUserBindMapper;
+import io.github.pnoker.center.auth.service.RoleUserBindService;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.enums.EnableFlagEnum;
+import io.github.pnoker.common.exception.AddException;
+import io.github.pnoker.common.exception.DeleteException;
+import io.github.pnoker.common.exception.NotFoundException;
+import io.github.pnoker.common.exception.UpdateException;
+import io.github.pnoker.common.model.Role;
+import io.github.pnoker.common.model.RoleUserBind;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author linys
+ * @since 2023.04.02
+ */
+@Slf4j
+@Service
+public class RoleUserBindServiceImpl implements RoleUserBindService {
+
+    @Resource
+    private RoleUserBindMapper roleUserBindMapper;
+
+    @Resource
+    private RoleMapper roleMapper;
+
+
+    @Override
+    public RoleUserBind selectById(String id) {
+        RoleUserBind roleUserBind = roleUserBindMapper.selectById(id);
+        if (ObjectUtil.isNull(roleUserBind)) {
+            throw new NotFoundException();
+        }
+        return roleUserBind;
+    }
+
+    @Override
+    public Page<RoleUserBind> list(RoleUserBindPageQuery pageQuery) {
+        if (ObjectUtil.isNull(pageQuery.getPage())) {
+            pageQuery.setPage(new Pages());
+        }
+        return roleUserBindMapper.selectPage(pageQuery.getPage().convert(), buildQueryWrapper(pageQuery));
+    }
+
+    @Override
+    public void add(RoleUserBind entityDo) {
+        //todo check if exists
+        if (roleUserBindMapper.insert(entityDo) < 1) {
+            throw new AddException("The role user bind add failed");
+        }
+    }
+
+    @Override
+    public void update(RoleUserBind entityDo) {
+        selectById(entityDo.getId());
+        if (roleUserBindMapper.updateById(entityDo) < 1) {
+            throw new UpdateException("The role user bind update failed");
+        }
+    }
+
+    @Override
+    public void delete(String id) {
+        selectById(id);
+        if (roleUserBindMapper.deleteById(id) < 1) {
+            throw new DeleteException("The role user bind delete failed");
+        }
+    }
+
+    @Override
+    public List<Role> listRoleByTenantIdAndUserId(String tenantId, String userId) {
+        LambdaQueryWrapper<RoleUserBind> queryWrapper = Wrappers.<RoleUserBind>query().lambda();
+        queryWrapper.eq(RoleUserBind::getUserId, userId);
+        List<RoleUserBind> roleUserBinds = roleUserBindMapper.selectList(queryWrapper);
+        if (CollUtil.isNotEmpty(roleUserBinds)) {
+            List<Role> roles = roleMapper.selectBatchIds(roleUserBinds.stream().map(RoleUserBind::getRoleId)
+                    .collect(Collectors.toList()));
+            return roles.stream().filter(e -> EnableFlagEnum.ENABLE.equals(e.getEnableFlag()) && tenantId.equals(e.getTenantId()))
+                    .collect(Collectors.toList());
+        }
+
+        return null;
+    }
+
+    public LambdaQueryWrapper<RoleUserBind> buildQueryWrapper(RoleUserBindPageQuery pageQuery) {
+        LambdaQueryWrapper<RoleUserBind> queryWrapper = Wrappers.<RoleUserBind>query().lambda();
+        if (ObjectUtil.isNotNull(pageQuery)) {
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(pageQuery.getUserId()), RoleUserBind::getUserId, pageQuery.getUserId());
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(pageQuery.getRoleId()), RoleUserBind::getRoleId, pageQuery.getRoleId());
+        }
+        return queryWrapper;
+    }
+}

+ 114 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/TenantBindServiceImpl.java

@@ -0,0 +1,114 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.TenantBindPageQuery;
+import io.github.pnoker.center.auth.mapper.TenantBindMapper;
+import io.github.pnoker.center.auth.service.TenantBindService;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.exception.AddException;
+import io.github.pnoker.common.exception.DeleteException;
+import io.github.pnoker.common.exception.NotFoundException;
+import io.github.pnoker.common.exception.UpdateException;
+import io.github.pnoker.common.model.TenantBind;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * TenantBindService Impl
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Service
+public class TenantBindServiceImpl implements TenantBindService {
+
+    @Resource
+    private TenantBindMapper tenantBindMapper;
+
+    @Override
+    public void add(TenantBind entityDO) {
+        if (tenantBindMapper.insert(entityDO) < 1) {
+            throw new AddException("The tenant bind add failed");
+        }
+    }
+
+    @Override
+    public void delete(String id) {
+        TenantBind tenantBind = selectById(id);
+        if (ObjectUtil.isNull(tenantBind)) {
+            throw new NotFoundException("The tenant bind does not exist");
+        }
+
+        if (tenantBindMapper.deleteById(id) < 1) {
+            throw new DeleteException("The tenant bind delete failed");
+        }
+    }
+
+    @Override
+    public void update(TenantBind entityDO) {
+        selectById(entityDO.getId());
+        entityDO.setOperateTime(null);
+        if (tenantBindMapper.updateById(entityDO) < 1) {
+            throw new UpdateException("The tenant bind update failed");
+        }
+    }
+
+    @Override
+    public TenantBind selectById(String id) {
+        TenantBind tenantBind = tenantBindMapper.selectById(id);
+        if (ObjectUtil.isNull(tenantBind)) {
+            throw new NotFoundException();
+        }
+        return tenantBind;
+    }
+
+    @Override
+    public TenantBind selectByTenantIdAndUserId(String tenantId, String userId) {
+        LambdaQueryWrapper<TenantBind> queryWrapper = Wrappers.<TenantBind>query().lambda();
+        queryWrapper.eq(TenantBind::getTenantId, tenantId);
+        queryWrapper.eq(TenantBind::getUserId, userId);
+        queryWrapper.last("limit 1");
+        return tenantBindMapper.selectOne(queryWrapper);
+    }
+
+    @Override
+    public Page<TenantBind> list(TenantBindPageQuery queryDTO) {
+        if (ObjectUtil.isNull(queryDTO.getPage())) {
+            queryDTO.setPage(new Pages());
+        }
+        return tenantBindMapper.selectPage(queryDTO.getPage().convert(), fuzzyQuery(queryDTO));
+    }
+
+    private LambdaQueryWrapper<TenantBind> fuzzyQuery(TenantBindPageQuery query) {
+        LambdaQueryWrapper<TenantBind> queryWrapper = Wrappers.<TenantBind>query().lambda();
+        if (ObjectUtil.isNotNull(query)) {
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(query.getTenantId()), TenantBind::getTenantId, query.getTenantId());
+            queryWrapper.eq(CharSequenceUtil.isNotEmpty(query.getUserId()), TenantBind::getUserId, query.getUserId());
+        }
+        return queryWrapper;
+    }
+
+}

+ 112 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/TenantServiceImpl.java

@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.TenantPageQuery;
+import io.github.pnoker.center.auth.mapper.TenantMapper;
+import io.github.pnoker.center.auth.service.TenantService;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.enums.EnableFlagEnum;
+import io.github.pnoker.common.exception.*;
+import io.github.pnoker.common.model.Tenant;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * 租户服务接口实现类
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Service
+public class TenantServiceImpl implements TenantService {
+
+    @Resource
+    private TenantMapper tenantMapper;
+
+    @Override
+    public void add(Tenant entityDO) {
+        Tenant select = selectByCode(entityDO.getTenantName());
+        if (ObjectUtil.isNotNull(select)) {
+            throw new DuplicateException("The tenant already exists");
+        }
+
+        if (tenantMapper.insert(entityDO) < 1) {
+            throw new AddException("The tenant {} add failed", entityDO.getTenantName());
+        }
+    }
+
+    @Override
+    public void delete(String id) {
+        Tenant tenant = selectById(id);
+        if (ObjectUtil.isNull(tenant)) {
+            throw new NotFoundException("The tenant does not exist");
+        }
+
+        if (tenantMapper.deleteById(id) < 1) {
+            throw new DeleteException("The tenant delete failed");
+        }
+    }
+
+    @Override
+    public void update(Tenant entityDO) {
+        entityDO.setTenantName(null);
+        entityDO.setOperateTime(null);
+        if (tenantMapper.updateById(entityDO) < 1) {
+            throw new UpdateException("The tenant update failed");
+        }
+    }
+
+    @Override
+    public Tenant selectById(String id) {
+        return tenantMapper.selectById(id);
+    }
+
+    @Override
+    public Tenant selectByCode(String code) {
+        LambdaQueryWrapper<Tenant> queryWrapper = Wrappers.<Tenant>query().lambda();
+        queryWrapper.eq(Tenant::getTenantCode, code);
+        queryWrapper.eq(Tenant::getEnableFlag, EnableFlagEnum.ENABLE);
+        queryWrapper.last("limit 1");
+        return tenantMapper.selectOne(queryWrapper);
+    }
+
+    @Override
+    public Page<Tenant> list(TenantPageQuery queryDTO) {
+        if (ObjectUtil.isNull(queryDTO.getPage())) {
+            queryDTO.setPage(new Pages());
+        }
+        return tenantMapper.selectPage(queryDTO.getPage().convert(), fuzzyQuery(queryDTO));
+    }
+
+    private LambdaQueryWrapper<Tenant> fuzzyQuery(TenantPageQuery query) {
+        LambdaQueryWrapper<Tenant> queryWrapper = Wrappers.<Tenant>query().lambda();
+        if (ObjectUtil.isNotNull(query)) {
+            queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getTenantName()), Tenant::getTenantName, query.getTenantName());
+        }
+        return queryWrapper;
+    }
+
+}

+ 190 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/TokenServiceImpl.java

@@ -0,0 +1,190 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import io.github.pnoker.center.auth.entity.bean.TokenValid;
+import io.github.pnoker.center.auth.entity.bean.UserLimit;
+import io.github.pnoker.center.auth.service.*;
+import io.github.pnoker.common.constant.cache.TimeoutConstant;
+import io.github.pnoker.common.constant.common.PrefixConstant;
+import io.github.pnoker.common.constant.common.SuffixConstant;
+import io.github.pnoker.common.constant.common.SymbolConstant;
+import io.github.pnoker.common.exception.NotFoundException;
+import io.github.pnoker.common.exception.ServiceException;
+import io.github.pnoker.common.model.Tenant;
+import io.github.pnoker.common.model.TenantBind;
+import io.github.pnoker.common.model.UserLogin;
+import io.github.pnoker.common.model.UserPassword;
+import io.github.pnoker.common.utils.DecodeUtil;
+import io.github.pnoker.common.utils.KeyUtil;
+import io.github.pnoker.common.utils.RedisUtil;
+import io.github.pnoker.common.utils.TimeUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 令牌服务接口实现类
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Service
+public class TokenServiceImpl implements TokenService {
+
+    @Resource
+    private TenantService tenantService;
+    @Resource
+    private UserLoginService userLoginService;
+    @Resource
+    private UserPasswordService userPasswordService;
+    @Resource
+    private TenantBindService tenantBindService;
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    @Override
+    public String generateSalt(String username, String tenantName) {
+        Tenant tenant = tenantService.selectByCode(tenantName);
+        if (ObjectUtil.isNull(tenant)) {
+            throw new NotFoundException("租户、用户信息不匹配");
+        }
+        String redisSaltKey = PrefixConstant.USER + SuffixConstant.SALT + SymbolConstant.DOUBLE_COLON + username + SymbolConstant.HASHTAG + tenant.getId();
+        String salt = redisUtil.getKey(redisSaltKey);
+        if (CharSequenceUtil.isBlank(salt)) {
+            salt = RandomUtil.randomString(16);
+            redisUtil.setKey(redisSaltKey, salt, TimeoutConstant.SALT_CACHE_TIMEOUT, TimeUnit.MINUTES);
+        }
+        return salt;
+    }
+
+    @Override
+    public String generateToken(String username, String salt, String password, String tenantName) {
+        Tenant tenant = tenantService.selectByCode(tenantName);
+        if (ObjectUtil.isNull(tenant)) {
+            throw new NotFoundException("租户、用户信息不匹配");
+        }
+        checkUserLimit(username, tenant.getId());
+        UserLogin userLogin = userLoginService.selectByLoginName(username, false);
+        if (ObjectUtil.isNull(userLogin)) {
+            throw new NotFoundException("租户、用户信息不匹配");
+        }
+        TenantBind tenantBind = tenantBindService.selectByTenantIdAndUserId(tenant.getId(), userLogin.getUserId());
+        if (ObjectUtil.isNull(tenantBind)) {
+            throw new NotFoundException("租户、用户信息不匹配");
+        }
+        UserPassword userPassword = userPasswordService.selectById(userLogin.getUserPasswordId());
+        String redisSaltKey = PrefixConstant.USER + SuffixConstant.SALT + SymbolConstant.DOUBLE_COLON + username + SymbolConstant.HASHTAG + tenant.getId();
+        String redisSaltValue = redisUtil.getKey(redisSaltKey);
+        String md5Password = DecodeUtil.md5(userPassword.getLoginPassword() + redisSaltValue);
+        if (CharSequenceUtil.isNotEmpty(redisSaltValue) && redisSaltValue.equals(salt) && md5Password.equals(password)) {
+            String redisTokenKey = PrefixConstant.USER + SuffixConstant.TOKEN + SymbolConstant.DOUBLE_COLON + username + SymbolConstant.HASHTAG + tenant.getId();
+            String token = KeyUtil.generateToken(username, redisSaltValue, tenant.getId());
+            redisUtil.setKey(redisTokenKey, token, TimeoutConstant.TOKEN_CACHE_TIMEOUT, TimeUnit.HOURS);
+            return token;
+        }
+        updateUserLimit(username, tenant.getId(), true);
+        throw new ServiceException("Invalid username、password、tenant");
+    }
+
+    @Override
+    public TokenValid checkTokenValid(String username, String salt, String token, String tenantName) {
+        Tenant tenant = tenantService.selectByCode(tenantName);
+        if (ObjectUtil.isNull(tenant)) {
+            throw new NotFoundException("租户、用户信息不匹配");
+        }
+        String redisKey = PrefixConstant.USER + SuffixConstant.TOKEN + SymbolConstant.DOUBLE_COLON + username + SymbolConstant.HASHTAG + tenant.getId();
+        String redisToken = redisUtil.getKey(redisKey);
+        if (CharSequenceUtil.isBlank(redisToken) || !redisToken.equals(token)) {
+            return new TokenValid(false, null);
+        }
+        try {
+            Claims claims = KeyUtil.parserToken(username, salt, token, tenant.getId());
+            return new TokenValid(true, claims.getExpiration());
+        } catch (Exception e) {
+            return new TokenValid(false, null);
+        }
+    }
+
+    @Override
+    public Boolean cancelToken(String username, String tenantName) {
+        Tenant tenant = tenantService.selectByCode(tenantName);
+        if (ObjectUtil.isNull(tenant)) {
+            throw new NotFoundException("租户、用户信息不匹配");
+        }
+        String redisKey = PrefixConstant.USER + SuffixConstant.TOKEN + SymbolConstant.DOUBLE_COLON + username + SymbolConstant.HASHTAG + tenant.getId();
+        redisUtil.deleteKey(redisKey);
+        return true;
+    }
+
+    /**
+     * 检测用户登录限制,返回该用户是否受限
+     *
+     * @param username 用户名称
+     * @param tenantId 租户ID
+     */
+    private void checkUserLimit(String username, String tenantId) {
+        String redisKey = PrefixConstant.USER + SuffixConstant.LIMIT + SymbolConstant.DOUBLE_COLON + username + SymbolConstant.HASHTAG + tenantId;
+        UserLimit limit = redisUtil.getKey(redisKey);
+        if (ObjectUtil.isNotNull(limit) && limit.getTimes() >= 5) {
+            Date now = new Date();
+            long interval = limit.getExpireTime().getTime() - now.getTime();
+            if (interval > 0) {
+                limit = updateUserLimit(username, tenantId, false);
+                throw new ServiceException("Access restricted,Please try again after {}", TimeUtil.completeFormat(limit.getExpireTime()));
+            }
+        }
+    }
+
+    /**
+     * 更新用户登录限制
+     *
+     * @param username   用户名称
+     * @param tenantId   租户ID
+     * @param expireTime Expire Time
+     * @return UserLimit
+     */
+    private UserLimit updateUserLimit(String username, String tenantId, boolean expireTime) {
+        int amount = TimeoutConstant.USER_LIMIT_TIMEOUT;
+        String redisKey = PrefixConstant.USER + SuffixConstant.LIMIT + SymbolConstant.DOUBLE_COLON + username + SymbolConstant.HASHTAG + tenantId;
+        UserLimit userLimit = redisUtil.getKey(redisKey);
+        UserLimit limit = Optional.ofNullable(userLimit).orElse(new UserLimit(0, new Date()));
+        limit.setTimes(limit.getTimes() + 1);
+        if (limit.getTimes() > 20) {
+            //TODO 拉黑IP和锁定用户操作,然后通过Gateway进行拦截
+            amount = 24 * 60;
+        } else if (limit.getTimes() > 5) {
+            amount = limit.getTimes() * TimeoutConstant.USER_LIMIT_TIMEOUT;
+        }
+        if (expireTime) {
+            limit.setExpireTime(TimeUtil.expireTime(amount, Calendar.MINUTE));
+        }
+        redisUtil.setKey(redisKey, limit, 1, TimeUnit.DAYS);
+        return limit;
+    }
+}

+ 142 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/UserLoginServiceImpl.java

@@ -0,0 +1,142 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.UserLoginPageQuery;
+import io.github.pnoker.center.auth.mapper.UserLoginMapper;
+import io.github.pnoker.center.auth.service.UserLoginService;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.enums.EnableFlagEnum;
+import io.github.pnoker.common.exception.*;
+import io.github.pnoker.common.model.UserLogin;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+/**
+ * 用户服务接口实现类
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Service
+public class UserLoginServiceImpl implements UserLoginService {
+
+    @Resource
+    private UserLoginMapper userLoginMapper;
+
+    @Override
+    @Transactional
+    public void add(UserLogin entityDO) {
+        // 判断登录名称是否存在
+        UserLogin selectByLoginName = selectByLoginName(entityDO.getLoginName(), false);
+        if (ObjectUtil.isNotNull(selectByLoginName)) {
+            throw new DuplicateException("The user already exists with login name: {}", entityDO.getLoginName());
+        }
+
+        // 插入 user 数据,并返回插入后的 user
+        if (userLoginMapper.insert(entityDO) < 1) {
+            throw new AddException("The user add failed: {}", entityDO.toString());
+        }
+    }
+
+    @Override
+    @Transactional
+    public void delete(String id) {
+        UserLogin userLogin = selectById(id);
+        if (ObjectUtil.isNull(userLogin)) {
+            throw new NotFoundException("The user login does not exist");
+        }
+
+        if (userLoginMapper.deleteById(id) < 1) {
+            throw new DeleteException("The user login delete failed");
+        }
+    }
+
+    @Override
+    public void update(UserLogin entityDO) {
+        UserLogin selectById = selectById(entityDO.getId());
+        if (ObjectUtil.isNull(selectById)) {
+            throw new NotFoundException("The user login does not exist");
+        }
+        entityDO.setLoginName(null);
+        entityDO.setOperateTime(null);
+        if (userLoginMapper.updateById(entityDO) < 1) {
+            throw new UpdateException("The user login update failed");
+        }
+    }
+
+    @Override
+    public UserLogin selectById(String id) {
+        return userLoginMapper.selectById(id);
+    }
+
+    @Override
+    public Page<UserLogin> list(UserLoginPageQuery queryDTO) {
+        if (ObjectUtil.isNull(queryDTO.getPage())) {
+            queryDTO.setPage(new Pages());
+        }
+        return userLoginMapper.selectPage(queryDTO.getPage().convert(), fuzzyQuery(queryDTO));
+    }
+
+    @Override
+    public UserLogin selectByLoginName(String loginName, boolean throwException) {
+        if (CharSequenceUtil.isEmpty(loginName)) {
+            if (throwException) {
+                throw new EmptyException("The login name is empty");
+            }
+            return null;
+        }
+
+        LambdaQueryWrapper<UserLogin> queryWrapper = Wrappers.<UserLogin>query().lambda();
+        queryWrapper.eq(UserLogin::getLoginName, loginName);
+        queryWrapper.eq(UserLogin::getEnableFlag, EnableFlagEnum.ENABLE);
+        queryWrapper.last("limit 1");
+        UserLogin userLogin = userLoginMapper.selectOne(queryWrapper);
+        if (ObjectUtil.isNull(userLogin)) {
+            throw new NotFoundException();
+        }
+        return userLogin;
+    }
+
+    @Override
+    public boolean checkLoginNameValid(String loginName) {
+        UserLogin userLogin = selectByLoginName(loginName, false);
+        if (ObjectUtil.isNotNull(userLogin)) {
+            return EnableFlagEnum.ENABLE.equals(userLogin.getEnableFlag());
+        }
+
+        return false;
+    }
+
+    private LambdaQueryWrapper<UserLogin> fuzzyQuery(UserLoginPageQuery query) {
+        LambdaQueryWrapper<UserLogin> queryWrapper = Wrappers.<UserLogin>query().lambda();
+        if (ObjectUtil.isNotNull(query)) {
+            queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getLoginName()), UserLogin::getLoginName, query.getLoginName());
+        }
+        return queryWrapper;
+    }
+
+}

+ 115 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/UserPasswordServiceImpl.java

@@ -0,0 +1,115 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.UserPasswordPageQuery;
+import io.github.pnoker.center.auth.mapper.UserPasswordMapper;
+import io.github.pnoker.center.auth.service.UserPasswordService;
+import io.github.pnoker.common.constant.common.AlgorithmConstant;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.exception.AddException;
+import io.github.pnoker.common.exception.DeleteException;
+import io.github.pnoker.common.exception.NotFoundException;
+import io.github.pnoker.common.exception.UpdateException;
+import io.github.pnoker.common.model.UserPassword;
+import io.github.pnoker.common.utils.DecodeUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+/**
+ * 用户密码服务接口实现类
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Service
+public class UserPasswordServiceImpl implements UserPasswordService {
+
+    @Resource
+    private UserPasswordMapper userPasswordMapper;
+
+    @Override
+    @Transactional
+    public void add(UserPassword entityDO) {
+        entityDO.setLoginPassword(DecodeUtil.md5(entityDO.getLoginPassword()));
+        // 插入 userPassword 数据,并返回插入后的 userPassword
+        if (userPasswordMapper.insert(entityDO) < 1) {
+            throw new AddException("The user password add failed: {}", entityDO.toString());
+        }
+    }
+
+    @Override
+    @Transactional
+    public void delete(String id) {
+        UserPassword userPassword = selectById(id);
+        if (ObjectUtil.isNull(userPassword)) {
+            throw new NotFoundException("The user password does not exist");
+        }
+
+        if (userPasswordMapper.deleteById(id) < 1) {
+            throw new DeleteException("The user password delete failed");
+        }
+    }
+
+    @Override
+    public void update(UserPassword entityDO) {
+        UserPassword selectById = selectById(entityDO.getId());
+        if (ObjectUtil.isNull(selectById)) {
+            throw new NotFoundException();
+        }
+        entityDO.setLoginPassword(DecodeUtil.md5(entityDO.getLoginPassword()));
+        entityDO.setOperateTime(null);
+        if (userPasswordMapper.updateById(entityDO) < 1) {
+            throw new UpdateException("The user password update failed");
+        }
+    }
+
+    @Override
+    public UserPassword selectById(String id) {
+        return userPasswordMapper.selectById(id);
+    }
+
+    @Override
+    public Page<UserPassword> list(UserPasswordPageQuery queryDTO) {
+        if (ObjectUtil.isNull(queryDTO.getPage())) {
+            queryDTO.setPage(new Pages());
+        }
+        return userPasswordMapper.selectPage(queryDTO.getPage().convert(), fuzzyQuery(queryDTO));
+    }
+
+    @Override
+    public void restPassword(String id) {
+        UserPassword userPassword = selectById(id);
+        if (ObjectUtil.isNotNull(userPassword)) {
+            userPassword.setLoginPassword(DecodeUtil.md5(AlgorithmConstant.DEFAULT_PASSWORD));
+            update(userPassword);
+        }
+    }
+
+    private LambdaQueryWrapper<UserPassword> fuzzyQuery(UserPasswordPageQuery query) {
+        return Wrappers.<UserPassword>query().lambda();
+    }
+
+}

+ 201 - 0
dc3-center/dc3-center-auth/src/main/java/io/github/pnoker/center/auth/service/impl/UserServiceImpl.java

@@ -0,0 +1,201 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.auth.service.impl;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.auth.entity.query.UserDto;
+import io.github.pnoker.center.auth.mapper.UserMapper;
+import io.github.pnoker.center.auth.service.UserService;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.exception.*;
+import io.github.pnoker.common.model.User;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+/**
+ * 用户服务接口实现类
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Service
+public class UserServiceImpl implements UserService {
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Override
+    @Transactional
+    public void add(User entityDO) {
+        // 判断用户是否存在
+        User selectByUserName = selectByUserName(entityDO.getUserName(), false);
+        if (ObjectUtil.isNotNull(selectByUserName)) {
+            throw new DuplicateException("The user already exists with username: {}", entityDO.getUserName());
+        }
+
+        // 判断 phone 是否存在,如果有 phone 不为空,检查该 phone 是否被占用
+        if (CharSequenceUtil.isNotEmpty(entityDO.getPhone())) {
+            User selectByPhone = selectByPhone(entityDO.getPhone(), false);
+            if (ObjectUtil.isNotNull(selectByPhone)) {
+                throw new DuplicateException("The user already exists with phone: {}", entityDO.getPhone());
+            }
+        }
+
+        // 判断 email 是否存在,如果有 email 不为空,检查该 email 是否被占用
+        if (CharSequenceUtil.isNotEmpty(entityDO.getEmail())) {
+            User selectByEmail = selectByEmail(entityDO.getEmail(), false);
+            if (ObjectUtil.isNotNull(selectByEmail)) {
+                throw new DuplicateException("The user already exists with email: {}", entityDO.getEmail());
+            }
+        }
+
+        // 插入 user 数据,并返回插入后的 user
+        if (userMapper.insert(entityDO) < 1) {
+            throw new AddException("The user add failed: {}", entityDO.toString());
+        }
+    }
+
+    @Override
+    @Transactional
+    public void delete(String id) {
+        User user = selectById(id);
+        if (ObjectUtil.isNull(user)) {
+            throw new NotFoundException("The user does not exist");
+        }
+
+        if (userMapper.deleteById(id) < 1) {
+            throw new DeleteException("The user delete failed");
+        }
+    }
+
+    @Override
+    public void update(User entityDO) {
+        User selectById = selectById(entityDO.getId());
+        // 判断 phone 是否修改
+        if (CharSequenceUtil.isNotEmpty(entityDO.getPhone())) {
+            if (!entityDO.getPhone().equals(selectById.getPhone())) {
+                User selectByPhone = selectByPhone(entityDO.getPhone(), false);
+                if (ObjectUtil.isNotNull(selectByPhone)) {
+                    throw new DuplicateException("The user already exists with phone {}", entityDO.getPhone());
+                }
+            }
+        } else {
+            entityDO.setPhone(null);
+        }
+
+        // 判断 email 是否修改
+        if (CharSequenceUtil.isNotEmpty(entityDO.getEmail())) {
+            if (!entityDO.getEmail().equals(selectById.getEmail())) {
+                User selectByEmail = selectByEmail(entityDO.getEmail(), false);
+                if (ObjectUtil.isNotNull(selectByEmail)) {
+                    throw new DuplicateException("The user already exists with email {}", entityDO.getEmail());
+                }
+            }
+        } else {
+            entityDO.setEmail(null);
+        }
+
+        entityDO.setUserName(null);
+        entityDO.setOperateTime(null);
+        if (userMapper.updateById(entityDO) < 1) {
+            throw new UpdateException("The user update failed");
+        }
+    }
+
+    @Override
+    public User selectById(String id) {
+        return userMapper.selectById(id);
+    }
+
+    public User selectByUserName(String userName, boolean throwException) {
+        if (CharSequenceUtil.isEmpty(userName)) {
+            if (throwException) {
+                throw new EmptyException("The name is empty");
+            }
+            return null;
+        }
+
+        return selectByKey(User::getUserName, userName, throwException);
+    }
+
+    @Override
+    public User selectByPhone(String phone, boolean throwException) {
+        if (CharSequenceUtil.isEmpty(phone)) {
+            if (throwException) {
+                throw new EmptyException("The phone is empty");
+            }
+            return null;
+        }
+
+        return selectByKey(User::getPhone, phone, throwException);
+    }
+
+    @Override
+    public User selectByEmail(String email, boolean throwException) {
+        if (CharSequenceUtil.isEmpty(email)) {
+            if (throwException) {
+                throw new EmptyException("The phone is empty");
+            }
+            return null;
+        }
+
+        return selectByKey(User::getEmail, email, throwException);
+    }
+
+    @Override
+    public Page<User> list(UserDto queryDTO) {
+        if (ObjectUtil.isNull(queryDTO.getPage())) {
+            queryDTO.setPage(new Pages());
+        }
+        return userMapper.selectPage(queryDTO.getPage().convert(), fuzzyQuery(queryDTO));
+    }
+
+    private LambdaQueryWrapper<User> fuzzyQuery(UserDto query) {
+        LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>query().lambda();
+        if (ObjectUtil.isNotNull(query)) {
+            queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getNickName()), User::getNickName, query.getNickName());
+            queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getUserName()), User::getUserName, query.getUserName());
+            queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getPhone()), User::getPhone, query.getPhone());
+            queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getEmail()), User::getEmail, query.getEmail());
+        }
+        return queryWrapper;
+    }
+
+    private User selectByKey(SFunction<User, ?> key, String value, boolean throwException) {
+        LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>query().lambda();
+        queryWrapper.eq(key, value);
+        queryWrapper.last("limit 1");
+        User user = userMapper.selectOne(queryWrapper);
+        if (ObjectUtil.isNull(user)) {
+            if (throwException) {
+                throw new NotFoundException();
+            }
+            return null;
+        }
+        return user;
+    }
+
+}

+ 22 - 0
dc3-center/dc3-center-auth/src/main/resources/META-INF/aop.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+  ~ Copyright 2016-present the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<aspectj>
+    <weaver options="-Xset:weaveJavaxPackages=true">
+        <include within="io.github.pnoker.center.auth.service..*"/>
+    </weaver>
+</aspectj>

+ 39 - 0
dc3-center/dc3-center-auth/src/main/resources/application-dev.yml

@@ -0,0 +1,39 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Development environment, customizable configuration
+spring:
+  env: dev
+  group: ${user.name}
+  datasource:
+    dynamic:
+      datasource:
+        master:
+          url: jdbc:mysql://${DB_HOST:dc3-mysql}:${MYSQL_PORT:33306}/${DB_NAME:dc3_auth}?allowPublicKeyRetrieval=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
+          username: ${DB_USERNAME:root}
+          password: ${DB_PASSWORD:dc3}
+  redis:
+    host: ${REDIS_HOST:dc3-redis}
+    port: ${REDIS_PORT:36379}
+    password: ${REDIS_PASSWORD:dc3}
+  cache:
+    redis:
+      time-to-live: ${CACHE_REDIS_TIME_TO_LIVE:5S}
+  cloud:
+    nacos:
+      discovery:
+        group: ${spring.group}
+        watch-delay: 5000

+ 21 - 0
dc3-center/dc3-center-auth/src/main/resources/application-pre.yml

@@ -0,0 +1,21 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Product environment, customizable configuration
+spring:
+  cache:
+    redis:
+      time-to-live: ${CACHE_REDIS_TIME_TO_LIVE:12H}

+ 21 - 0
dc3-center/dc3-center-auth/src/main/resources/application-pro.yml

@@ -0,0 +1,21 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Product environment, customizable configuration
+spring:
+  cache:
+    redis:
+      time-to-live: ${CACHE_REDIS_TIME_TO_LIVE:12H}

+ 21 - 0
dc3-center/dc3-center-auth/src/main/resources/application-test.yml

@@ -0,0 +1,21 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Test environment, customizable configuration
+spring:
+  cache:
+    redis:
+      time-to-live: ${CACHE_REDIS_TIME_TO_LIVE:15M}

+ 37 - 0
dc3-center/dc3-center-auth/src/main/resources/application.yml

@@ -0,0 +1,37 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+server:
+  port: ${SERVER_PORT:8300}
+
+grpc:
+  server:
+    port: ${GRPC_SERVER_PORT:9300}
+
+spring:
+  application:
+    name: @project.artifactId@
+  profiles:
+    active:
+      - ${NODE_ENV:dev}
+  redis:
+    database: 1
+
+logging:
+  level:
+    io.github.pnoker: DEBUG
+  file:
+    name: dc3/logs/center/auth/${spring.application.name}.log

+ 49 - 0
dc3-center/dc3-center-data/Dockerfile

@@ -0,0 +1,49 @@
+#
+# Copyright 2016-present the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# runtime
+FROM registry.cn-beijing.aliyuncs.com/dc3/alpine-java:dragonwell-8.13.14 AS runtime
+MAINTAINER pnoker <pnokers.icloud.com>
+
+ENV JAVA_OPS -server \
+             -Xms128m \
+             -Xmx1024m \
+             -Djava.security.egd=file:/dev/./urandom \
+             -XX:CompressedClassSpaceSize=128m \
+             -XX:MetaspaceSize=200m \
+             -XX:MaxMetaspaceSize=200m
+ENV GC_LOG   -XX:+PrintGCDetails \
+             -XX:+PrintGCDateStamps \
+             -XX:+PrintTenuringDistribution \
+             -XX:+PrintHeapAtGC \
+             -XX:+PrintReferenceGC \
+             -XX:+PrintGCApplicationStoppedTime \
+             -XX:+UseGCLogFileRotation \
+             -XX:NumberOfGCLogFiles=10 \
+             -XX:GCLogFileSize=10M \
+             -Xloggc:dc3/logs/center/data/gc/dc3-center-data.log
+
+RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+
+WORKDIR /dc3-center/dc3-center-data
+
+ADD ./target/dc3-center-data.jar ./
+
+EXPOSE 8500
+VOLUME /dc3-center/dc3-center-data/dc3/logs
+
+CMD mkdir -p /dc3-center/dc3-center-data/dc3/logs/center/data/gc \
+    && java ${JAVA_OPS} ${GC_LOG} -jar dc3-center-data.jar

+ 113 - 0
dc3-center/dc3-center-data/pom.xml

@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>io.github.pnoker</groupId>
+        <artifactId>dc3-center</artifactId>
+        <version>2023.4.5</version>
+    </parent>
+
+    <artifactId>dc3-center-data</artifactId>
+    <packaging>jar</packaging>
+
+    <description>IOT DC3 平台数据中心,包含Amqp,Websocket,Mqtt等通用消息中间件,通过消息订阅方式收集设备组信息。
+    </description>
+
+    <dependencies>
+
+        <!-- Elasticsearch -->
+        <dependency>
+            <groupId>co.elastic.clients</groupId>
+            <artifactId>elasticsearch-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.json</groupId>
+            <artifactId>jakarta.json-api</artifactId>
+        </dependency>
+
+        <!-- DC3 Api Manager -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-api-manager</artifactId>
+        </dependency>
+
+        <!-- DC3 Api Data -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-api-data</artifactId>
+        </dependency>
+
+        <!-- DC3 Common RabbitMQ -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-rabbitmq</artifactId>
+        </dependency>
+
+        <!-- DC3 Common MySQL -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-mysql</artifactId>
+        </dependency>
+
+        <!-- DC3 Common Mongo -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-mongo</artifactId>
+        </dependency>
+
+        <!-- DC3 Common Redis -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-redis</artifactId>
+        </dependency>
+
+        <!-- DC3 Common Influx -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-influx</artifactId>
+        </dependency>
+
+        <!-- DC3 Common tdengine -->
+        <!--<dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-tdengine</artifactId>
+        </dependency>-->
+
+        <!-- DC3 Common Quartz -->
+        <dependency>
+            <groupId>io.github.pnoker</groupId>
+            <artifactId>dc3-common-quartz</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 38 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/DataApplication.java

@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * 消息中心中心服务启动入口
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableTransactionManagement
+public class DataApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(DataApplication.class, args);
+    }
+}
+

+ 56 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/api/PointValueApi.java

@@ -0,0 +1,56 @@
+package io.github.pnoker.center.data.api;
+
+import cn.hutool.core.util.ObjectUtil;
+import io.github.pnoker.api.center.data.PointValueApiGrpc;
+import io.github.pnoker.api.center.data.PointValueDTO;
+import io.github.pnoker.api.center.data.PointValueQuery;
+import io.github.pnoker.api.center.data.RPointValueDTO;
+import io.github.pnoker.api.common.RDTO;
+import io.github.pnoker.center.data.service.PointValueService;
+import io.github.pnoker.common.entity.point.PointValue;
+import io.github.pnoker.common.enums.ResponseEnum;
+import io.grpc.stub.StreamObserver;
+import lombok.extern.slf4j.Slf4j;
+import net.devh.boot.grpc.server.service.GrpcService;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@GrpcService
+public class PointValueApi extends PointValueApiGrpc.PointValueApiImplBase {
+
+    @Resource
+    PointValueService pointValueService;
+
+    @Override
+    public void lastValue(PointValueQuery request, StreamObserver<RPointValueDTO> responseObserver) {
+        RPointValueDTO.Builder builder = RPointValueDTO.newBuilder();
+        RDTO.Builder rBuilder = RDTO.newBuilder();
+        PointValue pointValue = pointValueService.latest(request);
+        if (ObjectUtil.isNull(pointValue)) {
+            rBuilder.setOk(false);
+            rBuilder.setCode(ResponseEnum.NO_RESOURCE.getCode());
+            rBuilder.setMessage(ResponseEnum.NO_RESOURCE.getMessage());
+        } else {
+            rBuilder.setOk(true);
+            rBuilder.setCode(ResponseEnum.OK.getCode());
+            rBuilder.setMessage(ResponseEnum.OK.getMessage());
+            builder.setData(buildDTOByDO(pointValue));
+        }
+        builder.setResult(rBuilder);
+        responseObserver.onNext(builder.build());
+        responseObserver.onCompleted();
+    }
+
+    private PointValueDTO buildDTOByDO(PointValue pointValue) {
+        PointValueDTO.Builder builder = PointValueDTO.newBuilder();
+        builder.setDeviceId(pointValue.getDeviceId());
+        builder.setPointId(pointValue.getPointId());
+        builder.setValue(pointValue.getValue());
+        builder.setRawValue(pointValue.getRawValue());
+        builder.setCreateTime(pointValue.getCreateTime().getTime());
+        builder.setOriginTime(pointValue.getOriginTime().getTime());
+        return builder.build();
+    }
+
+}

+ 104 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/config/DataTopicConfig.java

@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.config;
+
+import io.github.pnoker.common.config.ExchangeConfig;
+import io.github.pnoker.common.constant.common.SymbolConstant;
+import io.github.pnoker.common.constant.driver.RabbitConstant;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.TopicExchange;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Configuration
+@ConditionalOnClass(ExchangeConfig.class)
+public class DataTopicConfig {
+
+    @Resource
+    private TopicExchange eventExchange;
+
+    @Resource
+    private TopicExchange valueExchange;
+
+    @Bean
+    Queue driverEventQueue() {
+        Map<String, Object> arguments = new HashMap<>();
+        // 30秒:30 * 1000 = 30000L
+        arguments.put(RabbitConstant.MESSAGE_TTL, 30000L);
+        return new Queue(RabbitConstant.QUEUE_DRIVER_EVENT, true, false, false, arguments);
+    }
+
+    @Bean
+    Binding driverEventBinding(Queue driverEventQueue) {
+        Binding binding = BindingBuilder
+                .bind(driverEventQueue)
+                .to(eventExchange)
+                .with(RabbitConstant.ROUTING_DRIVER_EVENT_PREFIX + SymbolConstant.ASTERISK);
+        binding.addArgument(RabbitConstant.AUTO_DELETE, true);
+        return binding;
+    }
+
+    @Bean
+    Queue deviceEventQueue() {
+        Map<String, Object> arguments = new HashMap<>();
+        // 30秒:30 * 1000 = 30000L
+        arguments.put(RabbitConstant.MESSAGE_TTL, 30000L);
+        return new Queue(RabbitConstant.QUEUE_DEVICE_EVENT, true, false, false, arguments);
+    }
+
+    @Bean
+    Binding deviceEventBinding(Queue deviceEventQueue) {
+        Binding binding = BindingBuilder
+                .bind(deviceEventQueue)
+                .to(eventExchange)
+                .with(RabbitConstant.ROUTING_DEVICE_EVENT_PREFIX + SymbolConstant.ASTERISK);
+        binding.addArgument(RabbitConstant.AUTO_DELETE, true);
+        return binding;
+    }
+
+    @Bean
+    Queue pointValueQueue() {
+        Map<String, Object> arguments = new HashMap<>();
+        // 7天: 7 * 24 * 60 * 60 * 1000 = 604800000L
+        arguments.put(RabbitConstant.MESSAGE_TTL, 604800000L);
+        return new Queue(RabbitConstant.QUEUE_POINT_VALUE, true, false, false, arguments);
+    }
+
+    @Bean
+    Binding pointValueBinding(Queue pointValueQueue) {
+        Binding binding = BindingBuilder
+                .bind(pointValueQueue)
+                .to(valueExchange)
+                .with(RabbitConstant.ROUTING_POINT_VALUE_PREFIX + SymbolConstant.ASTERISK);
+        binding.addArgument(RabbitConstant.AUTO_DELETE, true);
+        return binding;
+    }
+
+}

+ 88 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/config/ElasticsearchConfig.java

@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.config;
+
+import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.json.jackson.JacksonJsonpMapper;
+import co.elastic.clients.transport.ElasticsearchTransport;
+import co.elastic.clients.transport.rest_client.RestClientTransport;
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.elasticsearch.client.RestClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Elasticsearch Configuration
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Configuration
+@ConditionalOnProperty(name = "data.point.sava.elasticsearch.enable", havingValue = "true")
+public class ElasticsearchConfig {
+
+    @Value("${data.point.sava.elasticsearch.host}")
+    private String host;
+    @Value("${data.point.sava.elasticsearch.port}")
+    private Integer port;
+
+    @Bean
+    public ElasticsearchClient elasticsearchClient() {
+        ElasticsearchTransport transport = getElasticsearchTransport();
+
+        // And create the API client
+        return new ElasticsearchClient(transport);
+    }
+
+    @Bean
+    public ElasticsearchAsyncClient elasticsearchAsyncClient() {
+        // Create the low-level client
+        ElasticsearchTransport transport = getElasticsearchTransport();
+
+        // And create the API client
+        return new ElasticsearchAsyncClient(transport);
+    }
+
+    private ElasticsearchTransport getElasticsearchTransport() {
+        // Create the low-level client
+        RestClient restClient = RestClient.builder(new HttpHost(host, port)).build();
+
+        // Create the transport with a Jackson mapper
+        return new RestClientTransport(restClient, new JacksonJsonpMapper());
+    }
+
+    private ElasticsearchTransport getElasticsearchTransportWithAuth() {
+        // Create the credentials provider
+        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "password"));
+
+        // Create the low-level client
+        RestClient restClient = RestClient.builder(new HttpHost(host, port))
+                .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider))
+                .build();
+
+        // Create the transport with a Jackson mapper
+        return new RestClientTransport(restClient, new JacksonJsonpMapper());
+    }
+}

+ 48 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/config/OpentsdbConfig.java

@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.config;
+
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.ConnectionPool;
+import okhttp3.OkHttpClient;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Opentsdb Configuration
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@Configuration
+@ConditionalOnProperty(name = "data.point.sava.opentsdb.enable", havingValue = "true")
+public class OpentsdbConfig {
+
+    @Bean
+    public OkHttpClient okHttpClient() {
+        return new OkHttpClient.Builder()
+                .retryOnConnectionFailure(true)
+                .connectionPool(new ConnectionPool(1024, 5, TimeUnit.SECONDS))
+                .connectTimeout(5, TimeUnit.SECONDS)
+                .writeTimeout(10, TimeUnit.SECONDS)
+                .build();
+    }
+}

+ 70 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/DeviceEventController.java

@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.data.entity.vo.query.DeviceEventPageQuery;
+import io.github.pnoker.center.data.service.EventService;
+import io.github.pnoker.common.constant.service.DataServiceConstant;
+import io.github.pnoker.common.entity.DeviceEvent;
+import io.github.pnoker.common.entity.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 设备事件 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(DataServiceConstant.DEVICE_EVENT_URL_PREFIX)
+public class DeviceEventController {
+
+    @Resource
+    private EventService eventService;
+
+    /**
+     * 模糊分页查询 DeviceEvent
+     *
+     * @param deviceEventPageQuery DeviceEventDto
+     * @return Page Of DeviceEvent
+     */
+    @PostMapping("/device")
+    public R<Page<DeviceEvent>> deviceEvent(@RequestBody(required = false) DeviceEventPageQuery deviceEventPageQuery) {
+        try {
+            if (ObjectUtil.isEmpty(deviceEventPageQuery)) {
+                deviceEventPageQuery = new DeviceEventPageQuery();
+            }
+            Page<DeviceEvent> page = eventService.deviceEvent(deviceEventPageQuery);
+            if (ObjectUtil.isNotNull(page)) {
+                return R.ok(page);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail();
+    }
+
+}

+ 100 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/DeviceStatusController.java

@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.controller;
+
+import io.github.pnoker.center.data.entity.vo.query.DevicePageQuery;
+import io.github.pnoker.center.data.service.DeviceStatusService;
+import io.github.pnoker.common.constant.common.DefaultConstant;
+import io.github.pnoker.common.constant.common.RequestConstant;
+import io.github.pnoker.common.constant.service.DataServiceConstant;
+import io.github.pnoker.common.entity.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+import java.util.Map;
+
+/**
+ * 设备 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(DataServiceConstant.DEVICE_STATUS_URL_PREFIX)
+public class DeviceStatusController {
+
+    @Resource
+    private DeviceStatusService deviceStatusService;
+
+    /**
+     * 查询 Device 服务状态
+     * ONLINE, OFFLINE, MAINTAIN, FAULT
+     *
+     * @param devicePageQuery Device Dto
+     * @return Map String:String
+     */
+    @PostMapping("/device")
+    public R<Map<String, String>> deviceStatus(@RequestBody(required = false) DevicePageQuery devicePageQuery, @RequestHeader(value = RequestConstant.Header.X_AUTH_TENANT_ID, defaultValue = DefaultConstant.DEFAULT_ID) String tenantId) {
+        try {
+            devicePageQuery.setTenantId(tenantId);
+            Map<String, String> statuses = deviceStatusService.device(devicePageQuery);
+            return R.ok(statuses);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 驱动ID 查询 Device 服务状态
+     * ONLINE, OFFLINE, MAINTAIN, FAULT
+     *
+     * @param driverId Driver ID
+     * @return Map String:String
+     */
+    @GetMapping("/device/driver_id/{driverId}")
+    public R<Map<String, String>> deviceStatusByDriverId(@NotNull @PathVariable(value = "driverId") String driverId) {
+        try {
+            DevicePageQuery devicePageQuery = new DevicePageQuery();
+            devicePageQuery.setDriverId(driverId);
+            Map<String, String> statuses = deviceStatusService.device(devicePageQuery);
+            return R.ok(statuses);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 根据 模板ID 查询 Device 服务状态
+     * ONLINE, OFFLINE, MAINTAIN, FAULT
+     *
+     * @param profileId Profile ID
+     * @return Map String:String
+     */
+    @GetMapping("/device/profile_id/{profileId}")
+    public R<Map<String, String>> deviceStatusByProfileId(@NotNull @PathVariable(value = "profileId") String profileId) {
+        try {
+            Map<String, String> statuses = deviceStatusService.deviceByProfileId(profileId);
+            return R.ok(statuses);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+}

+ 70 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/DriverEventController.java

@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.data.entity.vo.query.DriverEventPageQuery;
+import io.github.pnoker.center.data.service.EventService;
+import io.github.pnoker.common.constant.service.DataServiceConstant;
+import io.github.pnoker.common.entity.DriverEvent;
+import io.github.pnoker.common.entity.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 驱动事件 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(DataServiceConstant.DRIVER_EVENT_URL_PREFIX)
+public class DriverEventController {
+
+    @Resource
+    private EventService eventService;
+
+    /**
+     * 模糊分页查询 DriverEvent
+     *
+     * @param driverEventPageQuery DriverEventDto
+     * @return Page Of DriverEvent
+     */
+    @PostMapping("/driver")
+    public R<Page<DriverEvent>> driverEvent(@RequestBody(required = false) DriverEventPageQuery driverEventPageQuery) {
+        try {
+            if (ObjectUtil.isEmpty(driverEventPageQuery)) {
+                driverEventPageQuery = new DriverEventPageQuery();
+            }
+            Page<DriverEvent> page = eventService.driverEvent(driverEventPageQuery);
+            if (ObjectUtil.isNotNull(page)) {
+                return R.ok(page);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail();
+    }
+
+}

+ 63 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/DriverStatusController.java

@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.controller;
+
+import io.github.pnoker.center.data.entity.vo.query.DriverPageQuery;
+import io.github.pnoker.center.data.service.DriverStatusService;
+import io.github.pnoker.common.constant.common.DefaultConstant;
+import io.github.pnoker.common.constant.common.RequestConstant;
+import io.github.pnoker.common.constant.service.DataServiceConstant;
+import io.github.pnoker.common.entity.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * 设备 Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(DataServiceConstant.DRIVER_STATUS_URL_PREFIX)
+public class DriverStatusController {
+
+    @Resource
+    private DriverStatusService driverStatusService;
+
+    /**
+     * 查询 Driver 服务状态
+     * ONLINE, OFFLINE
+     *
+     * @param driverPageQuery 驱动和分页参数
+     * @return Map String:String
+     */
+    @PostMapping("/driver")
+    public R<Map<String, String>> driverStatus(@RequestBody(required = false) DriverPageQuery driverPageQuery, @RequestHeader(value = RequestConstant.Header.X_AUTH_TENANT_ID, defaultValue = DefaultConstant.DEFAULT_ID) String tenantId) {
+        try {
+            driverPageQuery.setTenantId(tenantId);
+            Map<String, String> statuses = driverStatusService.driver(driverPageQuery);
+            return R.ok(statuses);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+}

+ 43 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/IndexController.java

@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Index Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+//@RequestMapping(value = DataServiceConstant.INDEX_URL_PREFIX)
+public class IndexController {
+
+    /**
+     * ping
+     *
+     * @return DataTime
+     */
+    /*@GetMapping("/ping")
+    public R<String> ping() {
+        return R.ok(TimeUtil.defaultFormat(new Date()));
+    }*/
+
+}

+ 79 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/PointValueCommandController.java

@@ -0,0 +1,79 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.controller;
+
+import io.github.pnoker.center.data.entity.vo.PointValueReadVO;
+import io.github.pnoker.center.data.entity.vo.PointValueWriteVO;
+import io.github.pnoker.center.data.service.PointValueCommandService;
+import io.github.pnoker.common.constant.service.DataServiceConstant;
+import io.github.pnoker.common.entity.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * PointValue Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(DataServiceConstant.VALUE_COMMAND_URL_PREFIX)
+public class PointValueCommandController {
+
+    @Resource
+    private PointValueCommandService pointValueCommandService;
+
+    /**
+     * 读指令
+     *
+     * @param entityVO PointValueReadVO
+     * @return PointValue
+     */
+    @PostMapping("/read")
+    public R<Boolean> read(@Validated @RequestBody PointValueReadVO entityVO) {
+        try {
+            pointValueCommandService.read(entityVO);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.ok();
+    }
+
+    /**
+     * 写指令
+     *
+     * @param entityVO PointValueWriteVO
+     * @return PointValue
+     */
+    @PostMapping("/write")
+    public R<Boolean> write(@Validated @RequestBody PointValueWriteVO entityVO) {
+        try {
+            pointValueCommandService.write(entityVO);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.ok();
+    }
+
+}

+ 92 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/controller/PointValueController.java

@@ -0,0 +1,92 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.github.pnoker.center.data.entity.vo.query.PointValuePageQuery;
+import io.github.pnoker.center.data.service.PointValueService;
+import io.github.pnoker.common.constant.service.DataServiceConstant;
+import io.github.pnoker.common.entity.R;
+import io.github.pnoker.common.entity.point.PointValue;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * PointValue Controller
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping(DataServiceConstant.VALUE_URL_PREFIX)
+public class PointValueController {
+
+    @Resource
+    private PointValueService pointValueService;
+
+    /**
+     * 查询最新 PointValue 集合
+     *
+     * @param pointValuePageQuery 位号值和分页参数
+     * @return 带分页的 {@link io.github.pnoker.common.entity.point.PointValue}
+     */
+    @PostMapping("/latest")
+    public R<Page<PointValue>> latest(@RequestBody PointValuePageQuery pointValuePageQuery) {
+        try {
+            if (ObjectUtil.isEmpty(pointValuePageQuery)) {
+                pointValuePageQuery = new PointValuePageQuery();
+            }
+            Page<PointValue> page = pointValueService.latest(pointValuePageQuery);
+            if (ObjectUtil.isNotNull(page)) {
+                return R.ok(page);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail();
+    }
+
+    /**
+     * 模糊分页查询 PointValue
+     *
+     * @param pointValuePageQuery 位号值和分页参数
+     * @return 带分页的 {@link io.github.pnoker.common.entity.point.PointValue}
+     */
+    @PostMapping("/list")
+    public R<Page<PointValue>> list(@RequestBody(required = false) PointValuePageQuery pointValuePageQuery) {
+        try {
+            if (ObjectUtil.isEmpty(pointValuePageQuery)) {
+                pointValuePageQuery = new PointValuePageQuery();
+            }
+            Page<PointValue> page = pointValueService.list(pointValuePageQuery);
+            if (ObjectUtil.isNotNull(page)) {
+                return R.ok(page);
+            }
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+        return R.fail();
+    }
+
+}

+ 43 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/PointValueReadVO.java

@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.entity.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * Point Value Read VO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PointValueReadVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @NotBlank(message = "Driver id can't be empty")
+    private String deviceId;
+
+    @NotBlank(message = "Point id can't be empty")
+    private String pointId;
+}

+ 46 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/PointValueWriteVO.java

@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.entity.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * Point Value Write VO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PointValueWriteVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @NotBlank(message = "Driver id can't be empty")
+    private String deviceId;
+
+    @NotBlank(message = "Point id can't be empty")
+    private String pointId;
+
+    @NotBlank(message = "Write value can't be empty")
+    private String value;
+}

+ 49 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/DeviceEventPageQuery.java

@@ -0,0 +1,49 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.entity.vo.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DeviceEventPageQuery implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 设备ID
+     */
+    private String deviceId;
+
+    /**
+     * 位号ID
+     */
+    private String pointId;
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 41 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/DevicePageQuery.java

@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.entity.vo.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.Device;
+import lombok.*;
+
+/**
+ * Device DTO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class DevicePageQuery extends Device {
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+
+    private String profileId;
+}

+ 44 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/DriverEventPageQuery.java

@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.entity.vo.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DriverEventPageQuery implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 驱动ID
+     */
+    private String driverId;
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 39 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/DriverPageQuery.java

@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.entity.vo.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.model.DriverDO;
+import lombok.*;
+
+/**
+ * Driver DTO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class DriverPageQuery extends DriverDO {
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 60 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/entity/vo/query/PointValuePageQuery.java

@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.entity.vo.query;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.github.pnoker.common.entity.common.Pages;
+import io.github.pnoker.common.enums.EnableFlagEnum;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * Point Value Page Query VO
+ *
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PointValuePageQuery implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String deviceId;
+    private String pointId;
+
+    /**
+     * 位号名称
+     */
+    private String pointName;
+
+    /**
+     * 使能标识
+     */
+    private EnableFlagEnum enableFlag;
+
+    /**
+     * 是否返回最近历史数据
+     */
+    private Boolean history = false;
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Pages page;
+}

+ 40 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/init/DataInitRunner.java

@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.github.pnoker.center.data.init;
+
+import io.github.pnoker.center.data.service.ScheduleService;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @author pnoker
+ * @since 2022.1.0
+ */
+@Component
+public class DataInitRunner implements ApplicationRunner {
+
+    @Resource
+    private ScheduleService scheduleService;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        scheduleService.initial();
+    }
+}

+ 28 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/mapper/TaosPointValueMapper.java

@@ -0,0 +1,28 @@
+package io.github.pnoker.center.data.mapper;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.github.pnoker.common.entity.point.TaosPointValue;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+@Mapper
+@DS("taos")
+public interface TaosPointValueMapper extends BaseMapper<TaosPointValue> {
+
+    @Update("CREATE STABLE IF NOT EXISTS point_value (create_time TIMESTAMP, point_value NCHAR(32), raw_value NCHAR(32),  origin_time TIMESTAMP) TAGS (device_id NCHAR(32), point_id NCHAR(32))")
+    int createSuperTable();
+
+    @Update("CREATE TABLE IF NOT EXISTS point_value_${deviceId} using point_value TAGS (#{deviceId},#{pointId})")
+    int createDeviceTable(@Param("deviceId") String deviceId, @Param("pointId") String pointId);
+
+    @Insert("INSERT INTO point_value_${deviceId} (create_time,point_value,raw_value,origin_time) VALUES (#{createTime},#{pointValue},#{rawValue},#{originTime})")
+    int insertOne(TaosPointValue taosPointValue);
+
+    @Insert("<script>INSERT INTO point_value_${deviceId} (create_time,point_value,raw_value,origin_time) VALUES <foreach collection='list' item='item' index='index' separator=','>(#{item.createTime},#{item.pointValue},#{item.rawValue},#{item.originTime})</foreach></script>")
+    int batchInsert(List<TaosPointValue> collect);
+}

+ 0 - 0
dc3-center/dc3-center-data/src/main/java/io/github/pnoker/center/data/service/DeviceStatusService.java


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.