168 changed files with 5732 additions and 1178 deletions
@ -0,0 +1,223 @@ |
|||
########################################################################## |
|||
#(100) excluded auto configuration - io.sc.platform.core |
|||
########################################################################## |
|||
spring.autoconfigure.exclude = |
|||
|
|||
########################################################################## |
|||
#(150) application configuration - io.sc.platform.core |
|||
########################################################################## |
|||
# - io.sc.platform.core |
|||
application.audit-log-mode = none |
|||
#application.audit-log-mode = none |
|||
#application.audit-log-mode = log |
|||
#application.audit-log-mode = database |
|||
# - io.sc.platform.installer |
|||
application.installer.enabled = true |
|||
# - io.sc.platform.jdbc.liquibase |
|||
application.updater.enabled = true |
|||
# - io.sc.platform.security |
|||
application.default-password = password |
|||
|
|||
########################################################################## |
|||
#(200) spring.main configuration - io.sc.platform.core |
|||
########################################################################## |
|||
spring.main.allow-bean-definition-overriding = false |
|||
spring.main.banner-mode = console |
|||
spring.main.lazy-initialization = false |
|||
spring.main.log-startup-info = true |
|||
spring.main.register-shutdown-hook = true |
|||
|
|||
########################################################################## |
|||
#(210) jasypt encryptor configuration - io.sc.platform.core |
|||
########################################################################## |
|||
jasypt.encryptor.bean = platformJasyptStringEncryptor |
|||
|
|||
########################################################################## |
|||
#(300) web server configuration - io.sc.platform.mvc |
|||
########################################################################## |
|||
#server.address = 127.0.0.1 |
|||
server.port = 8080 |
|||
server.servlet.context-path = / |
|||
server.servlet.session.timeout = 30m |
|||
server.error.path = /error |
|||
server.error.whitelabel.enabled = true |
|||
server.error.include-exception = true |
|||
server.error.include-binding-errors = always |
|||
server.error.include-message = always |
|||
server.error.include-stacktrace = always |
|||
|
|||
########################################################################## |
|||
#(1000) dataSource configuration - io.sc.platform.jdbc |
|||
########################################################################## |
|||
spring.datasource.items[primary].driver-class-name = org.h2.Driver |
|||
spring.datasource.items[primary].url = jdbc:h2:mem:DB_PLATFORM;DB_CLOSE_DELAY=-1 |
|||
spring.datasource.items[primary].username = platform |
|||
spring.datasource.items[primary].password = platform |
|||
|
|||
########################################################################## |
|||
#(1100) jpa configuration - io.sc.platform.orm.jpa |
|||
########################################################################## |
|||
spring.jpa.open-in-view = false |
|||
spring.jpa.show-sql = false |
|||
spring.jpa.generate-ddl = false |
|||
spring.jpa.hibernate.ddl-auto = none |
|||
spring.jpa.hibernate.jdbc.batch_size = 25 |
|||
spring.jpa.properties.hibernate.enable_lazy_load_no_trans =true |
|||
spring.jpa.properties.hibernate.dialect =org.hibernate.dialect.H2Dialect |
|||
|
|||
########################################################################## |
|||
#(1500) hikari configuration - io.sc.platform.jdbc |
|||
########################################################################## |
|||
#spring.datasource.items[primary].hikari.autoCommit = true |
|||
#spring.datasource.items[primary].hikari.connectionTimeout = 10000 |
|||
#spring.datasource.items[primary].hikari.idleTimeout = 600000 |
|||
#spring.datasource.items[primary].hikari.maxLifetime = 1800000 |
|||
#spring.datasource.items[primary].hikari.minimumIdle = 10 |
|||
#spring.datasource.items[primary].hikari.maximumPoolSize = 10 |
|||
#spring.datasource.items[primary].hikari.metricRegistry = |
|||
#spring.datasource.items[primary].hikari.healthCheckRegistry = |
|||
#spring.datasource.items[primary].hikari.poolName = |
|||
#spring.datasource.items[primary].hikari.initializationFailTimeout = 1 |
|||
#spring.datasource.items[primary].hikari.isolateInternalQueries = false |
|||
#spring.datasource.items[primary].hikari.allowPoolSuspension = false |
|||
#spring.datasource.items[primary].hikari.readOnly = false |
|||
#spring.datasource.items[primary].hikari.registerMbeans = false |
|||
#spring.datasource.items[primary].hikari.catalog = |
|||
#spring.datasource.items[primary].hikari.connectionInitSql = |
|||
#spring.datasource.items[primary].hikari.driverClassName = |
|||
#spring.datasource.items[primary].hikari.transactionIsolation = |
|||
#spring.datasource.items[primary].hikari.validationTimeout = 5000 |
|||
#spring.datasource.items[primary].hikari.leakDetectionThreshold = 0 |
|||
#spring.datasource.items[primary].hikari.dataSource = |
|||
#spring.datasource.items[primary].hikari.schema = |
|||
#spring.datasource.items[primary].hikari.threadFactory = |
|||
#spring.datasource.items[primary].hikari.scheduledExecutor = |
|||
|
|||
########################################################################## |
|||
#(2100) spring.session configuration - io.sc.platform.mvc |
|||
########################################################################## |
|||
spring.session.store-type = none |
|||
#spring.session.store-type = jdbc |
|||
#spring.session.store-type = redis |
|||
spring.session.jdbc.initializer.enabled = false |
|||
spring.session.jdbc.cleanup-cron = 0 */5 * * * * |
|||
spring.session.redis.namespace = spring:session |
|||
spring.session.redis.cleanupCron = 0 */5 * * * * |
|||
|
|||
########################################################################## |
|||
#(2200) spring web configuration (WebProperties) - io.sc.platform.mvc |
|||
########################################################################## |
|||
spring.web.resources.add-mappings = true |
|||
spring.web.resources.cache.cachecontrol.cache-public = true |
|||
spring.web.resources.cache.cachecontrol.must-revalidate = true |
|||
spring.web.resources.chain.cache = true |
|||
spring.web.resources.chain.compressed = true |
|||
|
|||
########################################################################## |
|||
#(2300) management http server configuration - io.sc.platform.mvc |
|||
########################################################################## |
|||
management.endpoints.enabled-by-default = true |
|||
management.endpoints.web.exposure.include = * |
|||
management.context-path = /actuator |
|||
management.security.enabled = false |
|||
|
|||
########################################################################## |
|||
#(2400) thymeleaf configuration - io.sc.platform.mvc |
|||
########################################################################## |
|||
spring.thymeleaf.enabled = true |
|||
spring.thymeleaf.cache = false |
|||
spring.thymeleaf.encoding = UTF-8 |
|||
spring.thymeleaf.mode = HTML |
|||
spring.thymeleaf.prefix = classpath:/templates/ |
|||
spring.thymeleaf.check-template = false |
|||
spring.thymeleaf.check-template-location = false |
|||
spring.thymeleaf.servlet.content-type = text/html |
|||
|
|||
########################################################################## |
|||
#(2500) jackson configuration - io.sc.platform.mvc |
|||
########################################################################## |
|||
spring.jackson.time-zone = Asia/Shanghai |
|||
spring.jackson.date-format = yyyy-MM-dd HH:mm:ss |
|||
spring.jackson.serialization.indent_output = true |
|||
spring.jackson.serialization.fail_on_empty_beans = false |
|||
spring.jackson.deserialization.fail_on_ignored_properties = false |
|||
spring.jackson.parser.allow_comments = true |
|||
spring.jackson.parser.allow_single_quotes = true |
|||
spring.jackson.parser.allow_trailing_comma = true |
|||
spring.jackson.parser.allow_unquoted_field_names = true |
|||
spring.jackson.parser.ignore_undefined = true |
|||
spring.jackson.parser.allow_unquoted_control_chars = true |
|||
|
|||
########################################################################## |
|||
#(2600) i18n message source configuration - io.sc.platform.mvc |
|||
########################################################################## |
|||
spring.messages.alwaysUseMessageFormat = false |
|||
spring.messages.cacheDuration = -1 |
|||
spring.messages.encoding = UTF-8 |
|||
spring.messages.fallbackToSystemLocale = false |
|||
spring.messages.useCodeAsDefaultMessage = true |
|||
|
|||
########################################################################## |
|||
#(3000) platform security configuration - io.sc.platform.security.loginform |
|||
########################################################################## |
|||
spring.security.formLogin.loginPage = /login |
|||
spring.security.formLogin.loginProcessingUrl = /login |
|||
spring.security.formLogin.failureUrl = /login-error |
|||
spring.security.logout.logoutUrl = /logout |
|||
spring.security.logout.logoutSuccessUrl = / |
|||
|
|||
########################################################################## |
|||
#(4000) email configuration - io.sc.platform.communication |
|||
########################################################################## |
|||
spring.mail.host=zzz.xxx.yyy |
|||
spring.mail.port=25 |
|||
spring.mail.protocol=smtp |
|||
spring.mail.test-connection=false |
|||
spring.mail.default-encoding=UTF-8 |
|||
spring.mail.properties.mail.smtp.auth=true |
|||
spring.mail.username=xxx |
|||
spring.mail.password=yyy |
|||
|
|||
########################################################################## |
|||
#(5000) flowable bpm configuration - io.sc.platform.flowable |
|||
########################################################################## |
|||
# core |
|||
flowable.asyncExecutorActivate =false |
|||
flowable.asyncHistoryExecutorActivate = false |
|||
flowable.check-process-definitions=false |
|||
flowable.custom-mybatis-mappers= |
|||
flowable.custom-mybatis-x-m-l-mappers= |
|||
flowable.database-schema= |
|||
flowable.database-schema-update=true |
|||
flowable.db-history-used=true |
|||
flowable.deployment-name=SpringBootAutoDeployment |
|||
flowable.history-level= |
|||
flowable.process-definition-location-prefix=classpath*:/processes/ |
|||
flowable.process-definition-location-suffixes=**.bpmn20.xml,**.bpmn |
|||
# process |
|||
flowable.process.definition-cache-limit=-1 |
|||
flowable.process.enable-safe-xml=true |
|||
flowable.process.servlet.load-on-startup=-1 |
|||
flowable.process.servlet.name=Flowable BPMN Rest API |
|||
flowable.process.servlet.path=/process-api |
|||
# cmmn |
|||
flowable.cmmn.enabled=false |
|||
# content |
|||
flowable.content.enabled=false |
|||
# dmn |
|||
flowable.dmn.enabled=false |
|||
# form |
|||
flowable.form.enabled=false |
|||
# idm |
|||
flowable.idm.enabled=false |
|||
|
|||
########################################################################## |
|||
#(8000) cxf configuration - io.sc.platform.ws.cxf |
|||
########################################################################## |
|||
cxf.path = /webservices |
|||
|
|||
########################################################################## |
|||
#(9000) p6spy configuration - io.sc.platform.jdbc |
|||
########################################################################## |
|||
p6spy.enabled = true |
|||
p6spy.ignorePattern = false |
@ -0,0 +1,48 @@ |
|||
************************************************************************************** |
|||
Name: app.platform |
|||
Version: ${application.version} |
|||
Base on Spring Boot ${spring-boot.version} |
|||
************************************************************************************** |
|||
System.environment: |
|||
-------------------------------------------------------------------------------------- |
|||
java.specification.version = 1.8 |
|||
java.specification.vendor = Oracle Corporation |
|||
java.specification.name = Java Platform API Specification |
|||
java.vm.specification.version = 1.8 |
|||
java.vm.specification.vendor = Oracle Corporation |
|||
java.vm.specification.name = Java Virtual Machine Specification |
|||
java.home = /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre |
|||
java.version = 1.8.0_332 |
|||
java.vendor = Azul Systems, Inc. |
|||
java.vendor.url = http://www.azul.com/ |
|||
java.vm.version = 25.332-b09 |
|||
java.vm.vendor = Azul Systems, Inc. |
|||
java.vm.name = OpenJDK 64-Bit Server VM |
|||
java.class.version = 52.0 |
|||
java.class.path = ${java.class.path2} |
|||
java.library.path = /Users/wangshaoping/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:. |
|||
java.io.tmpdir = /var/folders/82/6m96_g610hj1v1tcpvhtjysr0000gn/T/ |
|||
java.ext.dirs = /Users/wangshaoping/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java |
|||
os.name = Mac OS X |
|||
os.arch = aarch64 |
|||
os.version = 13.5.1 |
|||
user.name = wangshaoping |
|||
user.home = /Users/wangshaoping |
|||
user.dir = /Users/wangshaoping/wspsc/workspace/wangshaoping/v8/platform |
|||
|
|||
Application.environment |
|||
-------------------------------------------------------------------------------------- |
|||
application.name = app.platform |
|||
application.is-running-in-development = false |
|||
application.is-running-in-web-container = false |
|||
|
|||
application.home.dir = /Users/wangshaoping/wspsc/workspace/wangshaoping/v8/platform |
|||
application.installer.enabled = ${application.installer.enabled} |
|||
application.updater.enabled = ${application.updater.enabled} |
|||
application.audit-log-mode = ${application.audit-log-mode} |
|||
spring.config.location = file:/Users/wangshaoping/wspsc/workspace/wangshaoping/v8/platform/config/application.properties |
|||
spring.banner.location = file:/Users/wangshaoping/wspsc/workspace/wangshaoping/v8/platform/config/banner.txt |
|||
logging.config = file:/Users/wangshaoping/wspsc/workspace/wangshaoping/v8/platform/config/logback-spring.xml |
|||
p6spy.enabled = ${p6spy.enabled} |
|||
p6spy.ignorePattern = ${p6spy.ignorePattern} |
|||
************************************************************************************** |
@ -0,0 +1,216 @@ |
|||
Apache License |
|||
Version 2.0, January 2004 |
|||
https://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 |
|||
|
|||
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. |
|||
|
|||
======================================================================= |
|||
|
|||
To the extent any open source subcomponents are licensed under the EPL and/or other |
|||
similar licenses that require the source code and/or modifications to |
|||
source code to be made available (as would be noted above), you may obtain a |
|||
copy of the source code corresponding to the binaries for such open source |
|||
components and modifications thereto, if any, (the "Source Files"), by |
|||
downloading the Source Files from https://www.springsource.org/download, |
|||
or by sending a request, with your name and address to: VMware, Inc., 3401 Hillview |
|||
Avenue, Palo Alto, CA 94304, United States of America or email info@vmware.com. All |
|||
such requests should clearly specify: OPEN SOURCE FILES REQUEST, Attention General |
|||
Counsel. VMware shall mail a copy of the Source Files to you on a CD or equivalent |
|||
physical medium. This offer to obtain a copy of the Source Files is valid for three |
|||
years from the date you acquired this Software product. |
@ -0,0 +1,66 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!-- 自动扫描本文件,如果发生变化,则重新初始化日志系统,并设置每隔5秒钟扫描一次 --> |
|||
<configuration debug="false" scan="true" scanPeriod="5 seconds"> |
|||
<!-- |
|||
以下为 logback 的 spring 扩展支持的功能,即支持从 application.properties 文件中获取属性,并在此文件中采用 ${} 方式使用。 |
|||
要使用此功能,必须使用 logback-ext-spring 扩展 jar 包,以 gradle 构建系统,则需要加入以下依赖 |
|||
dependencies { |
|||
compile( |
|||
"org.logback-extensions:logback-ext-spring:0.1.2" |
|||
) |
|||
} |
|||
--> |
|||
<property name="homedir" value="/Users/wangshaoping/wspsc/workspace/wangshaoping/v8/platform"/> |
|||
<property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"/> |
|||
|
|||
<!-- 在控制台中输出日志 --> |
|||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
|||
<encoder><pattern>${pattern}</pattern></encoder> |
|||
</appender> |
|||
|
|||
<!-- 在磁盘文件中输出日志 --> |
|||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
|||
<encoder><pattern>${pattern}</pattern></encoder> |
|||
<file>${homedir}/logs/log.log</file> |
|||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|||
<fileNamePattern>${homedir}/logs/log.%d.log</fileNamePattern> |
|||
<maxHistory>30</maxHistory> |
|||
</rollingPolicy> |
|||
</appender> |
|||
|
|||
<root level="info"> |
|||
<appender-ref ref="STDOUT" /> |
|||
<appender-ref ref="FILE" /> |
|||
</root> |
|||
|
|||
<logger name="org.wsp.engine.model.core.code" level="info" additivity="false"/> |
|||
|
|||
<logger name="org.wsp.engine.rule.core.code" level="debug" additivity="false"> |
|||
<appender-ref ref="STDOUT" /> |
|||
<appender-ref ref="FILE" /> |
|||
</logger> |
|||
|
|||
<logger name="org.springframework.security" level="info" additivity="false"> |
|||
<appender-ref ref="STDOUT" /> |
|||
<appender-ref ref="FILE" /> |
|||
</logger> |
|||
|
|||
|
|||
<!-- 可对不同的日志写入不同的文件示例 --> |
|||
<!-- |
|||
<appender name="RULE_ENGINE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
|||
<encoder><pattern>${pattern}</pattern></encoder> |
|||
<file>${homedir}/logs/rule-engine.log</file> |
|||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|||
<fileNamePattern>${homedir}/logs/rule-engine.%d.log</fileNamePattern> |
|||
<maxHistory>30</maxHistory> |
|||
</rollingPolicy> |
|||
</appender> |
|||
|
|||
<logger name="org.wsp.engine.rule.core.code" level="debug" additivity="false"> |
|||
<appender-ref ref="STDOUT" /> |
|||
<appender-ref ref="FILE" /> |
|||
<appender-ref ref="RULE_ENGINE_FILE" /> |
|||
</logger> |
|||
--> |
|||
</configuration> |
@ -0,0 +1,167 @@ |
|||
import { laBell } from '@quasar/extras/line-awesome'; import { mergeProps } from 'vue'; import { pushScopeId } from 'vue'; import { clear } from 'console'; |
|||
<template> |
|||
<div> |
|||
<div class="flex justify-between"> |
|||
<div class="text-h6">{{ title }}</div> |
|||
<div class="flex justify-end gap-4"> |
|||
<template v-for="(btn, index) in actions as any" :key="index"> |
|||
<q-btn v-if="typeof btn === 'object'" :loading="btn.loading ? btn.loading : false" :label="btn.label" :icon="btn.icon" outline @click="btn.click()"> |
|||
</q-btn> |
|||
</template> |
|||
</div> |
|||
</div> |
|||
<q-tree |
|||
ref="tree" |
|||
v-bind="attrs" |
|||
v-model:selected="selectedRef" |
|||
v-model:ticked="tickedRef" |
|||
v-model:expanded="expandedRef" |
|||
class="w-full" |
|||
:nodes="nodesRef" |
|||
node-key="id" |
|||
label-key="i18nLabel" |
|||
/> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref, useAttrs, toRaw } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { TreeBuilder } from '@/platform'; |
|||
|
|||
const attrs = useAttrs(); |
|||
const props = defineProps({ |
|||
title: { type: String, default: '' }, |
|||
labelI18n: { type: Boolean, default: false }, |
|||
labelEmpty: { type: String, default: '' }, |
|||
actions: { type: Array, default: () => [] }, |
|||
}); |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const tree = ref(); |
|||
|
|||
const nodesCache = new Map<string, object>(); |
|||
const nodesRef = ref(TreeBuilder.build(attrs.nodes)); |
|||
const selectedRef = ref([]); |
|||
const tickedRef = ref([]); |
|||
const expandedRef = ref([]); |
|||
|
|||
const getNodeById = (id: string) => { |
|||
return nodesCache.get(id); |
|||
}; |
|||
|
|||
const setNodes = (nodes) => { |
|||
nodesCache.clear(); |
|||
const tickeds = []; |
|||
if (nodes && nodes.length > 0) { |
|||
const labelKey = attrs['label-key']; |
|||
for (const node of nodes) { |
|||
const label = node[labelKey]; |
|||
if (props.labelI18n) { |
|||
if (label) { |
|||
node.i18nLabel = t(label); |
|||
} else { |
|||
if (props.labelEmpty) { |
|||
node.i18nLabel = t(props.labelEmpty); |
|||
} else { |
|||
node.i18nLabel = label; |
|||
} |
|||
} |
|||
} else { |
|||
node.i18nLabel = label; |
|||
} |
|||
nodesCache.set(node.id, node); |
|||
if (node.selected) { |
|||
tickeds.push(node.id); |
|||
} |
|||
} |
|||
} |
|||
nodesRef.value = TreeBuilder.build(nodes); |
|||
tickedRef.value = tickeds; |
|||
}; |
|||
|
|||
const getSelectedNode = () => { |
|||
return nodesCache.get(selectedRef.value); |
|||
}; |
|||
|
|||
const getSelected = () => { |
|||
return selectedRef.value; |
|||
}; |
|||
|
|||
const setSelected = (selected) => { |
|||
selectedRef.value = selected; |
|||
}; |
|||
|
|||
const setTicked = (ticked) => { |
|||
tickedRef.value = ticked; |
|||
}; |
|||
|
|||
const getTicked = () => { |
|||
const result = new Set<string>(); |
|||
const tickeds = toRaw(tickedRef.value); |
|||
if (tickeds && tickeds.length > 0) { |
|||
for (const ticked of tickeds) { |
|||
result.add(ticked); |
|||
} |
|||
for (const ticked of tickeds) { |
|||
getAllParentIds(nodesCache.get(ticked).parentId, result); |
|||
} |
|||
} |
|||
return [...result]; |
|||
}; |
|||
|
|||
const getAllParentIds = (parentId, result) => { |
|||
if (parentId) { |
|||
const parent = nodesCache.get(parentId); |
|||
if (parent) { |
|||
result.add(parent.id); |
|||
getAllParentIds(parent.parentId, result); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
const getCascadeParentIds = (id) => { |
|||
const result = []; |
|||
let node = nodesCache.get(id); |
|||
if (node) { |
|||
result.push(id); |
|||
while (node.parentId) { |
|||
result.push(node.parentId); |
|||
node = nodesCache.get(node.parentId); |
|||
} |
|||
} |
|||
return result; |
|||
}; |
|||
|
|||
const getCascadeChildrenIds = (id) => { |
|||
const result = []; |
|||
let node = nodesCache.get(id); |
|||
if (node) { |
|||
if (node.children && node.children.length > 0) { |
|||
for (const child of node.children) { |
|||
result.push(child.id); |
|||
const childResult = getCascadeChildrenIds(child.id); |
|||
if (childResult && childResult.length > 0) { |
|||
result.push(...childResult); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return result; |
|||
}; |
|||
|
|||
defineExpose({ |
|||
getNodeById, |
|||
setNodes, |
|||
|
|||
getTicked, |
|||
setTicked, |
|||
|
|||
getSelectedNode, |
|||
getSelected, |
|||
setSelected, |
|||
|
|||
getCascadeParentIds, |
|||
getCascadeChildrenIds, |
|||
}); |
|||
</script> |
@ -0,0 +1,58 @@ |
|||
<template> |
|||
<div> |
|||
<w-tree-grid |
|||
ref="treeGrid" |
|||
title="机构树" |
|||
:nodes="nodes" |
|||
label-key="titleI18nKey" |
|||
label-i18n |
|||
label-empty="--------------------" |
|||
:actions="actions" |
|||
tick-strategy="leaf" |
|||
/> |
|||
<q-btn label="ok" @click="ok"></q-btn> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref, toRaw, onMounted } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { Environment, axios, BackendTools } from '@/platform'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const treeGrid = ref(); |
|||
const nodes = ref([]); |
|||
const selected = []; |
|||
const ticked = []; |
|||
const expanded = []; |
|||
const actions = [ |
|||
{ |
|||
name: 'refresh', |
|||
label: '刷新', |
|||
}, |
|||
{ |
|||
name: 'expandAll', |
|||
label: '全部展开', |
|||
}, |
|||
{ |
|||
name: 'selectAll', |
|||
label: '全部选择', |
|||
}, |
|||
{ |
|||
name: 'save', |
|||
label: '保存', |
|||
}, |
|||
]; |
|||
|
|||
onMounted(() => { |
|||
axios.get(Environment.apiContextPath('/api/system/menu?pageable=false')).then((response) => { |
|||
treeGrid.value.setNodes(response.data.content); |
|||
}); |
|||
}); |
|||
|
|||
const ok = () => { |
|||
console.log(treeGrid.value.getCascadeParentIds(treeGrid.value.getSelected())); |
|||
console.log(treeGrid.value.getCascadeChildrenIds(treeGrid.value.getSelected())); |
|||
console.log(treeGrid.value.getSelectedNode(treeGrid.value.getSelected())); |
|||
}; |
|||
</script> |
@ -0,0 +1,58 @@ |
|||
<template> |
|||
<div> |
|||
<w-tree-grid |
|||
ref="treeGrid" |
|||
title="机构树" |
|||
:nodes="nodes" |
|||
label-key="titleI18nKey" |
|||
label-i18n |
|||
label-empty="--------------------" |
|||
:actions="actions" |
|||
tick-strategy="leaf" |
|||
/> |
|||
<q-btn label="ok" @click="ok"></q-btn> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref, toRaw, onMounted } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { Environment, axios, BackendTools } from '@/platform'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const treeGrid = ref(); |
|||
const nodes = ref([]); |
|||
const selected = []; |
|||
const ticked = []; |
|||
const expanded = []; |
|||
const actions = [ |
|||
{ |
|||
name: 'refresh', |
|||
label: '刷新', |
|||
}, |
|||
{ |
|||
name: 'expandAll', |
|||
label: '全部展开', |
|||
}, |
|||
{ |
|||
name: 'selectAll', |
|||
label: '全部选择', |
|||
}, |
|||
{ |
|||
name: 'save', |
|||
label: '保存', |
|||
}, |
|||
]; |
|||
|
|||
onMounted(() => { |
|||
axios.get(Environment.apiContextPath('/api/system/menu?pageable=false')).then((response) => { |
|||
treeGrid.value.setNodes(response.data.content); |
|||
}); |
|||
}); |
|||
|
|||
const ok = () => { |
|||
console.log(treeGrid.value.getCascadeParentIds(treeGrid.value.getSelected())); |
|||
console.log(treeGrid.value.getCascadeChildrenIds(treeGrid.value.getSelected())); |
|||
console.log(treeGrid.value.getSelectedNode(treeGrid.value.getSelected())); |
|||
}; |
|||
</script> |
@ -1,104 +1,102 @@ |
|||
{ |
|||
"name": "io.sc.platform.developer.frontend", |
|||
"version": "8.1.11", |
|||
"description": "", |
|||
"private": false, |
|||
"keywords": [ |
|||
|
|||
], |
|||
"author": "", |
|||
"license": "ISC", |
|||
"scripts": { |
|||
"clean": "rm -rf ./node_modules && rm -rf pnpm-lock.yaml", |
|||
"dev": "nodemon", |
|||
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs", |
|||
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs", |
|||
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs", |
|||
"sync": "platform sync" |
|||
}, |
|||
"engines": { |
|||
"node": ">=18", |
|||
"pnpm": ">=7" |
|||
}, |
|||
"publishConfig": { |
|||
"registry": "http://nexus.sc.io:8000/repository/npm-releases/", |
|||
"access": "public" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/core": "7.23.2", |
|||
"@babel/preset-env": "7.23.2", |
|||
"@babel/preset-typescript": "7.23.2", |
|||
"@babel/plugin-transform-class-properties": "7.22.5", |
|||
"@babel/plugin-transform-object-rest-spread": "7.22.15", |
|||
"@quasar/app-webpack": "3.11.2", |
|||
"@quasar/cli": "2.3.0", |
|||
"@types/mockjs": "1.0.9", |
|||
"@types/node": "20.8.9", |
|||
"@typescript-eslint/eslint-plugin": "6.9.0", |
|||
"@typescript-eslint/parser": "6.9.0", |
|||
"@vue/compiler-sfc": "3.3.7", |
|||
"@webpack-cli/serve": "2.0.5", |
|||
"autoprefixer": "10.4.16", |
|||
"babel-loader": "9.1.3", |
|||
"clean-webpack-plugin": "4.0.0", |
|||
"copy-webpack-plugin": "11.0.0", |
|||
"cross-env": "7.0.3", |
|||
"css-loader": "6.8.1", |
|||
"eslint": "8.52.0", |
|||
"eslint-config-prettier": "9.0.0", |
|||
"eslint-plugin-prettier": "5.0.1", |
|||
"eslint-plugin-vue": "9.18.0", |
|||
"eslint-webpack-plugin": "4.0.1", |
|||
"html-webpack-plugin": "5.5.3", |
|||
"json5": "2.2.3", |
|||
"mini-css-extract-plugin": "2.7.6", |
|||
"nodemon": "3.0.1", |
|||
"postcss": "8.4.31", |
|||
"postcss-import": "15.1.0", |
|||
"postcss-loader": "7.3.3", |
|||
"postcss-preset-env": "9.2.0", |
|||
"prettier": "3.0.3", |
|||
"sass": "1.69.5", |
|||
"sass-loader": "13.3.2", |
|||
"typescript": "5.2.2", |
|||
"vue-loader": "17.3.0", |
|||
"webpack": "5.89.0", |
|||
"webpack-bundle-analyzer": "4.9.1", |
|||
"webpack-cli": "5.1.4", |
|||
"webpack-dev-server": "4.15.1", |
|||
"webpack-merge": "5.10.0" |
|||
}, |
|||
"dependencies": { |
|||
"@quasar/extras": "1.16.7", |
|||
"@vueuse/core": "10.3.0", |
|||
"axios": "1.5.1", |
|||
"dayjs": "1.11.10", |
|||
"echarts": "5.4.1", |
|||
"exceljs": "4.3.0", |
|||
"file-saver": "2.0.5", |
|||
"luckyexcel": "1.0.1", |
|||
"mockjs": "1.1.0", |
|||
"pinia": "2.1.7", |
|||
"platform-core": "8.1.27", |
|||
"quasar": "2.13.0", |
|||
"tailwindcss": "3.3.5", |
|||
"vue": "3.3.7", |
|||
"vue-dompurify-html": "4.1.4", |
|||
"vue-i18n": "9.6.0", |
|||
"vue-router": "4.2.5", |
|||
"@codemirror/autocomplete": "6.11.1", |
|||
"@codemirror/commands": "6.3.2", |
|||
"@codemirror/lang-html": "6.4.7", |
|||
"@codemirror/lang-java": "6.0.1", |
|||
"@codemirror/lang-javascript": "6.2.1", |
|||
"@codemirror/lang-json": "6.0.1", |
|||
"@codemirror/lang-sql": "6.5.4", |
|||
"@codemirror/lang-xml": "6.0.2", |
|||
"@codemirror/language": "6.9.3", |
|||
"@codemirror/search": "6.5.5", |
|||
"@codemirror/state": "6.3.3", |
|||
"@codemirror/view": "6.22.1", |
|||
"codemirror": "6.0.1", |
|||
"vue-codemirror6": "1.1.31" |
|||
} |
|||
"name": "io.sc.platform.developer.frontend", |
|||
"version": "8.1.12", |
|||
"description": "", |
|||
"private": false, |
|||
"keywords": [], |
|||
"author": "", |
|||
"license": "ISC", |
|||
"scripts": { |
|||
"clean": "rm -rf ./node_modules && rm -rf pnpm-lock.yaml", |
|||
"dev": "nodemon", |
|||
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs", |
|||
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs", |
|||
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs", |
|||
"sync": "platform sync" |
|||
}, |
|||
"engines": { |
|||
"node": ">=18", |
|||
"pnpm": ">=7" |
|||
}, |
|||
"publishConfig": { |
|||
"registry": "http://nexus.sc.io:8000/repository/npm-releases/", |
|||
"access": "public" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/core": "7.23.2", |
|||
"@babel/preset-env": "7.23.2", |
|||
"@babel/preset-typescript": "7.23.2", |
|||
"@babel/plugin-transform-class-properties": "7.22.5", |
|||
"@babel/plugin-transform-object-rest-spread": "7.22.15", |
|||
"@quasar/app-webpack": "3.11.2", |
|||
"@quasar/cli": "2.3.0", |
|||
"@types/mockjs": "1.0.9", |
|||
"@types/node": "20.8.9", |
|||
"@typescript-eslint/eslint-plugin": "6.9.0", |
|||
"@typescript-eslint/parser": "6.9.0", |
|||
"@vue/compiler-sfc": "3.3.7", |
|||
"@webpack-cli/serve": "2.0.5", |
|||
"autoprefixer": "10.4.16", |
|||
"babel-loader": "9.1.3", |
|||
"clean-webpack-plugin": "4.0.0", |
|||
"copy-webpack-plugin": "11.0.0", |
|||
"cross-env": "7.0.3", |
|||
"css-loader": "6.8.1", |
|||
"eslint": "8.52.0", |
|||
"eslint-config-prettier": "9.0.0", |
|||
"eslint-plugin-prettier": "5.0.1", |
|||
"eslint-plugin-vue": "9.18.0", |
|||
"eslint-webpack-plugin": "4.0.1", |
|||
"html-webpack-plugin": "5.5.3", |
|||
"json5": "2.2.3", |
|||
"mini-css-extract-plugin": "2.7.6", |
|||
"nodemon": "3.0.1", |
|||
"postcss": "8.4.31", |
|||
"postcss-import": "15.1.0", |
|||
"postcss-loader": "7.3.3", |
|||
"postcss-preset-env": "9.2.0", |
|||
"prettier": "3.0.3", |
|||
"sass": "1.69.5", |
|||
"sass-loader": "13.3.2", |
|||
"typescript": "5.2.2", |
|||
"vue-loader": "17.3.0", |
|||
"webpack": "5.89.0", |
|||
"webpack-bundle-analyzer": "4.9.1", |
|||
"webpack-cli": "5.1.4", |
|||
"webpack-dev-server": "4.15.1", |
|||
"webpack-merge": "5.10.0" |
|||
}, |
|||
"dependencies": { |
|||
"@quasar/extras": "1.16.7", |
|||
"@vueuse/core": "10.3.0", |
|||
"axios": "1.5.1", |
|||
"dayjs": "1.11.10", |
|||
"echarts": "5.4.1", |
|||
"exceljs": "4.3.0", |
|||
"file-saver": "2.0.5", |
|||
"luckyexcel": "1.0.1", |
|||
"mockjs": "1.1.0", |
|||
"pinia": "2.1.7", |
|||
"platform-core": "8.1.37", |
|||
"quasar": "2.13.0", |
|||
"tailwindcss": "3.3.5", |
|||
"vue": "3.3.7", |
|||
"vue-dompurify-html": "4.1.4", |
|||
"vue-i18n": "9.6.0", |
|||
"vue-router": "4.2.5", |
|||
"@codemirror/autocomplete": "6.11.1", |
|||
"@codemirror/commands": "6.3.2", |
|||
"@codemirror/lang-html": "6.4.7", |
|||
"@codemirror/lang-java": "6.0.1", |
|||
"@codemirror/lang-javascript": "6.2.1", |
|||
"@codemirror/lang-json": "6.0.1", |
|||
"@codemirror/lang-sql": "6.5.4", |
|||
"@codemirror/lang-xml": "6.0.2", |
|||
"@codemirror/language": "6.9.3", |
|||
"@codemirror/search": "6.5.5", |
|||
"@codemirror/state": "6.3.3", |
|||
"@codemirror/view": "6.22.1", |
|||
"codemirror": "6.0.1", |
|||
"vue-codemirror6": "1.1.31" |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
{ |
|||
"name": "app.platform", |
|||
"components": [ |
|||
], |
|||
"resources": [ |
|||
"/public/configure.js", |
|||
"/public/favicon.svg", |
|||
"/public/login-bg.jpg", |
|||
"/public/logo.svg" |
|||
] |
|||
} |
@ -0,0 +1,7 @@ |
|||
//ext['oracle-database.version'] = '12.2.0.1' |
|||
|
|||
dependencies { |
|||
api( |
|||
"oracle:oracle:12.2.0.1", |
|||
) |
|||
} |
@ -0,0 +1,10 @@ |
|||
{ |
|||
"installerEnable" : true, |
|||
"type" : "Oracle", |
|||
"version" : "12.2", |
|||
"driver" : "oracle.jdbc.OracleDriver", |
|||
"url" : "jdbc:oracle:thin:@${host}:${port}:${sid}", |
|||
"urlSample" : "jdbc:oracle:thin:@localhost:1521:EE", |
|||
"hibernateDialect" : "org.hibernate.dialect.Oracle10gDialect", |
|||
"validationQuery" : "select 1 from dual" |
|||
} |
@ -1,6 +1,7 @@ |
|||
//ext['oracle-database.version'] = '12.2.0.1' |
|||
|
|||
dependencies { |
|||
api( |
|||
"com.oracle.database.jdbc:ojdbc8", |
|||
"com.oracle.database.nls:orai18n" |
|||
"oracle:oracle:12.2.0.1", |
|||
) |
|||
} |
|||
} |
|||
|
@ -0,0 +1,12 @@ |
|||
dependencies { |
|||
api( |
|||
project(":io.sc.platform.jdbc"), |
|||
|
|||
"us.fatehi:schemacrawler:${schemacrawler_version}", |
|||
"us.fatehi:schemacrawler-mysql:${schemacrawler_version}", |
|||
"us.fatehi:schemacrawler-oracle:${schemacrawler_version}", |
|||
"us.fatehi:schemacrawler-db2:${schemacrawler_version}", |
|||
"us.fatehi:schemacrawler-postgresql:${schemacrawler_version}", |
|||
"us.fatehi:schemacrawler-sqlite:${schemacrawler_version}", |
|||
) |
|||
} |
@ -0,0 +1 @@ |
|||
|
@ -0,0 +1,218 @@ |
|||
package io.sc.platform.jdbc.schemacrawler; |
|||
|
|||
import io.sc.platform.jdbc.DatabaseType; |
|||
import io.sc.platform.jdbc.meta.MetaDataLoader; |
|||
import io.sc.platform.jdbc.meta.support.*; |
|||
import org.springframework.jdbc.datasource.DataSourceUtils; |
|||
import schemacrawler.schema.Catalog; |
|||
import schemacrawler.schema.TableRelationshipType; |
|||
import schemacrawler.schemacrawler.*; |
|||
import schemacrawler.utility.SchemaCrawlerUtility; |
|||
|
|||
import javax.sql.DataSource; |
|||
import java.sql.Connection; |
|||
import java.sql.SQLException; |
|||
import java.util.*; |
|||
|
|||
public class MetaDataLoaderImpl implements MetaDataLoader { |
|||
private Map<DataSource, Catalog> catalogs =new HashMap<DataSource,Catalog>(); |
|||
private Object lock =new Object(); |
|||
|
|||
public void crawler(DataSource dataSource) throws SQLException { |
|||
crawler(dataSource,getDefaultOptions(dataSource)); |
|||
} |
|||
|
|||
public void crawler(DataSource dataSource, SchemaCrawlerOptions options) throws SQLException { |
|||
//catalogs.clear();
|
|||
Connection connection = null; |
|||
try { |
|||
connection = DataSourceUtils.getConnection(dataSource); |
|||
synchronized (lock) { |
|||
catalogs.put(dataSource, SchemaCrawlerUtility.getCatalog(connection,getDefaultOptions(dataSource))); |
|||
} |
|||
}catch (SchemaCrawlerException e) { |
|||
throw new SQLException(e); |
|||
}finally { |
|||
DataSourceUtils.releaseConnection(connection, dataSource); |
|||
} |
|||
} |
|||
|
|||
public Catalog getCatalog(DataSource dataSource) throws SQLException{ |
|||
return getCatalog(dataSource,getDefaultOptions(dataSource)); |
|||
} |
|||
|
|||
public Catalog getCatalog(DataSource dataSource, SchemaCrawlerOptions options) throws SQLException{ |
|||
synchronized (lock) { |
|||
if(!catalogs.containsKey(dataSource)) { |
|||
crawler(dataSource,options); |
|||
} |
|||
return catalogs.get(dataSource); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public List<Schema> getSchemas(DataSource dataSource) throws MetaDataAccessException { |
|||
Catalog catalog = null; |
|||
try { |
|||
catalog = getCatalog(dataSource); |
|||
} catch (SQLException e) { |
|||
throw new MetaDataAccessException(e); |
|||
} |
|||
if(catalog!=null) { |
|||
Collection<schemacrawler.schema.Schema> schemas =catalog.getSchemas(); |
|||
if(schemas!=null && schemas.size()>0) { |
|||
List<Schema> result =new ArrayList<>(); |
|||
for(schemacrawler.schema.Schema schema : schemas){ |
|||
result.add(from(schema)); |
|||
} |
|||
return result; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public List<TableSummary> getTableSummary(DataSource dataSource, String schemaName) throws MetaDataAccessException { |
|||
List<Table> tables =getTables(dataSource,schemaName); |
|||
List<TableSummary> result =new ArrayList<>(); |
|||
for(Table table : tables){ |
|||
TableSummary summary =new TableSummary(); |
|||
summary.setName(table.getName()); |
|||
summary.setRemarks(table.getRemarks()); |
|||
result.add(summary); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public List<TableSummary> getTableSummary(DataSource dataSource, String schemaName, boolean isCount) throws MetaDataAccessException { |
|||
return getTableSummary(dataSource,schemaName,false); |
|||
} |
|||
|
|||
@Override |
|||
public List<Table> getTables(DataSource dataSource, String schemaName, String... tableNames) throws MetaDataAccessException { |
|||
Catalog catalog = null; |
|||
try { |
|||
catalog = getCatalog(dataSource); |
|||
} catch (SQLException e) { |
|||
throw new MetaDataAccessException(e); |
|||
} |
|||
if(catalog!=null) { |
|||
schemacrawler.schema.Schema schema =findSchema(catalog,schemaName); |
|||
if(schema!=null) { |
|||
Collection<schemacrawler.schema.Table> tables =catalog.getTables(schema); |
|||
if(tables!=null && tables.size()>0) { |
|||
List<Table> result =new ArrayList<Table>(); |
|||
for(schemacrawler.schema.Table table : tables){ |
|||
result.add(from(table)); |
|||
} |
|||
return result; |
|||
} |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public boolean isSelfReference(schemacrawler.schema.Table table) { |
|||
Collection<schemacrawler.schema.Table> parentTables =table.getRelatedTables(TableRelationshipType.parent); |
|||
if(parentTables!=null && !parentTables.isEmpty()) { |
|||
for(schemacrawler.schema.Table parentTable : parentTables) { |
|||
if(parentTable.equals(table)) { |
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
private Schema from(schemacrawler.schema.Schema schema){ |
|||
Schema result =new Schema(); |
|||
result.setName(schema.getName()==null?schema.getCatalogName():schema.getName()); |
|||
return result; |
|||
} |
|||
|
|||
private Table from(schemacrawler.schema.Table table){ |
|||
Table result =new Table(); |
|||
result.setName(table.getName()); |
|||
result.setRemarks(table.getRemarks()); |
|||
// 处理列
|
|||
for(schemacrawler.schema.Column column : table.getColumns()) { |
|||
result.getColumns().add(from(column)); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
private Column from(schemacrawler.schema.Column column){ |
|||
Column result =new Column(); |
|||
result.setName(column.getName()); |
|||
result.setRemarks(column.getRemarks()); |
|||
result.setJavaType(column.getType().getTypeMappedClass()); |
|||
result.setSqlType(column.getColumnDataType().getJavaSqlType().getName()); |
|||
result.setVendorTypeNumber(column.getColumnDataType().getJavaSqlType().getVendorTypeNumber()); |
|||
result.setNullable(column.isNullable()); |
|||
result.setDefaultValue(column.getDefaultValue()); |
|||
result.setGenerated(column.isGenerated()); |
|||
result.setHidden(column.isHidden()); |
|||
result.setAutoIncremented(column.isAutoIncremented()); |
|||
result.setPartOfIndex(column.isPartOfIndex()); |
|||
result.setPartOfUniqueIndex(column.isPartOfUniqueIndex()); |
|||
result.setPartOfPrimaryKey(column.isPartOfPrimaryKey()); |
|||
result.setSize(column.getSize()); |
|||
result.setWidth(column.getWidth()); |
|||
return result; |
|||
} |
|||
|
|||
private SchemaCrawlerOptions getDefaultOptions(DataSource dataSource) { |
|||
final SchemaCrawlerOptions options = new SchemaCrawlerOptions(); |
|||
options.setSchemaInfoLevel(SchemaInfoLevelBuilder.standard()); |
|||
options.setRoutineInclusionRule(new ExcludeAll()); |
|||
options.setTableInclusionRule(new IncludeAll()); |
|||
|
|||
|
|||
options.setSchemaInclusionRule(new RegularExpressionInclusionRule("I9")); |
|||
//options.setSchemaInclusionRule(new RegularExpressionInclusionRule("FRAMEWORK"));
|
|||
|
|||
|
|||
DatabaseType type =null; |
|||
try { |
|||
type = DatabaseType.fromMetaData(dataSource); |
|||
} catch (org.springframework.jdbc.support.MetaDataAccessException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
switch(type) { |
|||
case DB2: |
|||
options.setSchemaInclusionRule(new RegularExpressionExclusionRule("NULLID|SQLJ|SYSCAT|SYSFUN|SYSIBM|SYSIBMADM|SYSIBMINTERNAL|SYSIBMTS|SYSPROC|SYSPUBLIC|SYSSTAT|SYSTOOLS")); |
|||
break; |
|||
case ORACLE: |
|||
options.setSchemaInclusionRule(new RegularExpressionExclusionRule("ANONYMOUS|APEX_PUBLIC_USER|APPQOSSYS|BI|CTXSYS|DBSNMP|DIP|EXFSYS|FLOWS_30000|FLOWS_FILES|GSMADMIN_INTERNAL|HR|IX|LBACSYS|MDDATA|MDSYS|MGMT_VIEW|OE|OLAPSYS|ORACLE_OCM|ORDDATA|ORDPLUGINS|ORDSYS|OUTLN|OWBSYS|OWBSYS_AUDIT|PM|RDSADMIN|SCOTT|SH|SI_INFORMTN_SCHEMA|SPATIAL_CSW_ADMIN_USR|SPATIAL_WFS_ADMIN_USR|SYS|SYSMAN|\\\"SYSTEM\\\"|TSMSYS|WKPROXY|WKSYS|WK_TEST|WMSYS|XDB|APEX_[0-9]{6}|FLOWS_[0-9]{5,6}|XS\\$NULL|\\\"XS\\$NULL\\\"")); |
|||
break; |
|||
case MYSQL: |
|||
options.setSchemaInclusionRule(new RegularExpressionExclusionRule("sys|mysql|performance_schema|information_schema")); |
|||
break; |
|||
case POSTGRESQL: |
|||
options.setSchemaInclusionRule(new RegularExpressionExclusionRule("pg_catalog|information_schema")); |
|||
break; |
|||
default: |
|||
} |
|||
return options; |
|||
} |
|||
|
|||
private schemacrawler.schema.Schema findSchema(Catalog catalog,String schemaName) { |
|||
Collection<schemacrawler.schema.Schema> schemas =catalog.getSchemas(); |
|||
if(schemas!=null && schemas.size()>0) { |
|||
for(schemacrawler.schema.Schema schema : schemas) { |
|||
DatabaseType type =DatabaseType.fromProductName(catalog.getDatabaseInfo().getProductName()); |
|||
if(DatabaseType.MYSQL.equals(type)) {//mysql 没有 schema,只有 catalog
|
|||
if(schema.getCatalogName().equalsIgnoreCase(schemaName)) { |
|||
return schema; |
|||
} |
|||
}else { |
|||
if(schema.getName().equalsIgnoreCase(schemaName)) { |
|||
return schema; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
package io.sc.platform.jdbc.schemacrawler; |
|||
|
|||
import schemacrawler.schema.Table; |
|||
import schemacrawler.schema.TableRelationshipType; |
|||
|
|||
import java.util.Collection; |
|||
import java.util.Comparator; |
|||
|
|||
public class ParentAndChildrenTableComparator implements Comparator<Table> { |
|||
@Override |
|||
public int compare(Table o1, Table o2) { |
|||
Collection<Table> parentTables =o1.getRelatedTables(TableRelationshipType.parent); |
|||
Collection<schemacrawler.schema.Table> childrenTables =o1.getRelatedTables(TableRelationshipType.child); |
|||
if(parentTables!=null && !parentTables.isEmpty() && parentTables.contains(o2)) { |
|||
return 1; |
|||
}else if(childrenTables!=null && !childrenTables.isEmpty() && childrenTables.contains(o2)) { |
|||
return -1; |
|||
}else { |
|||
return o1.getName().compareTo(o2.getName()); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1 @@ |
|||
io.sc.platform.jdbc.schemacrawler.MetaDataLoaderImpl |
@ -1,104 +1,102 @@ |
|||
{ |
|||
"name": "io.sc.platform.lcdp.frontend", |
|||
"version": "8.1.11", |
|||
"description": "", |
|||
"private": false, |
|||
"keywords": [ |
|||
|
|||
], |
|||
"author": "", |
|||
"license": "ISC", |
|||
"scripts": { |
|||
"clean": "rm -rf ./node_modules && rm -rf pnpm-lock.yaml", |
|||
"dev": "nodemon", |
|||
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs", |
|||
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs", |
|||
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs", |
|||
"sync": "platform sync" |
|||
}, |
|||
"engines": { |
|||
"node": ">=18", |
|||
"pnpm": ">=7" |
|||
}, |
|||
"publishConfig": { |
|||
"registry": "http://nexus.sc.io:8000/repository/npm-releases/", |
|||
"access": "public" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/core": "7.23.2", |
|||
"@babel/preset-env": "7.23.2", |
|||
"@babel/preset-typescript": "7.23.2", |
|||
"@babel/plugin-transform-class-properties": "7.22.5", |
|||
"@babel/plugin-transform-object-rest-spread": "7.22.15", |
|||
"@quasar/app-webpack": "3.11.2", |
|||
"@quasar/cli": "2.3.0", |
|||
"@types/mockjs": "1.0.9", |
|||
"@types/node": "20.8.9", |
|||
"@typescript-eslint/eslint-plugin": "6.9.0", |
|||
"@typescript-eslint/parser": "6.9.0", |
|||
"@vue/compiler-sfc": "3.3.7", |
|||
"@webpack-cli/serve": "2.0.5", |
|||
"autoprefixer": "10.4.16", |
|||
"babel-loader": "9.1.3", |
|||
"clean-webpack-plugin": "4.0.0", |
|||
"copy-webpack-plugin": "11.0.0", |
|||
"cross-env": "7.0.3", |
|||
"css-loader": "6.8.1", |
|||
"eslint": "8.52.0", |
|||
"eslint-config-prettier": "9.0.0", |
|||
"eslint-plugin-prettier": "5.0.1", |
|||
"eslint-plugin-vue": "9.18.0", |
|||
"eslint-webpack-plugin": "4.0.1", |
|||
"html-webpack-plugin": "5.5.3", |
|||
"json5": "2.2.3", |
|||
"mini-css-extract-plugin": "2.7.6", |
|||
"nodemon": "3.0.1", |
|||
"postcss": "8.4.31", |
|||
"postcss-import": "15.1.0", |
|||
"postcss-loader": "7.3.3", |
|||
"postcss-preset-env": "9.2.0", |
|||
"prettier": "3.0.3", |
|||
"sass": "1.69.5", |
|||
"sass-loader": "13.3.2", |
|||
"typescript": "5.2.2", |
|||
"vue-loader": "17.3.0", |
|||
"webpack": "5.89.0", |
|||
"webpack-bundle-analyzer": "4.9.1", |
|||
"webpack-cli": "5.1.4", |
|||
"webpack-dev-server": "4.15.1", |
|||
"webpack-merge": "5.10.0" |
|||
}, |
|||
"dependencies": { |
|||
"@codemirror/autocomplete": "6.11.1", |
|||
"@codemirror/commands": "6.3.2", |
|||
"@codemirror/lang-html": "6.4.7", |
|||
"@codemirror/lang-java": "6.0.1", |
|||
"@codemirror/lang-javascript": "6.2.1", |
|||
"@codemirror/lang-json": "6.0.1", |
|||
"@codemirror/lang-sql": "6.5.4", |
|||
"@codemirror/lang-xml": "6.0.2", |
|||
"@codemirror/language": "6.9.3", |
|||
"@codemirror/search": "6.5.5", |
|||
"@codemirror/state": "6.3.3", |
|||
"@codemirror/view": "6.22.1", |
|||
"@quasar/extras": "1.16.7", |
|||
"@vueuse/core": "10.3.0", |
|||
"axios": "1.5.1", |
|||
"codemirror": "6.0.1", |
|||
"dayjs": "1.11.10", |
|||
"echarts": "5.4.1", |
|||
"exceljs": "4.3.0", |
|||
"file-saver": "2.0.5", |
|||
"luckyexcel": "1.0.1", |
|||
"mockjs": "1.1.0", |
|||
"pinia": "2.1.7", |
|||
"platform-core": "8.1.27", |
|||
"quasar": "2.13.0", |
|||
"tailwindcss": "3.3.5", |
|||
"vue": "3.3.7", |
|||
"vue-dompurify-html": "4.1.4", |
|||
"vue-i18n": "9.6.0", |
|||
"vue-router": "4.2.5", |
|||
"vue-codemirror6": "1.1.31" |
|||
} |
|||
"name": "io.sc.platform.lcdp.frontend", |
|||
"version": "8.1.12", |
|||
"description": "", |
|||
"private": false, |
|||
"keywords": [], |
|||
"author": "", |
|||
"license": "ISC", |
|||
"scripts": { |
|||
"clean": "rm -rf ./node_modules && rm -rf pnpm-lock.yaml", |
|||
"dev": "nodemon", |
|||
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs", |
|||
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs", |
|||
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs", |
|||
"sync": "platform sync" |
|||
}, |
|||
"engines": { |
|||
"node": ">=18", |
|||
"pnpm": ">=7" |
|||
}, |
|||
"publishConfig": { |
|||
"registry": "http://nexus.sc.io:8000/repository/npm-releases/", |
|||
"access": "public" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/core": "7.23.2", |
|||
"@babel/preset-env": "7.23.2", |
|||
"@babel/preset-typescript": "7.23.2", |
|||
"@babel/plugin-transform-class-properties": "7.22.5", |
|||
"@babel/plugin-transform-object-rest-spread": "7.22.15", |
|||
"@quasar/app-webpack": "3.11.2", |
|||
"@quasar/cli": "2.3.0", |
|||
"@types/mockjs": "1.0.9", |
|||
"@types/node": "20.8.9", |
|||
"@typescript-eslint/eslint-plugin": "6.9.0", |
|||
"@typescript-eslint/parser": "6.9.0", |
|||
"@vue/compiler-sfc": "3.3.7", |
|||
"@webpack-cli/serve": "2.0.5", |
|||
"autoprefixer": "10.4.16", |
|||
"babel-loader": "9.1.3", |
|||
"clean-webpack-plugin": "4.0.0", |
|||
"copy-webpack-plugin": "11.0.0", |
|||
"cross-env": "7.0.3", |
|||
"css-loader": "6.8.1", |
|||
"eslint": "8.52.0", |
|||
"eslint-config-prettier": "9.0.0", |
|||
"eslint-plugin-prettier": "5.0.1", |
|||
"eslint-plugin-vue": "9.18.0", |
|||
"eslint-webpack-plugin": "4.0.1", |
|||
"html-webpack-plugin": "5.5.3", |
|||
"json5": "2.2.3", |
|||
"mini-css-extract-plugin": "2.7.6", |
|||
"nodemon": "3.0.1", |
|||
"postcss": "8.4.31", |
|||
"postcss-import": "15.1.0", |
|||
"postcss-loader": "7.3.3", |
|||
"postcss-preset-env": "9.2.0", |
|||
"prettier": "3.0.3", |
|||
"sass": "1.69.5", |
|||
"sass-loader": "13.3.2", |
|||
"typescript": "5.2.2", |
|||
"vue-loader": "17.3.0", |
|||
"webpack": "5.89.0", |
|||
"webpack-bundle-analyzer": "4.9.1", |
|||
"webpack-cli": "5.1.4", |
|||
"webpack-dev-server": "4.15.1", |
|||
"webpack-merge": "5.10.0" |
|||
}, |
|||
"dependencies": { |
|||
"@codemirror/autocomplete": "6.11.1", |
|||
"@codemirror/commands": "6.3.2", |
|||
"@codemirror/lang-html": "6.4.7", |
|||
"@codemirror/lang-java": "6.0.1", |
|||
"@codemirror/lang-javascript": "6.2.1", |
|||
"@codemirror/lang-json": "6.0.1", |
|||
"@codemirror/lang-sql": "6.5.4", |
|||
"@codemirror/lang-xml": "6.0.2", |
|||
"@codemirror/language": "6.9.3", |
|||
"@codemirror/search": "6.5.5", |
|||
"@codemirror/state": "6.3.3", |
|||
"@codemirror/view": "6.22.1", |
|||
"@quasar/extras": "1.16.7", |
|||
"@vueuse/core": "10.3.0", |
|||
"axios": "1.5.1", |
|||
"codemirror": "6.0.1", |
|||
"dayjs": "1.11.10", |
|||
"echarts": "5.4.1", |
|||
"exceljs": "4.3.0", |
|||
"file-saver": "2.0.5", |
|||
"luckyexcel": "1.0.1", |
|||
"mockjs": "1.1.0", |
|||
"pinia": "2.1.7", |
|||
"platform-core": "8.1.37", |
|||
"quasar": "2.13.0", |
|||
"tailwindcss": "3.3.5", |
|||
"vue": "3.3.7", |
|||
"vue-dompurify-html": "4.1.4", |
|||
"vue-i18n": "9.6.0", |
|||
"vue-router": "4.2.5", |
|||
"vue-codemirror6": "1.1.31" |
|||
} |
|||
} |
@ -1,104 +1,102 @@ |
|||
{ |
|||
"name": "io.sc.platform.mvc.frontend", |
|||
"version": "8.1.11", |
|||
"description": "", |
|||
"private": false, |
|||
"keywords": [ |
|||
|
|||
], |
|||
"author": "", |
|||
"license": "ISC", |
|||
"scripts": { |
|||
"dev": "nodemon", |
|||
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs", |
|||
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs", |
|||
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs", |
|||
"sync": "platform sync", |
|||
"clean": "rm -rf ./node_modules && rm -rf pnpm-lock.yaml" |
|||
}, |
|||
"engines": { |
|||
"node": ">=18", |
|||
"pnpm": ">=7" |
|||
}, |
|||
"publishConfig": { |
|||
"registry": "http://nexus.sc.io:8000/repository/npm-releases/", |
|||
"access": "public" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/core": "7.23.2", |
|||
"@babel/preset-env": "7.23.2", |
|||
"@babel/preset-typescript": "7.23.2", |
|||
"@babel/plugin-transform-class-properties": "7.22.5", |
|||
"@babel/plugin-transform-object-rest-spread": "7.22.15", |
|||
"@quasar/app-webpack": "3.11.2", |
|||
"@quasar/cli": "2.3.0", |
|||
"@types/mockjs": "1.0.9", |
|||
"@types/node": "20.8.9", |
|||
"@typescript-eslint/eslint-plugin": "6.9.0", |
|||
"@typescript-eslint/parser": "6.9.0", |
|||
"@vue/compiler-sfc": "3.3.7", |
|||
"@webpack-cli/serve": "2.0.5", |
|||
"autoprefixer": "10.4.16", |
|||
"babel-loader": "9.1.3", |
|||
"clean-webpack-plugin": "4.0.0", |
|||
"copy-webpack-plugin": "11.0.0", |
|||
"cross-env": "7.0.3", |
|||
"css-loader": "6.8.1", |
|||
"eslint": "8.52.0", |
|||
"eslint-config-prettier": "9.0.0", |
|||
"eslint-plugin-prettier": "5.0.1", |
|||
"eslint-plugin-vue": "9.18.0", |
|||
"eslint-webpack-plugin": "4.0.1", |
|||
"html-webpack-plugin": "5.5.3", |
|||
"json5": "2.2.3", |
|||
"mini-css-extract-plugin": "2.7.6", |
|||
"nodemon": "3.0.1", |
|||
"postcss": "8.4.31", |
|||
"postcss-import": "15.1.0", |
|||
"postcss-loader": "7.3.3", |
|||
"postcss-preset-env": "9.2.0", |
|||
"prettier": "3.0.3", |
|||
"sass": "1.69.5", |
|||
"sass-loader": "13.3.2", |
|||
"typescript": "5.2.2", |
|||
"vue-loader": "17.3.0", |
|||
"webpack": "5.89.0", |
|||
"webpack-bundle-analyzer": "4.9.1", |
|||
"webpack-cli": "5.1.4", |
|||
"webpack-dev-server": "4.15.1", |
|||
"webpack-merge": "5.10.0" |
|||
}, |
|||
"dependencies": { |
|||
"@quasar/extras": "1.16.7", |
|||
"@vueuse/core": "10.3.0", |
|||
"axios": "1.5.1", |
|||
"dayjs": "1.11.10", |
|||
"echarts": "5.4.1", |
|||
"exceljs": "4.3.0", |
|||
"file-saver": "2.0.5", |
|||
"luckyexcel": "1.0.1", |
|||
"mockjs": "1.1.0", |
|||
"pinia": "2.1.7", |
|||
"platform-core": "8.1.27", |
|||
"quasar": "2.13.0", |
|||
"tailwindcss": "3.3.5", |
|||
"vue": "3.3.7", |
|||
"vue-dompurify-html": "4.1.4", |
|||
"vue-i18n": "9.6.0", |
|||
"vue-router": "4.2.5", |
|||
"@codemirror/autocomplete": "6.11.1", |
|||
"@codemirror/commands": "6.3.2", |
|||
"@codemirror/lang-html": "6.4.7", |
|||
"@codemirror/lang-java": "6.0.1", |
|||
"@codemirror/lang-javascript": "6.2.1", |
|||
"@codemirror/lang-json": "6.0.1", |
|||
"@codemirror/lang-sql": "6.5.4", |
|||
"@codemirror/lang-xml": "6.0.2", |
|||
"@codemirror/language": "6.9.3", |
|||
"@codemirror/search": "6.5.5", |
|||
"@codemirror/state": "6.3.3", |
|||
"@codemirror/view": "6.22.1", |
|||
"codemirror": "6.0.1", |
|||
"vue-codemirror6": "1.1.31" |
|||
} |
|||
"name": "io.sc.platform.mvc.frontend", |
|||
"version": "8.1.12", |
|||
"description": "", |
|||
"private": false, |
|||
"keywords": [], |
|||
"author": "", |
|||
"license": "ISC", |
|||
"scripts": { |
|||
"dev": "nodemon", |
|||
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs", |
|||
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs", |
|||
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs", |
|||
"sync": "platform sync", |
|||
"clean": "rm -rf ./node_modules && rm -rf pnpm-lock.yaml" |
|||
}, |
|||
"engines": { |
|||
"node": ">=18", |
|||
"pnpm": ">=7" |
|||
}, |
|||
"publishConfig": { |
|||
"registry": "http://nexus.sc.io:8000/repository/npm-releases/", |
|||
"access": "public" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/core": "7.23.2", |
|||
"@babel/preset-env": "7.23.2", |
|||
"@babel/preset-typescript": "7.23.2", |
|||
"@babel/plugin-transform-class-properties": "7.22.5", |
|||
"@babel/plugin-transform-object-rest-spread": "7.22.15", |
|||
"@quasar/app-webpack": "3.11.2", |
|||
"@quasar/cli": "2.3.0", |
|||
"@types/mockjs": "1.0.9", |
|||
"@types/node": "20.8.9", |
|||
"@typescript-eslint/eslint-plugin": "6.9.0", |
|||
"@typescript-eslint/parser": "6.9.0", |
|||
"@vue/compiler-sfc": "3.3.7", |
|||
"@webpack-cli/serve": "2.0.5", |
|||
"autoprefixer": "10.4.16", |
|||
"babel-loader": "9.1.3", |
|||
"clean-webpack-plugin": "4.0.0", |
|||
"copy-webpack-plugin": "11.0.0", |
|||
"cross-env": "7.0.3", |
|||
"css-loader": "6.8.1", |
|||
"eslint": "8.52.0", |
|||
"eslint-config-prettier": "9.0.0", |
|||
"eslint-plugin-prettier": "5.0.1", |
|||
"eslint-plugin-vue": "9.18.0", |
|||
"eslint-webpack-plugin": "4.0.1", |
|||
"html-webpack-plugin": "5.5.3", |
|||
"json5": "2.2.3", |
|||
"mini-css-extract-plugin": "2.7.6", |
|||
"nodemon": "3.0.1", |
|||
"postcss": "8.4.31", |
|||
"postcss-import": "15.1.0", |
|||
"postcss-loader": "7.3.3", |
|||
"postcss-preset-env": "9.2.0", |
|||
"prettier": "3.0.3", |
|||
"sass": "1.69.5", |
|||
"sass-loader": "13.3.2", |
|||
"typescript": "5.2.2", |
|||
"vue-loader": "17.3.0", |
|||
"webpack": "5.89.0", |
|||
"webpack-bundle-analyzer": "4.9.1", |
|||
"webpack-cli": "5.1.4", |
|||
"webpack-dev-server": "4.15.1", |
|||
"webpack-merge": "5.10.0" |
|||
}, |
|||
"dependencies": { |
|||
"@quasar/extras": "1.16.7", |
|||
"@vueuse/core": "10.3.0", |
|||
"axios": "1.5.1", |
|||
"dayjs": "1.11.10", |
|||
"echarts": "5.4.1", |
|||
"exceljs": "4.3.0", |
|||
"file-saver": "2.0.5", |
|||
"luckyexcel": "1.0.1", |
|||
"mockjs": "1.1.0", |
|||
"pinia": "2.1.7", |
|||
"platform-core": "8.1.37", |
|||
"quasar": "2.13.0", |
|||
"tailwindcss": "3.3.5", |
|||
"vue": "3.3.7", |
|||
"vue-dompurify-html": "4.1.4", |
|||
"vue-i18n": "9.6.0", |
|||
"vue-router": "4.2.5", |
|||
"@codemirror/autocomplete": "6.11.1", |
|||
"@codemirror/commands": "6.3.2", |
|||
"@codemirror/lang-html": "6.4.7", |
|||
"@codemirror/lang-java": "6.0.1", |
|||
"@codemirror/lang-javascript": "6.2.1", |
|||
"@codemirror/lang-json": "6.0.1", |
|||
"@codemirror/lang-sql": "6.5.4", |
|||
"@codemirror/lang-xml": "6.0.2", |
|||
"@codemirror/language": "6.9.3", |
|||
"@codemirror/search": "6.5.5", |
|||
"@codemirror/state": "6.3.3", |
|||
"@codemirror/view": "6.22.1", |
|||
"codemirror": "6.0.1", |
|||
"vue-codemirror6": "1.1.31" |
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
package io.sc.platform.mvc.support; |
|||
|
|||
public class OrderItem<ID,ORDER> { |
|||
private ID id; |
|||
private ORDER order; |
|||
|
|||
public ID getId() { |
|||
return id; |
|||
} |
|||
|
|||
public void setId(ID id) { |
|||
this.id = id; |
|||
} |
|||
|
|||
public ORDER getOrder() { |
|||
return order; |
|||
} |
|||
|
|||
public void setOrder(ORDER order) { |
|||
this.order = order; |
|||
} |
|||
} |
@ -1,12 +1,12 @@ |
|||
[ |
|||
/*系统*/ |
|||
{"id":"parameter.system","order":0}, |
|||
/*系统/首页 Thymeleaf 视图模板*/ |
|||
/*系统/首页路由*/ |
|||
{ |
|||
"id" : "parameter.system.indexPageTemplate", |
|||
"id" : "parameter.system.homePage", |
|||
"parentId" : "parameter.system", |
|||
"code" : "parameter.system.indexPageTemplate", |
|||
"defaultValue" : "io.sc.platform.mvc.frontend.html", |
|||
"code" : "parameter.system.homePage", |
|||
"defaultValue" : "/home", |
|||
"order" : 100 |
|||
} |
|||
] |
@ -0,0 +1,44 @@ |
|||
package io.sc.platform.system.api.announcement; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonPropertyOrder; |
|||
import io.sc.platform.orm.api.vo.AuditorVo; |
|||
|
|||
|
|||
@JsonPropertyOrder({ |
|||
"id", |
|||
"title", |
|||
"content", |
|||
"creator", |
|||
"createDate", |
|||
"lastModifier", |
|||
"lastModifyDate" |
|||
}) |
|||
public class AnnouncementVo extends AuditorVo { |
|||
private String id; |
|||
private String title; |
|||
private String content; |
|||
|
|||
public String getId() { |
|||
return id; |
|||
} |
|||
|
|||
public void setId(String id) { |
|||
this.id = id; |
|||
} |
|||
|
|||
public String getTitle() { |
|||
return title; |
|||
} |
|||
|
|||
public void setTitle(String title) { |
|||
this.title = title; |
|||
} |
|||
|
|||
public String getContent() { |
|||
return content; |
|||
} |
|||
|
|||
public void setContent(String content) { |
|||
this.content = content; |
|||
} |
|||
} |
@ -1,4 +0,0 @@ |
|||
package io.sc.platform.system.api.parameter; |
|||
|
|||
public class Parameter { |
|||
} |
@ -0,0 +1,40 @@ |
|||
package io.sc.platform.system.api.parameter; |
|||
|
|||
public class ParameterVo { |
|||
private String id; |
|||
private String code; |
|||
private String value; |
|||
private String parentId; |
|||
|
|||
public String getId() { |
|||
return id; |
|||
} |
|||
|
|||
public void setId(String id) { |
|||
this.id = id; |
|||
} |
|||
|
|||
public String getCode() { |
|||
return code; |
|||
} |
|||
|
|||
public void setCode(String code) { |
|||
this.code = code; |
|||
} |
|||
|
|||
public String getValue() { |
|||
return value; |
|||
} |
|||
|
|||
public void setValue(String value) { |
|||
this.value = value; |
|||
} |
|||
|
|||
public String getParentId() { |
|||
return parentId; |
|||
} |
|||
|
|||
public void setParentId(String parentId) { |
|||
this.parentId = parentId; |
|||
} |
|||
} |
@ -1,4 +0,0 @@ |
|||
<template> |
|||
<div>Corporation</div> |
|||
</template> |
|||
<script setup lang="ts"></script> |
@ -1,4 +0,0 @@ |
|||
<template> |
|||
<div>Dictionary</div> |
|||
</template> |
|||
<script setup lang="ts"></script> |
@ -1,4 +0,0 @@ |
|||
<template> |
|||
<div>Parameter</div> |
|||
</template> |
|||
<script setup lang="ts"></script> |
@ -0,0 +1,70 @@ |
|||
<template> |
|||
<div> |
|||
<platform-grid |
|||
ref="announcementGridRef" |
|||
:table-props="{ borderded: false, flat: true }" |
|||
:query-form-cols-number="announcementConfigure.queryFormColsNumber" |
|||
:query-form-cols-auto="announcementConfigure.queryFormColsAuto" |
|||
:table-title="announcementConfigure.tableTitle" |
|||
:table-row-key="announcementConfigure.tableRowKey" |
|||
:table-init-load-data="announcementConfigure.tableInitLoadData" |
|||
:table-data-url="announcementConfigure.tableDataUrl" |
|||
:table-show-sort-no="false" |
|||
:table-columns="announcementConfigure.tableColumns" |
|||
:table-left-column-sticky-number="announcementConfigure.tableLeftColumnStickyNumber" |
|||
:table-buttons="announcementConfigure.tableButtons" |
|||
:query-form-fields="announcementConfigure.queryFormFields" |
|||
:table-pagination="announcementConfigure.tablePagination" |
|||
:add-form-props="announcementConfigure.addFormProps" |
|||
:table-dense="false" |
|||
@row-click="announcementConfigure.rowClickFun" |
|||
> |
|||
</platform-grid> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { Environment, axios } from 'platform-core'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const announcementConfigure = { |
|||
queryFormColsNumber: 4, |
|||
queryFormColsAuto: false, |
|||
hideBottom: false, |
|||
tableInitLoadData: true, |
|||
tableLeftColumnStickyNumber: 0, |
|||
tableTitle: t('system.announcement.gridTitle'), |
|||
tableRowKey: 'id', |
|||
tableDataUrl: Environment.apiContextPath('/api/system/announcement'), |
|||
tablePagination: { |
|||
sortBy: 'lastModifyDate', |
|||
descending: true, |
|||
reqPageStart: 0, |
|||
rowsPerPage: 10, |
|||
}, |
|||
queryFormFields: [ |
|||
{ width: 100, name: 'title', label: t('title') }, |
|||
{ width: 110, name: 'lastModifier', label: t('lastModifier') }, |
|||
{ width: 115, name: 'lastModifyDate', label: t('lastModifyDate') }, |
|||
], |
|||
tableButtons: ['add', 'edit', 'delete', 'separator', 'view', 'inFullscreen'], |
|||
tableColumns: [ |
|||
{ width: 100, name: 'title', label: t('title') }, |
|||
{ width: 100, name: 'content', label: t('content') }, |
|||
{ width: 110, name: 'lastModifier', label: t('lastModifier') }, |
|||
{ width: 115, name: 'lastModifyDate', label: t('lastModifyDate') }, |
|||
], |
|||
addFormProps: { |
|||
dialogInitWidth: '50%', |
|||
dialogInitHeight: '90%', |
|||
formColsNumber: 1, |
|||
formColsAuto: false, |
|||
formFields: [ |
|||
{ modelName: 'title', label: t('title'), type: 'text', required: true }, |
|||
{ modelName: 'content', label: t('content'), type: 'textarea', required: true }, |
|||
], |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,51 @@ |
|||
<template> |
|||
<div> |
|||
<w-tree-grid ref="corporationTreeGridRef" title="法人树" label-key="name" :actions="corporationConfigure.actions" /> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref, onMounted } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { Environment, axios } from 'platform-core'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const corporationTreeGridRef = ref(); |
|||
|
|||
const corporationConfigure = { |
|||
actions: [ |
|||
{ |
|||
name: 'refresh', |
|||
label: t('refresh'), |
|||
click: () => {}, |
|||
}, |
|||
|
|||
{ |
|||
name: 'addRoot', |
|||
label: t('system.corporation.action.addTop'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'addChild', |
|||
label: t('system.corporation.action.addChild'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'edit', |
|||
label: t('edit'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'delete', |
|||
label: t('delete'), |
|||
click: () => {}, |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
onMounted(() => { |
|||
axios.get(Environment.apiContextPath('/api/system/corporation?pageable=false&sortBy=name')).then((response) => { |
|||
corporationTreeGridRef.value.setNodes(response.data.content); |
|||
}); |
|||
}); |
|||
</script> |
@ -0,0 +1,70 @@ |
|||
<template> |
|||
<div> |
|||
<platform-grid |
|||
ref="dictionaryGridRef" |
|||
:table-props="{ borderded: false, flat: true }" |
|||
:table-title="dictionaryConfigure.tableTitle" |
|||
:table-init-load-data="dictionaryConfigure.tableInitLoadData" |
|||
:table-row-key="dictionaryConfigure.tableRowKey" |
|||
:table-data-url="dictionaryConfigure.tableDataUrl" |
|||
:table-columns="dictionaryConfigure.tableColumns" |
|||
:table-buttons="dictionaryConfigure.tableButtons" |
|||
:add-form-props="dictionaryConfigure.addFormProps" |
|||
:table-show-sort-no="false" |
|||
:table-dense="true" |
|||
:table-row-drag="true" |
|||
:table-pagination="dictionaryConfigure.tablePagination" |
|||
@row-drag-drop-after="rowDragDropAfter" |
|||
> |
|||
</platform-grid> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { onMounted, ref } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { Environment, axios } from 'platform-core'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const dictionaryGridRef = ref(); |
|||
const dictionaryConfigure = { |
|||
tableTitle: '数据字典列表', |
|||
tableInitLoadData: true, |
|||
tableRowKey: 'id', |
|||
tableDataUrl: Environment.apiContextPath('/api/system/dictionary'), |
|||
tablePagination: { |
|||
sortBy: 'order', |
|||
descending: false, |
|||
reqPageStart: 0, |
|||
rowsPerPage: 0, |
|||
}, |
|||
tableColumns: [ |
|||
{ name: 'code', label: t('code') }, |
|||
{ name: 'value', label: t('value') }, |
|||
{ name: 'value', label: t('displayValue'), format: (value) => t(value) }, |
|||
{ name: 'order', label: t('order') }, |
|||
], |
|||
tableButtons: ['refresh', 'add', 'edit', 'delete'], |
|||
addFormProps: { |
|||
dialogInitWidth: '50%', |
|||
dialogInitHeight: '90%', |
|||
formColsNumber: 1, |
|||
formColsAuto: false, |
|||
formFields: [ |
|||
{ modelName: 'code', label: t('code'), type: 'text', required: true }, |
|||
{ modelName: 'value', label: t('value'), type: 'text', required: true }, |
|||
{ modelName: 'order', label: t('order'), type: 'text', required: true }, |
|||
], |
|||
}, |
|||
}; |
|||
|
|||
const rowDragDropAfter = () => { |
|||
const rows = dictionaryGridRef.value.getRowsFun(); |
|||
for (let i = 0; i < rows.length; i++) { |
|||
rows[i].order = i; |
|||
} |
|||
axios.post(Environment.apiContextPath('/api/system/dictionary/updateDictionariesOrder'), rows).then(() => { |
|||
//dictionaryGridRef.value.refreshTable(); |
|||
}); |
|||
}; |
|||
</script> |
@ -0,0 +1,70 @@ |
|||
<template> |
|||
<div> |
|||
<platform-grid |
|||
ref="i18nGridRef" |
|||
:table-props="{ borderded: false, flat: true }" |
|||
:table-title="i18nConfigure.tableTitle" |
|||
:table-init-load-data="i18nConfigure.tableInitLoadData" |
|||
:table-row-key="i18nConfigure.tableRowKey" |
|||
:table-data-url="i18nConfigure.tableDataUrl" |
|||
:table-columns="i18nConfigure.tableColumns" |
|||
:table-buttons="i18nConfigure.tableButtons" |
|||
:add-form-props="i18nConfigure.addFormProps" |
|||
:table-show-sort-no="false" |
|||
:table-dense="true" |
|||
:table-row-drag="true" |
|||
:table-pagination="i18nConfigure.tablePagination" |
|||
> |
|||
</platform-grid> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { onMounted, ref } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { Environment, axios } from 'platform-core'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const Language = { |
|||
en: '英文', |
|||
zh_CN: '简体中文', |
|||
tw_CN: '繁体中文', |
|||
}; |
|||
|
|||
const LanguageOptions = [ |
|||
{ label: '英文', value: 'en' }, |
|||
{ label: '简体中文', value: 'zh_CN' }, |
|||
{ label: '繁体中文', value: 'tw_CN' }, |
|||
]; |
|||
|
|||
const i18nGridRef = ref(); |
|||
const i18nConfigure = { |
|||
tableTitle: '多语言消息列表', |
|||
tableInitLoadData: true, |
|||
tableRowKey: 'id', |
|||
tableDataUrl: Environment.apiContextPath('/api/system/i18n'), |
|||
tablePagination: { |
|||
sortBy: 'code', |
|||
descending: false, |
|||
reqPageStart: 0, |
|||
rowsPerPage: 20, |
|||
}, |
|||
tableColumns: [ |
|||
{ name: 'code', label: t('code') }, |
|||
{ name: 'lang', label: t('lang'), format: (value) => Language[value] }, |
|||
{ name: 'message', label: t('message') }, |
|||
], |
|||
tableButtons: ['refresh', 'add', 'edit', 'delete'], |
|||
addFormProps: { |
|||
dialogInitWidth: '50%', |
|||
dialogInitHeight: '90%', |
|||
formColsNumber: 1, |
|||
formColsAuto: false, |
|||
formFields: [ |
|||
{ modelName: 'code', label: t('code'), type: 'text', required: true }, |
|||
{ modelName: 'lang', label: t('lang'), type: 'select', required: true, options: LanguageOptions }, |
|||
{ modelName: 'message', label: t('message'), type: 'text', required: true }, |
|||
], |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,248 @@ |
|||
<template> |
|||
<q-splitter :model-value="70" class="w-full h-full"> |
|||
<template #before> |
|||
<w-tree-grid |
|||
ref="menuTreeGridRef" |
|||
title="菜单树" |
|||
label-key="titleI18nKey" |
|||
label-i18n |
|||
label-empty="--------------------" |
|||
:actions="menuConfigure.actions" |
|||
tick-strategy="none" |
|||
@update:selected="menuSelected" |
|||
/> |
|||
</template> |
|||
<template #after> |
|||
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0"> |
|||
<q-tab name="role" icon="bi-diagram-3" :label="$t('role')" /> |
|||
<q-tab name="org" icon="bi-people" :label="$t('org')" /> |
|||
</q-tabs> |
|||
|
|||
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> |
|||
<q-tab-panel name="user"> |
|||
<platform-grid |
|||
ref="roleGridRef" |
|||
:table-props="{ borderded: false, flat: true }" |
|||
:query-form-cols-number="roleConfigure.queryFormColsNumber" |
|||
:hide-bottom="roleConfigure.hideBottom" |
|||
:query-form-cols-auto="roleConfigure.queryFormColsAuto" |
|||
:table-title="roleConfigure.tableTitle" |
|||
:table-row-key="roleConfigure.tableRowKey" |
|||
:table-init-load-data="roleConfigure.tableInitLoadData" |
|||
:table-data-url="roleConfigure.tableDataUrl" |
|||
:table-show-sort-no="false" |
|||
:table-columns="roleConfigure.tableColumns" |
|||
:table-left-column-sticky-number="roleConfigure.tableLeftColumnStickyNumber" |
|||
:table-buttons="roleConfigure.tableButtons" |
|||
:query-form-fields="roleConfigure.queryFormFields" |
|||
:table-pagination="roleConfigure.tablePagination" |
|||
table-selection="multiple" |
|||
:table-dense="false" |
|||
> |
|||
</platform-grid> |
|||
</q-tab-panel> |
|||
|
|||
<q-tab-panel name="org"> |
|||
<w-tree-grid |
|||
ref="orgTreeGridRef" |
|||
title="机构树" |
|||
label-key="titleI18nKey" |
|||
label-i18n |
|||
label-empty="--------------------" |
|||
:actions="orgConfigure.actions" |
|||
/> |
|||
</q-tab-panel> |
|||
</q-tab-panels> |
|||
</template> |
|||
<SelectRoleDialog ref="selectRoleDialog" title="可选角色列表" :maximized="false" width="50%" height="500px"></SelectRoleDialog> |
|||
</q-splitter> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref, onMounted } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { Environment, axios } from 'platform-core'; |
|||
import SelectRoleDialog from './SelectRoleDialog.vue'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const menuTreeGridRef = ref(); |
|||
const roleGridRef = ref(); |
|||
const orgTreeGridRef = ref(); |
|||
|
|||
const selectRoleDialog = ref(); |
|||
const selectedTabRef = ref('user'); |
|||
let selectedMenuId = ''; |
|||
|
|||
const roleConfigure = { |
|||
queryFormColsNumber: 4, |
|||
queryFormColsAuto: false, |
|||
queryFormFields: [], |
|||
hideBottom: true, |
|||
tableInitLoadData: false, |
|||
tableLeftColumnStickyNumber: 0, |
|||
tableTitle: t('system.role.gridTitle'), |
|||
tableRowKey: 'id', |
|||
tableDataUrl: '', |
|||
tablePagination: { |
|||
sortBy: 'lastModifyDate', |
|||
descending: true, |
|||
reqPageStart: 0, |
|||
rowsPerPage: 0, |
|||
}, |
|||
tableButtons: [ |
|||
'refresh', |
|||
'inFullscreen', |
|||
{ |
|||
name: 'addRole', |
|||
label: t('system.role.action.addRole'), |
|||
icon: '', |
|||
enable: () => {}, |
|||
click: () => { |
|||
selectRoleDialog.value.show({ roleGridRef: roleGridRef, menuTreeGridRef: menuTreeGridRef }); |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'addAllRole', |
|||
label: t('system.role.action.addAllRole'), |
|||
icon: '', |
|||
enable: () => {}, |
|||
click: () => { |
|||
const menuId = menuTreeGridRef.value.getSelected(); |
|||
axios |
|||
.post(Environment.apiContextPath('/api/system/menu/addAllRoles'), { |
|||
source: menuId, |
|||
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId), |
|||
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId), |
|||
targets: [], |
|||
}) |
|||
.then((response) => { |
|||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => { |
|||
roleGridRef.value.replaceRowsFun(response.data.content); |
|||
}); |
|||
}); |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'removeRole', |
|||
label: t('system.role.action.removeRole'), |
|||
icon: '', |
|||
enable: () => {}, |
|||
click: () => { |
|||
const menuId = menuTreeGridRef.value.getSelected(); |
|||
const roleIds = []; |
|||
for (const role of roleGridRef.value.getSelectedRows()) { |
|||
roleIds.push(role.id); |
|||
} |
|||
axios |
|||
.post(Environment.apiContextPath('/api/system/menu/removeRoles'), { |
|||
source: menuId, |
|||
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId), |
|||
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId), |
|||
targets: roleIds, |
|||
}) |
|||
.then((response) => { |
|||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => { |
|||
roleGridRef.value.replaceRowsFun(response.data.content); |
|||
}); |
|||
}); |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'removeAllRole', |
|||
label: t('system.role.action.removeAllRole'), |
|||
icon: '', |
|||
enable: () => {}, |
|||
click: () => { |
|||
const menuId = menuTreeGridRef.value.getSelected(); |
|||
axios |
|||
.post(Environment.apiContextPath('/api/system/menu/removeAllRoles'), { |
|||
source: menuId, |
|||
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId), |
|||
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId), |
|||
targets: [], |
|||
}) |
|||
.then((response) => { |
|||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => { |
|||
roleGridRef.value.replaceRowsFun(response.data.content); |
|||
}); |
|||
}); |
|||
}, |
|||
}, |
|||
], |
|||
tableColumns: [ |
|||
{ width: 100, name: 'code', label: t('code') }, |
|||
{ width: 100, name: 'name', label: t('name') }, |
|||
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) }, |
|||
], |
|||
}; |
|||
|
|||
const menuConfigure = { |
|||
actions: [ |
|||
{ |
|||
name: 'refresh', |
|||
label: t('refresh'), |
|||
click: () => {}, |
|||
}, |
|||
|
|||
{ |
|||
name: 'addRoot', |
|||
label: t('system.menu.action.addTop'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'addChild', |
|||
label: t('system.menu.action.addChild'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'edit', |
|||
label: t('edit'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'delete', |
|||
label: t('delete'), |
|||
click: () => {}, |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
const orgConfigure = { |
|||
actions: [ |
|||
{ |
|||
name: 'save', |
|||
label: '保存', |
|||
click: () => { |
|||
const orgId = menuTreeGridRef.value.getSelected()[0]; |
|||
axios |
|||
.post(Environment.apiContextPath('/api/system/menu/updateOrgs'), { |
|||
one: orgId, |
|||
many: menuTreeGridRef.value.getTicked(), |
|||
}) |
|||
.then((response) => {}); |
|||
}, |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
const menuSelected = (target) => { |
|||
selectedMenuId = target; |
|||
if (roleGridRef.value) { |
|||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + selectedMenuId).then((response) => { |
|||
roleGridRef.value.replaceRowsFun(response.data.content); |
|||
}); |
|||
} |
|||
|
|||
// if (orgTreeGridRef.value) { |
|||
// axios.get(Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByMenu?menuId=') + selectedMenuId).then((response) => { |
|||
// orgTreeGridRef.value.setNodes(response.data); |
|||
// }); |
|||
// } |
|||
}; |
|||
|
|||
onMounted(() => { |
|||
axios.get(Environment.apiContextPath('/api/system/menu?pageable=false&sortBy=order')).then((response) => { |
|||
menuTreeGridRef.value.setNodes(response.data.content); |
|||
}); |
|||
}); |
|||
</script> |
@ -0,0 +1,155 @@ |
|||
<template> |
|||
<div> |
|||
<q-dialog ref="dialogRef" allow-focus-outside v-bind="attrs"> |
|||
<q-card |
|||
:style="{ |
|||
width: attrs.maximized ? '100vw' : width, |
|||
'max-width': '100vw', |
|||
height: attrs.maximized ? '100vh' : height, |
|||
'max-height': '100vh', |
|||
}" |
|||
> |
|||
<q-card-section :style="headerStyle"> |
|||
<div class="flex justify-between"> |
|||
<div class="text-h6">{{ title }}</div> |
|||
<div class="flex justify-end q-gutter-md"> |
|||
<q-btn :label="$t('confirm')" dense color="primary" style="width: 100px" @click="addRoles" /> |
|||
<q-btn v-close-popup dense flat icon="close" :title="$t('close')"> </q-btn> |
|||
</div> |
|||
</div> |
|||
</q-card-section> |
|||
<q-card-section class="q-pt-none" :style="bodyStyle"> |
|||
<platform-grid |
|||
ref="gridRef" |
|||
:table-props="{ borderded: false, flat: true }" |
|||
:query-form-cols-number="roleConfigure.queryFormColsNumber" |
|||
:hide-bottom="roleConfigure.hideBottom" |
|||
:query-form-cols-auto="roleConfigure.queryFormColsAuto" |
|||
:table-title="roleConfigure.tableTitle" |
|||
:table-row-key="roleConfigure.tableRowKey" |
|||
:table-init-load-data="roleConfigure.tableInitLoadData" |
|||
:table-data-url="roleConfigure.tableDataUrl" |
|||
:table-show-sort-no="false" |
|||
:table-columns="roleConfigure.tableColumns" |
|||
:table-left-column-sticky-number="roleConfigure.tableLeftColumnStickyNumber" |
|||
:table-buttons="roleConfigure.tableButtons" |
|||
:query-form-fields="roleConfigure.queryFormFields" |
|||
:table-pagination="roleConfigure.tablePagination" |
|||
table-selection="multiple" |
|||
:table-dense="false" |
|||
> |
|||
</platform-grid> |
|||
</q-card-section> |
|||
</q-card> |
|||
</q-dialog> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { useAttrs, ref, onMounted, nextTick } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { axios, Environment } from 'platform-core'; |
|||
|
|||
const attrs = useAttrs(); |
|||
|
|||
const props = defineProps({ |
|||
headerStyle: { type: String, default: 'width:100%;padding: 16px 8px 4px 16px' }, |
|||
bodyStyle: { type: String, default: 'padding: 0px 8px 0px 8px;height:calc(100%)' }, |
|||
title: { type: String, default: '' }, |
|||
width: { type: String, default: '70%' }, |
|||
height: { type: String, default: '70%' }, |
|||
}); |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const dialogRef = ref(); |
|||
const gridRef = ref(); |
|||
let menuTreeGridRef, roleGridRef; |
|||
|
|||
const roleConfigure = { |
|||
queryFormColsNumber: 4, |
|||
queryFormColsAuto: false, |
|||
hideBottom: true, |
|||
tableInitLoadData: false, |
|||
tableLeftColumnStickyNumber: 0, |
|||
tableTitle: '', |
|||
tableRowKey: 'id', |
|||
tableDataUrl: '', |
|||
tablePagination: { |
|||
sortBy: 'lastModifyDate', |
|||
descending: true, |
|||
reqPageStart: 0, |
|||
rowsPerPage: 0, |
|||
}, |
|||
tableButtons: ['query', 'refresh'], |
|||
queryFormFields: [ |
|||
{ label: t('code'), modelName: 'code', type: 'text' }, |
|||
{ label: t('name'), modelName: 'name', type: 'text' }, |
|||
{ |
|||
label: t('enable'), |
|||
modelName: 'enable', |
|||
type: 'select', |
|||
options: [ |
|||
{ value: true, label: '是' }, |
|||
{ value: false, label: '否' }, |
|||
], |
|||
}, |
|||
{ |
|||
label: t('dataComeFrom'), |
|||
modelName: 'dataComeFrom', |
|||
type: 'select', |
|||
options: [ |
|||
{ value: 'MANUAL', label: t('io.sc.platform.orm.api.enums.DataComeFrom.MANUAL') }, |
|||
{ value: 'AUTO', label: t('io.sc.platform.orm.api.enums.DataComeFrom.AUTO') }, |
|||
], |
|||
}, |
|||
], |
|||
tableColumns: [ |
|||
{ width: 100, name: 'code', label: t('code') }, |
|||
{ width: 100, name: 'name', label: t('name') }, |
|||
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) }, |
|||
], |
|||
}; |
|||
|
|||
const addRoles = () => { |
|||
const menuId = menuTreeGridRef.value.getSelected(); |
|||
const roleIds = []; |
|||
for (const role of gridRef.value.getSelectedRows()) { |
|||
roleIds.push(role.id); |
|||
} |
|||
axios |
|||
.post(Environment.apiContextPath('/api/system/menu/addRoles'), { |
|||
source: menuId, |
|||
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId), |
|||
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId), |
|||
targets: roleIds, |
|||
}) |
|||
.then((response) => { |
|||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => { |
|||
roleGridRef.value.replaceRowsFun(response.data.content); |
|||
}); |
|||
dialogRef.value.hide(); |
|||
}); |
|||
}; |
|||
|
|||
const show = (param: object) => { |
|||
menuTreeGridRef = param.menuTreeGridRef; |
|||
roleGridRef = param.roleGridRef; |
|||
const currentMenuId = menuTreeGridRef.value.getSelected()[0]; |
|||
|
|||
dialogRef.value.show(); |
|||
nextTick(() => { |
|||
axios.get(Environment.apiContextPath('/api/system/role/queryOtherRolesByMenu?menuId=') + currentMenuId).then((response) => { |
|||
gridRef.value.replaceRowsFun(response.data.content); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
const hide = () => { |
|||
dialogRef.value.hide(); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
show, |
|||
hide, |
|||
}); |
|||
</script> |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue